mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-01-31 23:30:11 +08:00
fdde73ff48
translation completed 20180115 How debuggers really work
932 lines
71 KiB
Markdown
932 lines
71 KiB
Markdown
|
||
|
||
|
||
|
||
|
||
|
||
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<link rel="dns-prefetch" href="https://assets-cdn.github.com">
|
||
<link rel="dns-prefetch" href="https://avatars0.githubusercontent.com">
|
||
<link rel="dns-prefetch" href="https://avatars1.githubusercontent.com">
|
||
<link rel="dns-prefetch" href="https://avatars2.githubusercontent.com">
|
||
<link rel="dns-prefetch" href="https://avatars3.githubusercontent.com">
|
||
<link rel="dns-prefetch" href="https://github-cloud.s3.amazonaws.com">
|
||
<link rel="dns-prefetch" href="https://user-images.githubusercontent.com/">
|
||
|
||
|
||
|
||
<link crossorigin="anonymous" media="all" integrity="sha512-T9mI+Xgc8yCjMH6J/gS6kaW3O3zJaDuANCq4x9/EpAreyyj61xpmrp9qxWgdCYvpBqyX3T0nOmQzfAO82cdiww==" rel="stylesheet" href="https://assets-cdn.github.com/assets/frameworks-0e1c43e90618c1e26b9b138a9d83c008.css" />
|
||
<link crossorigin="anonymous" media="all" integrity="sha512-IRZ7RDIi0r/O4C5v+F7llFxjOZVEp59AYG9cEZgVtwXlrWuVDO54yUbaLxO0VAYSiMaTXf3IXoHXgwkz5aXsTQ==" rel="stylesheet" href="https://assets-cdn.github.com/assets/github-4f8d5d8c6735e64227c6ce64f907c974.css" />
|
||
|
||
|
||
|
||
|
||
|
||
<meta name="viewport" content="width=device-width">
|
||
|
||
<title>TranslateProject/20180115 How debuggers really work.md at patch-2 · stephenxs/TranslateProject</title>
|
||
<meta name="description" content="GitHub is where people build software. More than 28 million people use GitHub to discover, fork, and contribute to over 85 million projects.">
|
||
<link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub">
|
||
<link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub">
|
||
<meta property="fb:app_id" content="1401488693436528">
|
||
|
||
|
||
<meta property="og:image" content="https://avatars2.githubusercontent.com/u/5379172?s=400&v=4" /><meta property="og:site_name" content="GitHub" /><meta property="og:type" content="object" /><meta property="og:title" content="stephenxs/TranslateProject" /><meta property="og:url" content="https://github.com/stephenxs/TranslateProject" /><meta property="og:description" content="TranslateProject - Linux中国翻译项目" />
|
||
|
||
<link rel="assets" href="https://assets-cdn.github.com/">
|
||
<link rel="web-socket" href="wss://live.github.com/_sockets/VjI6Mjg3NjEwMDk3OmU2ZmZjMTRjMzg5NTc5YzJkOTU3NmFiODU1NTA4YjNjZWFhOWM1Njc2MjIzOTBhOWI1ZGJlYjEyOTI2ZWE1N2M=--b4ef35ec9468096d95af164a5e5bdd3676bb5746">
|
||
<meta name="pjax-timeout" content="1000">
|
||
<link rel="sudo-modal" href="/sessions/sudo_modal">
|
||
<meta name="request-id" content="B492:7089:948088:DDC2EB:5B2BB3AF" data-pjax-transient>
|
||
|
||
|
||
|
||
|
||
<meta name="selected-link" value="repo_source" data-pjax-transient>
|
||
|
||
<meta name="google-site-verification" content="KT5gs8h0wvaagLKAVWq8bbeNwnZZK1r1XQysX3xurLU">
|
||
<meta name="google-site-verification" content="ZzhVyEFwb7w3e0-uOTltm8Jsck2F5StVihD0exw2fsA">
|
||
<meta name="google-site-verification" content="GXs5KoUUkNCoaAZn7wPN-t01Pywp9M3sEjnt_3_ZWPc">
|
||
<meta name="google-analytics" content="UA-3769691-2">
|
||
|
||
<meta name="octolytics-host" content="collector.githubapp.com" /><meta name="octolytics-app-id" content="github" /><meta name="octolytics-event-url" content="https://collector.githubapp.com/github-external/browser_event" /><meta name="octolytics-dimension-request_id" content="B492:7089:948088:DDC2EB:5B2BB3AF" /><meta name="octolytics-dimension-region_edge" content="sea" /><meta name="octolytics-dimension-region_render" content="iad" /><meta name="octolytics-actor-id" content="5379172" /><meta name="octolytics-actor-login" content="stephenxs" /><meta name="octolytics-actor-hash" content="8a0054b4a3b6bb04e7644c9d242914f365f73899b5d8d455adc09ba8bd5b0bc6" />
|
||
<meta name="analytics-location" content="/<user-name>/<repo-name>/blob/show" data-pjax-transient="true" />
|
||
|
||
|
||
|
||
|
||
<meta class="js-ga-set" name="dimension1" content="Logged In">
|
||
|
||
|
||
|
||
|
||
<meta name="hostname" content="github.com">
|
||
<meta name="user-login" content="stephenxs">
|
||
|
||
<meta name="expected-hostname" content="github.com">
|
||
<meta name="js-proxy-site-detection-payload" content="ZDhhYWQzNzU1ZWIwZGVlYWI0ODdjNjBkMmU4ZjJlOTliMzkwOTE1YWNlYzliN2Q1OGZiOTM2MzMzZDJhNGJmYXx7InJlbW90ZV9hZGRyZXNzIjoiMTA0LjIzNy44Ni4xOTQiLCJyZXF1ZXN0X2lkIjoiQjQ5Mjo3MDg5Ojk0ODA4ODpEREMyRUI6NUIyQkIzQUYiLCJ0aW1lc3RhbXAiOjE1Mjk1OTA3MjIsImhvc3QiOiJnaXRodWIuY29tIn0=">
|
||
|
||
<meta name="enabled-features" content="UNIVERSE_BANNER,FREE_TRIALS,MARKETPLACE_INSIGHTS,MARKETPLACE_INSIGHTS_CONVERSION_PERCENTAGES">
|
||
|
||
<meta name="html-safe-nonce" content="3d93b6cd86dec28c3b83acb86f9b4756a26cb77b">
|
||
|
||
<meta http-equiv="x-pjax-version" content="361405cc9e6ea59f35dd4fb724d47834">
|
||
|
||
|
||
<link href="https://github.com/stephenxs/TranslateProject/commits/patch-2.atom" rel="alternate" title="Recent Commits to TranslateProject:patch-2" type="application/atom+xml">
|
||
|
||
<meta name="description" content="TranslateProject - Linux中国翻译项目">
|
||
<meta name="go-import" content="github.com/stephenxs/TranslateProject git https://github.com/stephenxs/TranslateProject.git">
|
||
|
||
<meta name="octolytics-dimension-user_id" content="5379172" /><meta name="octolytics-dimension-user_login" content="stephenxs" /><meta name="octolytics-dimension-repository_id" content="137820026" /><meta name="octolytics-dimension-repository_nwo" content="stephenxs/TranslateProject" /><meta name="octolytics-dimension-repository_public" content="true" /><meta name="octolytics-dimension-repository_is_fork" content="true" /><meta name="octolytics-dimension-repository_parent_id" content="12745174" /><meta name="octolytics-dimension-repository_parent_nwo" content="LCTT/TranslateProject" /><meta name="octolytics-dimension-repository_network_root_id" content="12745174" /><meta name="octolytics-dimension-repository_network_root_nwo" content="LCTT/TranslateProject" /><meta name="octolytics-dimension-repository_explore_github_marketplace_ci_cta_shown" content="true" />
|
||
|
||
|
||
<link rel="canonical" href="https://github.com/stephenxs/TranslateProject/blob/patch-2/sources/tech/20180115%20How%20debuggers%20really%20work.md" data-pjax-transient>
|
||
|
||
|
||
<meta name="browser-stats-url" content="https://api.github.com/_private/browser/stats">
|
||
|
||
<meta name="browser-errors-url" content="https://api.github.com/_private/browser/errors">
|
||
|
||
<link rel="mask-icon" href="https://assets-cdn.github.com/pinned-octocat.svg" color="#000000">
|
||
<link rel="icon" type="image/x-icon" class="js-site-favicon" href="https://assets-cdn.github.com/favicon.ico">
|
||
|
||
<meta name="theme-color" content="#1e2327">
|
||
|
||
|
||
<meta name="u2f-support" content="true">
|
||
|
||
<link rel="manifest" href="/manifest.json" crossOrigin="use-credentials">
|
||
|
||
</head>
|
||
|
||
<body class="logged-in env-production page-blob">
|
||
|
||
|
||
<div class="position-relative js-header-wrapper ">
|
||
<a href="#start-of-content" tabindex="1" class="p-3 bg-blue text-white show-on-focus js-skip-to-content">Skip to content</a>
|
||
<div id="js-pjax-loader-bar" class="pjax-loader-bar"><div class="progress"></div></div>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<header class="Header f5" role="banner">
|
||
<div class="d-flex flex-justify-between px-3 container-lg">
|
||
<div class="d-flex flex-justify-between ">
|
||
<div class="">
|
||
<a class="header-logo-invertocat" href="https://github.com/" data-hotkey="g d" aria-label="Homepage" data-ga-click="Header, go to dashboard, icon:logo">
|
||
<svg height="32" class="octicon octicon-mark-github" viewBox="0 0 16 16" version="1.1" width="32" aria-hidden="true"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"/></svg>
|
||
</a>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<div class="HeaderMenu d-flex flex-justify-between flex-auto">
|
||
<div class="d-flex">
|
||
<div class="">
|
||
<div class="header-search scoped-search site-scoped-search js-site-search position-relative js-jump-to"
|
||
role="search combobox"
|
||
aria-owns="jump-to-results"
|
||
aria-label="Search or jump to"
|
||
aria-haspopup="listbox"
|
||
aria-expanded="true"
|
||
>
|
||
<div class="position-relative">
|
||
<!-- '"` --><!-- </textarea></xmp> --></option></form><form class="js-site-search-form" data-scope-type="Repository" data-scope-id="137820026" data-scoped-search-url="/stephenxs/TranslateProject/search" data-unscoped-search-url="/search" action="/stephenxs/TranslateProject/search" accept-charset="UTF-8" method="get"><input name="utf8" type="hidden" value="✓" />
|
||
<label class="form-control header-search-wrapper header-search-wrapper-jump-to position-relative d-flex flex-justify-between flex-items-center js-chromeless-input-container">
|
||
<input type="text"
|
||
class="form-control header-search-input jump-to-field js-jump-to-field js-site-search-focus js-site-search-field is-clearable"
|
||
data-hotkey="s,/"
|
||
name="q"
|
||
value=""
|
||
placeholder="Search or jump to…"
|
||
data-unscoped-placeholder="Search or jump to…"
|
||
data-scoped-placeholder="Search or jump to…"
|
||
autocapitalize="off"
|
||
aria-autocomplete="list"
|
||
aria-controls="jump-to-results"
|
||
data-jump-to-suggestions-path="/_graphql/GetSuggestedNavigationDestinations#csrf-token=uW25wEuL33wphNXeCSV5VHTfW7FuPisN/8upP0GiSgM6yBrzY5rIteLIa21dlk1PY1XKF6eFZcYLxf218kt2JA=="
|
||
spellcheck="false"
|
||
autocomplete="off"
|
||
>
|
||
<input type="hidden" class="js-site-search-type-field" name="type" >
|
||
<img src="https://assets-cdn.github.com/images/search-shortcut-hint.svg" alt="" class="mr-2 header-search-key-slash">
|
||
|
||
<div class="Box position-absolute overflow-hidden d-none jump-to-suggestions js-jump-to-suggestions-container">
|
||
<ul class="d-none js-jump-to-suggestions-template-container">
|
||
<li class="d-flex flex-justify-start flex-items-center p-0 f5 navigation-item js-navigation-item">
|
||
<a tabindex="-1" class="no-underline d-flex flex-auto flex-items-center p-2 jump-to-suggestions-path js-jump-to-suggestion-path js-navigation-open" href="">
|
||
<div class="jump-to-octicon js-jump-to-octicon mr-2 text-center d-none"></div>
|
||
<img class="avatar mr-2 flex-shrink-0 js-jump-to-suggestion-avatar" alt="" aria-label="Team" src="" width="28" height="28">
|
||
|
||
<div class="jump-to-suggestion-name js-jump-to-suggestion-name flex-auto overflow-hidden no-wrap css-truncate css-truncate-target">
|
||
</div>
|
||
|
||
<div class="border rounded-1 flex-shrink-0 bg-gray px-1 text-gray-light ml-1 f6 d-none js-jump-to-badge-search">
|
||
<span class="js-jump-to-badge-search-text-default d-none" aria-label="in this repository">
|
||
In this repository
|
||
</span>
|
||
<span class="js-jump-to-badge-search-text-global d-none" aria-label="in all of GitHub">
|
||
All GitHub
|
||
</span>
|
||
<span aria-hidden="true" class="d-inline-block ml-1 v-align-middle">↵</span>
|
||
</div>
|
||
|
||
<div aria-hidden="true" class="border rounded-1 flex-shrink-0 bg-gray px-1 text-gray-light ml-1 f6 d-none d-on-nav-focus js-jump-to-badge-jump">
|
||
Jump to
|
||
<span class="d-inline-block ml-1 v-align-middle">↵</span>
|
||
</div>
|
||
</a>
|
||
</li>
|
||
<svg height="16" width="16" class="octicon octicon-repo flex-shrink-0 js-jump-to-repo-octicon-template" title="Repository" aria-label="Repository" viewBox="0 0 12 16" version="1.1" role="img"><path fill-rule="evenodd" d="M4 9H3V8h1v1zm0-3H3v1h1V6zm0-2H3v1h1V4zm0-2H3v1h1V2zm8-1v12c0 .55-.45 1-1 1H6v2l-1.5-1.5L3 16v-2H1c-.55 0-1-.45-1-1V1c0-.55.45-1 1-1h10c.55 0 1 .45 1 1zm-1 10H1v2h2v-1h3v1h5v-2zm0-10H2v9h9V1z"/></svg>
|
||
<svg height="16" width="16" class="octicon octicon-project flex-shrink-0 js-jump-to-project-octicon-template" title="Project" aria-label="Project" viewBox="0 0 15 16" version="1.1" role="img"><path fill-rule="evenodd" d="M10 12h3V2h-3v10zm-4-2h3V2H6v8zm-4 4h3V2H2v12zm-1 1h13V1H1v14zM14 0H1a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h13a1 1 0 0 0 1-1V1a1 1 0 0 0-1-1z"/></svg>
|
||
<svg height="16" width="16" class="octicon octicon-search flex-shrink-0 js-jump-to-search-octicon-template" title="Search" aria-label="Search" viewBox="0 0 16 16" version="1.1" role="img"><path fill-rule="evenodd" d="M15.7 13.3l-3.81-3.83A5.93 5.93 0 0 0 13 6c0-3.31-2.69-6-6-6S1 2.69 1 6s2.69 6 6 6c1.3 0 2.48-.41 3.47-1.11l3.83 3.81c.19.2.45.3.7.3.25 0 .52-.09.7-.3a.996.996 0 0 0 0-1.41v.01zM7 10.7c-2.59 0-4.7-2.11-4.7-4.7 0-2.59 2.11-4.7 4.7-4.7 2.59 0 4.7 2.11 4.7 4.7 0 2.59-2.11 4.7-4.7 4.7z"/></svg>
|
||
</ul>
|
||
<ul class="d-none js-jump-to-no-results-template-container">
|
||
<li class="d-flex flex-justify-center flex-items-center p-3 f5 d-none">
|
||
<span class="text-gray">No suggested jump to results</span>
|
||
</li>
|
||
</ul>
|
||
|
||
<ul id="jump-to-results" class="js-navigation-container jump-to-suggestions-results-container js-jump-to-suggestions-results-container" >
|
||
<li class="d-flex flex-justify-center flex-items-center p-0 f5">
|
||
<img src="https://assets-cdn.github.com/images/spinners/octocat-spinner-128.gif" alt="Octocat Spinner Icon" class="m-2" width="28">
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</label>
|
||
</form> </div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<ul class="d-flex pl-2 flex-items-center text-bold list-style-none" role="navigation">
|
||
<li>
|
||
<a class="js-selected-navigation-item HeaderNavlink px-2" data-hotkey="g p" data-ga-click="Header, click, Nav menu - item:pulls context:user" aria-label="Pull requests you created" data-selected-links="/pulls /pulls/assigned /pulls/mentioned /pulls" href="/pulls">
|
||
Pull requests
|
||
</a> </li>
|
||
<li>
|
||
<a class="js-selected-navigation-item HeaderNavlink px-2" data-hotkey="g i" data-ga-click="Header, click, Nav menu - item:issues context:user" aria-label="Issues you created" data-selected-links="/issues /issues/assigned /issues/mentioned /issues" href="/issues">
|
||
Issues
|
||
</a> </li>
|
||
<li>
|
||
<a class="js-selected-navigation-item HeaderNavlink px-2" data-ga-click="Header, click, Nav menu - item:marketplace context:user" data-octo-click="marketplace_click" data-octo-dimensions="location:nav_bar, group:" data-selected-links=" /marketplace" href="/marketplace">
|
||
Marketplace
|
||
</a> </li>
|
||
<li>
|
||
<a class="js-selected-navigation-item HeaderNavlink px-2" data-ga-click="Header, click, Nav menu - item:explore" data-selected-links="/explore /trending /trending/developers /integrations /integrations/feature/code /integrations/feature/collaborate /integrations/feature/ship showcases showcases_search showcases_landing /explore" href="/explore">
|
||
Explore
|
||
</a> </li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="d-flex">
|
||
|
||
<ul class="user-nav d-flex flex-items-center list-style-none" id="user-links">
|
||
<li class="dropdown">
|
||
<span class="d-inline-block px-2">
|
||
|
||
<a aria-label="You have no unread notifications" class="notification-indicator tooltipped tooltipped-s js-socket-channel js-notification-indicator" data-hotkey="g n" data-ga-click="Header, go to notifications, icon:read" data-channel="notification-changed:5379172" href="/notifications">
|
||
<span class="mail-status "></span>
|
||
<svg class="octicon octicon-bell" viewBox="0 0 14 16" version="1.1" width="14" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M13.99 11.991v1H0v-1l.73-.58c.769-.769.809-2.547 1.189-4.416.77-3.767 4.077-4.996 4.077-4.996 0-.55.45-1 .999-1 .55 0 1 .45 1 1 0 0 3.387 1.229 4.156 4.996.38 1.879.42 3.657 1.19 4.417l.659.58h-.01zM6.995 15.99c1.11 0 1.999-.89 1.999-1.999H4.996c0 1.11.89 1.999 1.999 1.999z"/></svg>
|
||
</a>
|
||
</span>
|
||
</li>
|
||
|
||
<li class="dropdown">
|
||
<details class="details-overlay details-reset js-dropdown-details d-flex px-2 flex-items-center">
|
||
<summary class="HeaderNavlink"
|
||
aria-label="Create new…"
|
||
data-ga-click="Header, create new, icon:add">
|
||
<svg class="octicon octicon-plus float-left mr-1 mt-1" viewBox="0 0 12 16" version="1.1" width="12" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M12 9H7v5H5V9H0V7h5V2h2v5h5v2z"/></svg>
|
||
<span class="dropdown-caret mt-1"></span>
|
||
</summary>
|
||
|
||
<ul class="dropdown-menu dropdown-menu-sw">
|
||
|
||
<a class="dropdown-item" href="/new" data-ga-click="Header, create new repository">
|
||
New repository
|
||
</a>
|
||
|
||
<a class="dropdown-item" href="/new/import" data-ga-click="Header, import a repository">
|
||
Import repository
|
||
</a>
|
||
|
||
<a class="dropdown-item" href="https://gist.github.com/" data-ga-click="Header, create new gist">
|
||
New gist
|
||
</a>
|
||
|
||
<a class="dropdown-item" href="/organizations/new" data-ga-click="Header, create new organization">
|
||
New organization
|
||
</a>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</details>
|
||
</li>
|
||
|
||
<li class="dropdown">
|
||
|
||
<details class="details-overlay details-reset js-dropdown-details d-flex pl-2 flex-items-center">
|
||
<summary class="HeaderNavlink name mt-1"
|
||
aria-label="View profile and more"
|
||
data-ga-click="Header, show menu, icon:avatar">
|
||
<img alt="@stephenxs" class="avatar float-left mr-1" src="https://avatars2.githubusercontent.com/u/5379172?s=40&v=4" height="20" width="20">
|
||
<span class="dropdown-caret"></span>
|
||
</summary>
|
||
|
||
<ul class="dropdown-menu dropdown-menu-sw">
|
||
<li class="dropdown-header header-nav-current-user css-truncate">
|
||
Signed in as <strong class="css-truncate-target">stephenxs</strong>
|
||
</li>
|
||
|
||
<li class="dropdown-divider"></li>
|
||
|
||
<li><a class="dropdown-item" href="/stephenxs" data-ga-click="Header, go to profile, text:your profile">
|
||
Your profile
|
||
</a></li>
|
||
<li><a class="dropdown-item" href="/stephenxs?tab=stars" data-ga-click="Header, go to starred repos, text:your stars">
|
||
Your stars
|
||
</a></li>
|
||
<li><a class="dropdown-item" href="https://gist.github.com/" data-ga-click="Header, your gists, text:your gists">Your gists</a></li>
|
||
|
||
<li class="dropdown-divider"></li>
|
||
|
||
<li><a class="dropdown-item" href="https://help.github.com" data-ga-click="Header, go to help, text:help">
|
||
Help
|
||
</a></li>
|
||
|
||
<li><a class="dropdown-item" href="/settings/profile" data-ga-click="Header, go to settings, icon:settings">
|
||
Settings
|
||
</a></li>
|
||
|
||
<li><!-- '"` --><!-- </textarea></xmp> --></option></form><form class="logout-form" action="/logout" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="authenticity_token" value="9dDFXZEZnef7Wmq6srnkRsV/ThD0DC964CDiVctkMBjZaal6bsdZKjvSpD5O+G4Vse924P4E3LEO2AJQU78AMQ==" />
|
||
<button type="submit" class="dropdown-item dropdown-signout" data-ga-click="Header, sign out, icon:logout">
|
||
Sign out
|
||
</button>
|
||
</form></li>
|
||
</ul>
|
||
</details>
|
||
</li>
|
||
</ul>
|
||
|
||
|
||
|
||
<!-- '"` --><!-- </textarea></xmp> --></option></form><form class="sr-only right-0" action="/logout" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="authenticity_token" value="vLZzlVJ289D9F9kvOij2aZ6Mr8ie3ivWSgL1D2Bpqy+QDx+yrag3HT2fF6vGaXw66hyXOJTW2B2k+hUK+LKbBg==" />
|
||
<button type="submit" class="dropdown-item dropdown-signout" data-ga-click="Header, sign out, icon:logout">
|
||
Sign out
|
||
</button>
|
||
</form> </div>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
|
||
|
||
|
||
</div>
|
||
|
||
<div id="start-of-content" class="show-on-focus"></div>
|
||
|
||
<div id="js-flash-container">
|
||
</div>
|
||
|
||
|
||
|
||
<div role="main" class="application-main ">
|
||
<div itemscope itemtype="http://schema.org/SoftwareSourceCode" class="">
|
||
<div id="js-repo-pjax-container" data-pjax-container >
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<div class="pagehead repohead instapaper_ignore readability-menu experiment-repo-nav ">
|
||
<div class="repohead-details-container clearfix container">
|
||
|
||
<ul class="pagehead-actions">
|
||
<li>
|
||
<!-- '"` --><!-- </textarea></xmp> --></option></form><form data-autosubmit="true" data-remote="true" class="js-social-container" action="/notifications/subscribe" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="authenticity_token" value="n/wOx5FkXwEFjgxolK9n+sZAFEXoqwvzAw2+tqCY0JvMZ0/DxwOz5lvp6w9pB2aJUZCfayRIp+pShwJHotp2LQ==" /> <input type="hidden" name="repository_id" id="repository_id" value="137820026" class="form-control" />
|
||
|
||
<div class="select-menu js-menu-container js-select-menu">
|
||
<a href="/stephenxs/TranslateProject/subscription"
|
||
class="btn btn-sm btn-with-count select-menu-button js-menu-target"
|
||
role="button"
|
||
aria-haspopup="true"
|
||
aria-expanded="false"
|
||
aria-label="Toggle repository notifications menu"
|
||
data-ga-click="Repository, click Watch settings, action:blob#show">
|
||
<span class="js-select-button">
|
||
<svg class="octicon octicon-eye" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z"/></svg>
|
||
Unwatch
|
||
</span>
|
||
</a>
|
||
<a class="social-count js-social-count"
|
||
href="/stephenxs/TranslateProject/watchers"
|
||
aria-label="1 user is watching this repository">
|
||
1
|
||
</a>
|
||
|
||
<div class="select-menu-modal-holder">
|
||
<div class="select-menu-modal subscription-menu-modal js-menu-content">
|
||
<div class="select-menu-header js-navigation-enable" tabindex="-1">
|
||
<svg class="octicon octicon-x js-menu-close" role="img" aria-label="Close" viewBox="0 0 12 16" version="1.1" width="12" height="16"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48L7.48 8z"/></svg>
|
||
<span class="select-menu-title">Notifications</span>
|
||
</div>
|
||
|
||
<div class="select-menu-list js-navigation-container" role="menu">
|
||
|
||
<div class="select-menu-item js-navigation-item " role="menuitem" tabindex="0">
|
||
<svg class="octicon octicon-check select-menu-item-icon" viewBox="0 0 12 16" version="1.1" width="12" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5L12 5z"/></svg>
|
||
<div class="select-menu-item-text">
|
||
<input type="radio" name="do" id="do_included" value="included" />
|
||
<span class="select-menu-item-heading">Not watching</span>
|
||
<span class="description">Be notified when participating or @mentioned.</span>
|
||
<span class="js-select-button-text hidden-select-button-text">
|
||
<svg class="octicon octicon-eye" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z"/></svg>
|
||
Watch
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="select-menu-item js-navigation-item selected" role="menuitem" tabindex="0">
|
||
<svg class="octicon octicon-check select-menu-item-icon" viewBox="0 0 12 16" version="1.1" width="12" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5L12 5z"/></svg>
|
||
<div class="select-menu-item-text">
|
||
<input type="radio" name="do" id="do_subscribed" value="subscribed" checked="checked" />
|
||
<span class="select-menu-item-heading">Watching</span>
|
||
<span class="description">Be notified of all conversations.</span>
|
||
<span class="js-select-button-text hidden-select-button-text">
|
||
<svg class="octicon octicon-eye" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z"/></svg>
|
||
Unwatch
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="select-menu-item js-navigation-item " role="menuitem" tabindex="0">
|
||
<svg class="octicon octicon-check select-menu-item-icon" viewBox="0 0 12 16" version="1.1" width="12" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5L12 5z"/></svg>
|
||
<div class="select-menu-item-text">
|
||
<input type="radio" name="do" id="do_ignore" value="ignore" />
|
||
<span class="select-menu-item-heading">Ignoring</span>
|
||
<span class="description">Never be notified.</span>
|
||
<span class="js-select-button-text hidden-select-button-text">
|
||
<svg class="octicon octicon-mute" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M8 2.81v10.38c0 .67-.81 1-1.28.53L3 10H1c-.55 0-1-.45-1-1V7c0-.55.45-1 1-1h2l3.72-3.72C7.19 1.81 8 2.14 8 2.81zm7.53 3.22l-1.06-1.06-1.97 1.97-1.97-1.97-1.06 1.06L11.44 8 9.47 9.97l1.06 1.06 1.97-1.97 1.97 1.97 1.06-1.06L13.56 8l1.97-1.97z"/></svg>
|
||
Stop ignoring
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
<div class="js-toggler-container js-social-container starring-container ">
|
||
<!-- '"` --><!-- </textarea></xmp> --></option></form><form class="starred js-social-form" action="/stephenxs/TranslateProject/unstar" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="authenticity_token" value="s8HZwIVfnJPT+1cpDbLGWepWPWU269+2VzjHyVOIJpzApzVB/oEFRlFCLNZ26Z95zq4BCma8Dgs9ByWCbpPAyA==" />
|
||
<input type="hidden" name="context" value="repository"></input>
|
||
<button
|
||
type="submit"
|
||
class="btn btn-sm btn-with-count js-toggler-target"
|
||
aria-label="Unstar this repository" title="Unstar stephenxs/TranslateProject"
|
||
data-ga-click="Repository, click unstar button, action:blob#show; text:Unstar">
|
||
<svg class="octicon octicon-star" viewBox="0 0 14 16" version="1.1" width="14" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14 7 11.67 11.33 14l-.93-4.74L14 6z"/></svg>
|
||
Unstar
|
||
</button>
|
||
<a class="social-count js-social-count" href="/stephenxs/TranslateProject/stargazers"
|
||
aria-label="0 users starred this repository">
|
||
0
|
||
</a>
|
||
</form>
|
||
<!-- '"` --><!-- </textarea></xmp> --></option></form><form class="unstarred js-social-form" action="/stephenxs/TranslateProject/star" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="authenticity_token" value="T+FQvVQQsz4wWUuqwveR/qoyXWYso2lO8JY57LzQgbgtkj5GbHawWd3Bo2iAoNegMTXt/lwMV06CaSZwv+9/ng==" />
|
||
<input type="hidden" name="context" value="repository"></input>
|
||
<button
|
||
type="submit"
|
||
class="btn btn-sm btn-with-count js-toggler-target"
|
||
aria-label="Star this repository" title="Star stephenxs/TranslateProject"
|
||
data-ga-click="Repository, click star button, action:blob#show; text:Star">
|
||
<svg class="octicon octicon-star" viewBox="0 0 14 16" version="1.1" width="14" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14 7 11.67 11.33 14l-.93-4.74L14 6z"/></svg>
|
||
Star
|
||
</button>
|
||
<a class="social-count js-social-count" href="/stephenxs/TranslateProject/stargazers"
|
||
aria-label="0 users starred this repository">
|
||
0
|
||
</a>
|
||
</form> </div>
|
||
|
||
</li>
|
||
|
||
<li>
|
||
<!-- '"` --><!-- </textarea></xmp> --></option></form><form class="btn-with-count" action="/stephenxs/TranslateProject/fork" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="authenticity_token" value="AHk0a/AWtCG5JhUumY6XhAXS3WIqz/flhUYQ5kV6PCzy5K90DTqoPIDJ6iRa9r/2lM/K/wbLgTerPJtxK6usGQ==" />
|
||
<button
|
||
type="submit"
|
||
class="btn btn-sm btn-with-count"
|
||
data-ga-click="Repository, show fork modal, action:blob#show; text:Fork"
|
||
title="Fork your own copy of stephenxs/TranslateProject to your account"
|
||
aria-label="Fork your own copy of stephenxs/TranslateProject to your account">
|
||
<svg class="octicon octicon-repo-forked" viewBox="0 0 10 16" version="1.1" width="10" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M8 1a1.993 1.993 0 0 0-1 3.72V6L5 8 3 6V4.72A1.993 1.993 0 0 0 2 1a1.993 1.993 0 0 0-1 3.72V6.5l3 3v1.78A1.993 1.993 0 0 0 5 15a1.993 1.993 0 0 0 1-3.72V9.5l3-3V4.72A1.993 1.993 0 0 0 8 1zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3 10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3-10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"/></svg>
|
||
Fork
|
||
</button>
|
||
</form>
|
||
<a href="/stephenxs/TranslateProject/network" class="social-count"
|
||
aria-label="114 users forked this repository">
|
||
114
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
|
||
<h1 class="public ">
|
||
<svg class="octicon octicon-repo-forked" viewBox="0 0 10 16" version="1.1" width="10" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M8 1a1.993 1.993 0 0 0-1 3.72V6L5 8 3 6V4.72A1.993 1.993 0 0 0 2 1a1.993 1.993 0 0 0-1 3.72V6.5l3 3v1.78A1.993 1.993 0 0 0 5 15a1.993 1.993 0 0 0 1-3.72V9.5l3-3V4.72A1.993 1.993 0 0 0 8 1zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3 10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3-10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"/></svg>
|
||
<span class="author" itemprop="author"><a class="url fn" rel="author" href="/stephenxs">stephenxs</a></span><!--
|
||
--><span class="path-divider">/</span><!--
|
||
--><strong itemprop="name"><a data-pjax="#js-repo-pjax-container" href="/stephenxs/TranslateProject">TranslateProject</a></strong>
|
||
|
||
<span class="fork-flag">
|
||
<span class="text">forked from <a href="/LCTT/TranslateProject">LCTT/TranslateProject</a></span>
|
||
</span>
|
||
</h1>
|
||
|
||
</div>
|
||
|
||
<nav class="reponav js-repo-nav js-sidenav-container-pjax container"
|
||
itemscope
|
||
itemtype="http://schema.org/BreadcrumbList"
|
||
role="navigation"
|
||
data-pjax="#js-repo-pjax-container">
|
||
|
||
<span itemscope itemtype="http://schema.org/ListItem" itemprop="itemListElement">
|
||
<a class="js-selected-navigation-item selected reponav-item" itemprop="url" data-hotkey="g c" data-selected-links="repo_source repo_downloads repo_commits repo_releases repo_tags repo_branches repo_packages /stephenxs/TranslateProject/tree/patch-2" href="/stephenxs/TranslateProject/tree/patch-2">
|
||
<svg class="octicon octicon-code" viewBox="0 0 14 16" version="1.1" width="14" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M9.5 3L8 4.5 11.5 8 8 11.5 9.5 13 14 8 9.5 3zm-5 0L0 8l4.5 5L6 11.5 2.5 8 6 4.5 4.5 3z"/></svg>
|
||
<span itemprop="name">Code</span>
|
||
<meta itemprop="position" content="1">
|
||
</a> </span>
|
||
|
||
|
||
<span itemscope itemtype="http://schema.org/ListItem" itemprop="itemListElement">
|
||
<a data-hotkey="g p" itemprop="url" class="js-selected-navigation-item reponav-item" data-selected-links="repo_pulls checks /stephenxs/TranslateProject/pulls" href="/stephenxs/TranslateProject/pulls">
|
||
<svg class="octicon octicon-git-pull-request" viewBox="0 0 12 16" version="1.1" width="12" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M11 11.28V5c-.03-.78-.34-1.47-.94-2.06C9.46 2.35 8.78 2.03 8 2H7V0L4 3l3 3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 10 15a1.993 1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zM4 3c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v6.56A1.993 1.993 0 0 0 2 15a1.993 1.993 0 0 0 1-3.72V4.72c.59-.34 1-.98 1-1.72zm-.8 10c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"/></svg>
|
||
<span itemprop="name">Pull requests</span>
|
||
<span class="Counter">0</span>
|
||
<meta itemprop="position" content="3">
|
||
</a> </span>
|
||
|
||
<a data-hotkey="g b" class="js-selected-navigation-item reponav-item" data-selected-links="repo_projects new_repo_project repo_project /stephenxs/TranslateProject/projects" href="/stephenxs/TranslateProject/projects">
|
||
<svg class="octicon octicon-project" viewBox="0 0 15 16" version="1.1" width="15" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M10 12h3V2h-3v10zm-4-2h3V2H6v8zm-4 4h3V2H2v12zm-1 1h13V1H1v14zM14 0H1a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h13a1 1 0 0 0 1-1V1a1 1 0 0 0-1-1z"/></svg>
|
||
Projects
|
||
<span class="Counter" >0</span>
|
||
</a>
|
||
<a class="js-selected-navigation-item reponav-item" data-hotkey="g w" data-selected-links="repo_wiki /stephenxs/TranslateProject/wiki" href="/stephenxs/TranslateProject/wiki">
|
||
<svg class="octicon octicon-book" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M3 5h4v1H3V5zm0 3h4V7H3v1zm0 2h4V9H3v1zm11-5h-4v1h4V5zm0 2h-4v1h4V7zm0 2h-4v1h4V9zm2-6v9c0 .55-.45 1-1 1H9.5l-1 1-1-1H2c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h5.5l1 1 1-1H15c.55 0 1 .45 1 1zm-8 .5L7.5 3H2v9h6V3.5zm7-.5H9.5l-.5.5V12h6V3z"/></svg>
|
||
Wiki
|
||
</a>
|
||
|
||
<a class="js-selected-navigation-item reponav-item" data-selected-links="repo_graphs repo_contributors dependency_graph pulse /stephenxs/TranslateProject/pulse" href="/stephenxs/TranslateProject/pulse">
|
||
<svg class="octicon octicon-graph" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M16 14v1H0V0h1v14h15zM5 13H3V8h2v5zm4 0H7V3h2v10zm4 0h-2V6h2v7z"/></svg>
|
||
Insights
|
||
</a>
|
||
<a class="js-selected-navigation-item reponav-item" data-selected-links="repo_settings repo_branch_settings hooks integration_installations repo_keys_settings issue_template_editor /stephenxs/TranslateProject/settings" href="/stephenxs/TranslateProject/settings">
|
||
<svg class="octicon octicon-gear" viewBox="0 0 14 16" version="1.1" width="14" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M14 8.77v-1.6l-1.94-.64-.45-1.09.88-1.84-1.13-1.13-1.81.91-1.09-.45-.69-1.92h-1.6l-.63 1.94-1.11.45-1.84-.88-1.13 1.13.91 1.81-.45 1.09L0 7.23v1.59l1.94.64.45 1.09-.88 1.84 1.13 1.13 1.81-.91 1.09.45.69 1.92h1.59l.63-1.94 1.11-.45 1.84.88 1.13-1.13-.92-1.81.47-1.09L14 8.75v.02zM7 11c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3z"/></svg>
|
||
Settings
|
||
</a>
|
||
</nav>
|
||
|
||
|
||
</div>
|
||
|
||
<div class="container new-discussion-timeline experiment-repo-nav ">
|
||
<div class="repository-content ">
|
||
|
||
|
||
<a class="d-none js-permalink-shortcut" data-hotkey="y" href="/stephenxs/TranslateProject/blob/6d81dac07cfd1d4aca9a91d397de9786d043b7f9/sources/tech/20180115%20How%20debuggers%20really%20work.md">Permalink</a>
|
||
|
||
<!-- blob contrib key: blob_contributors:v21:68d34bb399dbb7d1693820695c2d6bc0 -->
|
||
|
||
|
||
|
||
<div class="file-navigation">
|
||
|
||
<div class="select-menu branch-select-menu js-menu-container js-select-menu float-left">
|
||
<button class=" btn btn-sm select-menu-button js-menu-target css-truncate" data-hotkey="w"
|
||
|
||
type="button" aria-label="Switch branches or tags" aria-expanded="false" aria-haspopup="true">
|
||
<i>Branch:</i>
|
||
<span class="js-select-button css-truncate-target">patch-2</span>
|
||
</button>
|
||
|
||
<div class="select-menu-modal-holder js-menu-content js-navigation-container" data-pjax>
|
||
|
||
<div class="select-menu-modal">
|
||
<div class="select-menu-header">
|
||
<svg class="octicon octicon-x js-menu-close" role="img" aria-label="Close" viewBox="0 0 12 16" version="1.1" width="12" height="16"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48L7.48 8z"/></svg>
|
||
<span class="select-menu-title">Switch branches/tags</span>
|
||
</div>
|
||
|
||
<div class="select-menu-filters">
|
||
<div class="select-menu-text-filter">
|
||
<input type="text" aria-label="Find or create a branch…" id="context-commitish-filter-field" class="form-control js-filterable-field js-navigation-enable" placeholder="Find or create a branch…">
|
||
</div>
|
||
<div class="select-menu-tabs">
|
||
<ul>
|
||
<li class="select-menu-tab">
|
||
<a href="#" data-tab-filter="branches" data-filter-placeholder="Find or create a branch…" class="js-select-menu-tab" role="tab">Branches</a>
|
||
</li>
|
||
<li class="select-menu-tab">
|
||
<a href="#" data-tab-filter="tags" data-filter-placeholder="Find a tag…" class="js-select-menu-tab" role="tab">Tags</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket" data-tab-filter="branches" role="menu">
|
||
|
||
<div data-filterable-for="context-commitish-filter-field" data-filterable-type="substring">
|
||
|
||
|
||
<a class="select-menu-item js-navigation-item js-navigation-open "
|
||
href="/stephenxs/TranslateProject/blob/master/sources/tech/20180115%20How%20debuggers%20really%20work.md"
|
||
data-name="master"
|
||
data-skip-pjax="true"
|
||
rel="nofollow">
|
||
<svg class="octicon octicon-check select-menu-item-icon" viewBox="0 0 12 16" version="1.1" width="12" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5L12 5z"/></svg>
|
||
<span class="select-menu-item-text css-truncate-target js-select-menu-filter-text">
|
||
master
|
||
</span>
|
||
</a>
|
||
<a class="select-menu-item js-navigation-item js-navigation-open "
|
||
href="/stephenxs/TranslateProject/blob/patch-1/sources/tech/20180115%20How%20debuggers%20really%20work.md"
|
||
data-name="patch-1"
|
||
data-skip-pjax="true"
|
||
rel="nofollow">
|
||
<svg class="octicon octicon-check select-menu-item-icon" viewBox="0 0 12 16" version="1.1" width="12" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5L12 5z"/></svg>
|
||
<span class="select-menu-item-text css-truncate-target js-select-menu-filter-text">
|
||
patch-1
|
||
</span>
|
||
</a>
|
||
<a class="select-menu-item js-navigation-item js-navigation-open selected"
|
||
href="/stephenxs/TranslateProject/blob/patch-2/sources/tech/20180115%20How%20debuggers%20really%20work.md"
|
||
data-name="patch-2"
|
||
data-skip-pjax="true"
|
||
rel="nofollow">
|
||
<svg class="octicon octicon-check select-menu-item-icon" viewBox="0 0 12 16" version="1.1" width="12" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5L12 5z"/></svg>
|
||
<span class="select-menu-item-text css-truncate-target js-select-menu-filter-text">
|
||
patch-2
|
||
</span>
|
||
</a>
|
||
<a class="select-menu-item js-navigation-item js-navigation-open "
|
||
href="/stephenxs/TranslateProject/blob/sunxi-patch-1/sources/tech/20180115%20How%20debuggers%20really%20work.md"
|
||
data-name="sunxi-patch-1"
|
||
data-skip-pjax="true"
|
||
rel="nofollow">
|
||
<svg class="octicon octicon-check select-menu-item-icon" viewBox="0 0 12 16" version="1.1" width="12" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5L12 5z"/></svg>
|
||
<span class="select-menu-item-text css-truncate-target js-select-menu-filter-text">
|
||
sunxi-patch-1
|
||
</span>
|
||
</a>
|
||
</div>
|
||
|
||
<!-- '"` --><!-- </textarea></xmp> --></option></form><form class="js-create-branch select-menu-item select-menu-new-item-form js-navigation-item js-new-item-form" action="/stephenxs/TranslateProject/branches" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="authenticity_token" value="6ZFKv+oCoLJZapq+EggFzfbJmXczraPyNY47NT8n7i9K8J7Kj065XnjWo2ZyPDQrBEIifwzCBuBKWWWvaFCkzw==" />
|
||
<svg class="octicon octicon-git-branch select-menu-item-icon" viewBox="0 0 10 16" version="1.1" width="10" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M10 5c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v.3c-.02.52-.23.98-.63 1.38-.4.4-.86.61-1.38.63-.83.02-1.48.16-2 .45V4.72a1.993 1.993 0 0 0-1-3.72C.88 1 0 1.89 0 3a2 2 0 0 0 1 1.72v6.56c-.59.35-1 .99-1 1.72 0 1.11.89 2 2 2 1.11 0 2-.89 2-2 0-.53-.2-1-.53-1.36.09-.06.48-.41.59-.47.25-.11.56-.17.94-.17 1.05-.05 1.95-.45 2.75-1.25S8.95 7.77 9 6.73h-.02C9.59 6.37 10 5.73 10 5zM2 1.8c.66 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2C1.35 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2zm0 12.41c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm6-8c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"/></svg>
|
||
<div class="select-menu-item-text">
|
||
<span class="select-menu-item-heading">Create branch: <span class="js-new-item-name"></span></span>
|
||
<span class="description">from ‘patch-2’</span>
|
||
</div>
|
||
<input type="hidden" name="name" id="name" class="js-new-item-value">
|
||
<input type="hidden" name="branch" id="branch" value="patch-2">
|
||
<input type="hidden" name="path" id="path" value="sources/tech/20180115%20How%20debuggers%20really%20work.md">
|
||
</form>
|
||
</div>
|
||
|
||
<div class="select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket" data-tab-filter="tags">
|
||
<div data-filterable-for="context-commitish-filter-field" data-filterable-type="substring">
|
||
|
||
|
||
<a class="select-menu-item js-navigation-item js-navigation-open "
|
||
href="/stephenxs/TranslateProject/tree/0.0/sources/tech/20180115%20How%20debuggers%20really%20work.md"
|
||
data-name="0.0"
|
||
data-skip-pjax="true"
|
||
rel="nofollow">
|
||
<svg class="octicon octicon-check select-menu-item-icon" viewBox="0 0 12 16" version="1.1" width="12" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5L12 5z"/></svg>
|
||
<span class="select-menu-item-text css-truncate-target" title="0.0">
|
||
0.0
|
||
</span>
|
||
</a>
|
||
</div>
|
||
|
||
<div class="select-menu-no-results">Nothing to show</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="BtnGroup float-right">
|
||
<a href="/stephenxs/TranslateProject/find/patch-2"
|
||
class="js-pjax-capture-input btn btn-sm BtnGroup-item"
|
||
data-pjax
|
||
data-hotkey="t">
|
||
Find file
|
||
</a>
|
||
<clipboard-copy for="blob-path" class="btn btn-sm BtnGroup-item">
|
||
Copy path
|
||
</clipboard-copy>
|
||
</div>
|
||
<div id="blob-path" class="breadcrumb">
|
||
<span class="repo-root js-repo-root"><span class="js-path-segment"><a data-pjax="true" href="/stephenxs/TranslateProject/tree/patch-2"><span>TranslateProject</span></a></span></span><span class="separator">/</span><span class="js-path-segment"><a data-pjax="true" href="/stephenxs/TranslateProject/tree/patch-2/sources"><span>sources</span></a></span><span class="separator">/</span><span class="js-path-segment"><a data-pjax="true" href="/stephenxs/TranslateProject/tree/patch-2/sources/tech"><span>tech</span></a></span><span class="separator">/</span><strong class="final-path">20180115 How debuggers really work.md</strong>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
<div class="commit-tease">
|
||
<span class="float-right">
|
||
<a class="commit-tease-sha" href="/stephenxs/TranslateProject/commit/6d81dac07cfd1d4aca9a91d397de9786d043b7f9" data-pjax>
|
||
6d81dac
|
||
</a>
|
||
<relative-time datetime="2018-06-21T14:14:23Z">Jun 21, 2018</relative-time>
|
||
</span>
|
||
<div>
|
||
<a rel="author" data-skip-pjax="true" data-hovercard-user-id="5379172" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="/stephenxs"><img class="avatar" src="https://avatars2.githubusercontent.com/u/5379172?s=40&v=4" width="20" height="20" alt="@stephenxs" /></a>
|
||
<a class="user-mention" rel="author" data-hovercard-user-id="5379172" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="/stephenxs">stephenxs</a>
|
||
<a data-pjax="true" title="correct an error
|
||
|
||
correct an error" class="message" href="/stephenxs/TranslateProject/commit/6d81dac07cfd1d4aca9a91d397de9786d043b7f9">correct an error</a>
|
||
</div>
|
||
|
||
<div class="commit-tease-contributors">
|
||
<button type="button" class="btn-link muted-link contributors-toggle" data-facebox="#blob_contributors_box">
|
||
<strong>2</strong>
|
||
contributors
|
||
</button>
|
||
<a class="avatar-link" data-hovercard-user-id="5379172" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="/stephenxs/TranslateProject/commits/patch-2/sources/tech/20180115%20How%20debuggers%20really%20work.md?author=stephenxs">
|
||
<img class="avatar" src="https://avatars2.githubusercontent.com/u/5379172?s=40&v=4" width="20" height="20" alt="@stephenxs" />
|
||
</a> <a class="avatar-link" data-hovercard-user-id="6605174" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="/stephenxs/TranslateProject/commits/patch-2/sources/tech/20180115%20How%20debuggers%20really%20work.md?author=lujun9972">
|
||
<img class="avatar" src="https://avatars3.githubusercontent.com/u/6605174?s=40&v=4" width="20" height="20" alt="@lujun9972" />
|
||
</a>
|
||
|
||
</div>
|
||
|
||
<div id="blob_contributors_box" style="display:none">
|
||
<h2 class="facebox-header" data-facebox-id="facebox-header">Users who have contributed to this file</h2>
|
||
<ul class="facebox-user-list" data-facebox-id="facebox-description">
|
||
<li class="facebox-user-list-item">
|
||
<a class="d-inline-block" data-hovercard-user-id="5379172" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="/stephenxs"><img src="https://avatars3.githubusercontent.com/u/5379172?s=48&v=4" width="24" height="24" alt="@stephenxs" /></a>
|
||
<a data-hovercard-user-id="5379172" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="/stephenxs">stephenxs</a>
|
||
</li>
|
||
<li class="facebox-user-list-item">
|
||
<a class="d-inline-block" data-hovercard-user-id="6605174" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="/lujun9972"><img src="https://avatars2.githubusercontent.com/u/6605174?s=48&v=4" width="24" height="24" alt="@lujun9972" /></a>
|
||
<a data-hovercard-user-id="6605174" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="/lujun9972">lujun9972</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
<div class="file">
|
||
<div class="file-header">
|
||
<div class="file-actions">
|
||
|
||
<div class="BtnGroup">
|
||
<a id="raw-url" class="btn btn-sm BtnGroup-item" href="/stephenxs/TranslateProject/raw/patch-2/sources/tech/20180115%20How%20debuggers%20really%20work.md">Raw</a>
|
||
<a class="btn btn-sm js-update-url-with-hash BtnGroup-item" data-hotkey="b" href="/stephenxs/TranslateProject/blame/patch-2/sources/tech/20180115%20How%20debuggers%20really%20work.md">Blame</a>
|
||
<a rel="nofollow" class="btn btn-sm BtnGroup-item" href="/stephenxs/TranslateProject/commits/patch-2/sources/tech/20180115%20How%20debuggers%20really%20work.md">History</a>
|
||
</div>
|
||
|
||
|
||
<!-- '"` --><!-- </textarea></xmp> --></option></form><form class="inline-form js-update-url-with-hash" action="/stephenxs/TranslateProject/edit/patch-2/sources/tech/20180115%20How%20debuggers%20really%20work.md" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="authenticity_token" value="m+Oy9RycjROu5Ugp/XmWTPra9Fy2MD7q/j70GGIOdXRJWfmDKbvQhL511U4xGvsksuQA8Yc3uSmizR9fZ5+khQ==" />
|
||
<button class="btn-octicon tooltipped tooltipped-nw" type="submit"
|
||
aria-label="Edit this file" data-hotkey="e" data-disable-with>
|
||
<svg class="octicon octicon-pencil" viewBox="0 0 14 16" version="1.1" width="14" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M0 12v3h3l8-8-3-3-8 8zm3 2H1v-2h1v1h1v1zm10.3-9.3L12 6 9 3l1.3-1.3a.996.996 0 0 1 1.41 0l1.59 1.59c.39.39.39 1.02 0 1.41z"/></svg>
|
||
</button>
|
||
</form>
|
||
<!-- '"` --><!-- </textarea></xmp> --></option></form><form class="inline-form" action="/stephenxs/TranslateProject/delete/patch-2/sources/tech/20180115%20How%20debuggers%20really%20work.md" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="authenticity_token" value="4eymEJBdTRIrvtgPww6aW2oiIWRncp7cKCs/DTltYzBYYmsZq5F29AkZZZza7FKQu1Zw1g41vXNxmf/FgJRS/Q==" />
|
||
<button class="btn-octicon btn-octicon-danger tooltipped tooltipped-nw" type="submit"
|
||
aria-label="Delete this file" data-disable-with>
|
||
<svg class="octicon octicon-trashcan" viewBox="0 0 12 16" version="1.1" width="12" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M11 2H9c0-.55-.45-1-1-1H5c-.55 0-1 .45-1 1H2c-.55 0-1 .45-1 1v1c0 .55.45 1 1 1v9c0 .55.45 1 1 1h7c.55 0 1-.45 1-1V5c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1zm-1 12H3V5h1v8h1V5h1v8h1V5h1v8h1V5h1v9zm1-10H2V3h9v1z"/></svg>
|
||
</button>
|
||
</form> </div>
|
||
|
||
<div class="file-info">
|
||
99 lines (51 sloc)
|
||
<span class="file-info-divider"></span>
|
||
8.63 KB
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<div id="readme" class="readme blob instapaper_body">
|
||
<article class="markdown-body entry-content" itemprop="text"><h1><a id="user-content-调试器到底怎样工作" class="anchor" aria-hidden="true" href="#调试器到底怎样工作"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>调试器到底怎样工作</h1>
|
||
<p><a target="_blank" href="https://camo.githubusercontent.com/e33ffd6db8be59b39c4e0e25aa88c19f083a4134/68747470733a2f2f6f70656e736f757263652e636f6d2f73697465732f64656661756c742f66696c65732f7374796c65732f696d6167652d66756c6c2d73697a652f7075626c69632f6c6561642d696d616765732f616e6e6f79696e67627567732e706e673f69746f6b3d7977465a39394773"><img src="https://camo.githubusercontent.com/e33ffd6db8be59b39c4e0e25aa88c19f083a4134/68747470733a2f2f6f70656e736f757263652e636f6d2f73697465732f64656661756c742f66696c65732f7374796c65732f696d6167652d66756c6c2d73697a652f7075626c69632f6c6561642d696d616765732f616e6e6f79696e67627567732e706e673f69746f6b3d7977465a39394773" alt="" data-canonical-src="https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/annoyingbugs.png?itok=ywFZ99Gs" style="max-width:100%;"></a></p>
|
||
<p>供图:opensource.com</p>
|
||
<p>调试器是那些大多数(即使不是每个)开发人员在软件工程职业生涯中至少使用过一次的软件之一,但是你们中有多少人知道它们到底是如何工作的?我在悉尼 <a href="https://linux.conf.au/index.html" rel="nofollow">linux.conf.au 2018</a> 的演讲中,将讨论从头开始编写调试器...使用 <a href="https://www.rust-lang.org" rel="nofollow">Rust</a>!</p>
|
||
<p>在本文中,术语调试器/跟踪器可以互换。 “被跟踪者”是指正在被跟踪者跟踪的进程。</p>
|
||
<h3><a id="user-content-ptrace-系统调用" class="anchor" aria-hidden="true" href="#ptrace-系统调用"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>ptrace 系统调用</h3>
|
||
<p>大多数调试器严重依赖称为 <code>ptrace(2)</code> 的系统调用,其原型如下:</p>
|
||
<pre><code>long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);
|
||
</code></pre>
|
||
<p>这是一个可以操纵进程几乎所有方面的系统调用;但是,在调试器可以连接到一个进程之前,“被跟踪者”必须以请求 <code>PTRACE_TRACEME</code> 调用 <code>ptrace</code>。这告诉 Linux,父进程通过 <code>ptrace</code> 连接到这个进程是合法的。但是......我们如何强制一个进程调用 <code>ptrace</code>?很简单!<code>fork/execve</code> 提供了在 <code>fork</code> 之后但在被跟踪者真正开始使用 <code>execve</code> 之前调用 <code>ptrace</code> 的简单方法。很方便地,<code>fork</code> 还会返回被跟踪者的 <code>pid</code>,这是后面使用 <code>ptrace</code> 所必需的。</p>
|
||
<p>现在被跟踪者可以被调试器追踪,重要的变化发生了:</p>
|
||
<ul>
|
||
<li>每当一个信号被传送到被调试者时,它就会停止,并且一个可以被 <code>wait</code> 系列系统调用捕获的等待事件被传送给跟踪器。</li>
|
||
<li>每个 <code>execve</code> 系统调用都会导致 <code>SIGTRAP</code> 被传递给被跟踪者。(与之前的项目相结合,这意味着被跟踪者在一个 <code>execve</code> 完全发生之前停止。)</li>
|
||
</ul>
|
||
<p>这意味着,一旦我们发出 <code>PTRACE_TRACEME</code> 请求并调用 <code>execve</code> 系统调用来实际在被跟踪者(进程上下文)中启动程序时,被跟踪者将立即停止,因为 <code>execve</code> 会传递一个 <code>SIGTRAP</code>,并且会被跟踪器中的等待事件捕获。我们如何继续?正如人们所期望的那样,<code>ptrace</code> 有大量的请求可以用来告诉被跟踪者可以继续:</p>
|
||
<ul>
|
||
<li><code>PTRACE_CONT</code>:这是最简单的。 被跟踪者运行,直到它接收到一个信号,此时等待事件被传递给跟踪器。这是最常见的实现真实世界调试器的“继续直至断点”和“永远继续”选项的方式。断点将在下面介绍。</li>
|
||
<li><code>PTRACE_SYSCALL</code>:与 <code>PTRACE_CONT</code> 非常相似,但在进入系统调用之前以及在系统调用返回到用户空间之前停止。它可以与其他请求(我们将在本文后面介绍)结合使用来监视和修改系统调用的参数或返回值。系统调用追踪程序 <code>strace</code> 很大程度上使用这个请求来获知进程发起了哪些系统调用。</li>
|
||
<li><code>PTRACE_SINGLESTEP</code>:这个很好理解。如果您之前使用过调试器(你会知道),此请求会执行下一条指令,然后立即停止。</li>
|
||
</ul>
|
||
<p>我们可以通过各种各样的请求停止进程,但我们如何获得被调试者的状态?进程的状态大多是通过其寄存器捕获的,所以当然 <code>ptrace</code> 有一个请求来获得(或修改)寄存器:</p>
|
||
<ul>
|
||
<li><code>PTRACE_GETREGS</code>:这个请求将给出被跟踪者刚刚被停止时的寄存器的状态。</li>
|
||
<li><code>PTRACE_SETREGS</code>:如果跟踪器之前通过调用 <code>PTRACE_GETREGS</code> 得到了寄存器的值,它可以在参数结构中修改相应寄存器的值并使用 <code>PTRACE_SETREGS</code> 将寄存器设为新值。</li>
|
||
<li><code>PTRACE_PEEKUSER</code> 和 <code>PTRACE_POKEUSER</code>:这些允许从被跟踪者的 <code>USER</code> 区读取信息,这里保存了寄存器和其他有用的信息。 这可以用来修改单一寄存器,而避免使用更重的 <code>PTRACE_{GET,SET}REGS</code> 请求。</li>
|
||
</ul>
|
||
<p>在调试器仅仅修改寄存器是不够的。调试器有时需要读取一部分内存,甚至对其进行修改。GDB 可以使用 <code>print</code> 得到一个内存位置或变量的值。<code>ptrace</code> 通过下面的方法实现这个功能:</p>
|
||
<ul>
|
||
<li><code>PTRACE_PEEKTEXT</code> 和 <code>PTRACE_POKETEXT</code>:这些允许读取和写入被跟踪者地址空间中的一个字。当然,使用这个功能时被跟踪者要被暂停。</li>
|
||
</ul>
|
||
<p>真实世界的调试器也有类似断点和观察点的功能。 在接下来的部分中,我将深入体系结构对调试器支持的细节。为了清晰和简洁,本文将只考虑x86。</p>
|
||
<h3><a id="user-content-体系结构的支持" class="anchor" aria-hidden="true" href="#体系结构的支持"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>体系结构的支持</h3>
|
||
<p><code>ptrace</code> 很酷,但它是如何工作? 在前面的部分中,我们已经看到 <code>ptrace</code> 跟信号有很大关系:<code>SIGTRAP</code> 可以在单步跟踪、<code>execve</code> 之前以及系统调用前后被传送。信号可以通过一些方式产生,但我们将研究两个具体的例子,以展示信号可以被调试器用来在给定的位置停止程序(有效地创建一个断点!):</p>
|
||
<ul>
|
||
<li>
|
||
<p><strong>未定义的指令</strong>:当一个进程尝试执行一个未定义的指令,CPU 将产生一个异常。此异常通过 CPU 中断处理,内核中相应的中断处理程序被调用。这将导致一个 <code>SIGILL</code> 信号被发送给进程。 这依次导致进程被停止,跟踪器通过一个等待事件被通知,然后它可以决定后面做什么。在 x86 上,指令 <code>ud2</code> 被确保始终是未定义的。</p>
|
||
</li>
|
||
<li>
|
||
<p><strong>调试中断</strong>:前面的方法的问题是,<code>ud2</code> 指令需要占用两个字节的机器码。存在一条特殊的单字节指令能够触发一个中断,它是 <code>int $3</code>,机器码是 <code>0xCC</code>。 当该中断发出时,内核向进程发送一个 <code>SIGTRAP</code>,如前所述,跟踪器被通知。</p>
|
||
</li>
|
||
</ul>
|
||
<p>这很好,但如何做我们胁迫的被跟踪者执行这些指令? 这很简单:利用 <code>ptrace</code> 的 <code>PTRACE_POKETEXT</code> 请求,它可以覆盖内存中的一个字。 调试器将使用 <code>PTRACE_PEEKTEXT</code> 读取该位置原来的值并替换为 <code>0xCC</code> ,然后在其内部状态中记录该处原来的值,以及它是一个断点的事实。 下次被跟踪者执行到该位置时,它将被通过 <code>SIGTRAP</code> 信号自动停止。 然后调试器的最终用户可以决定如何继续(例如,检查寄存器)。</p>
|
||
<p>好吧,我们已经讲过了断点,那观察点呢? 当一个特定的内存位置被读或写,调试器如何停止程序? 当然你不可能为了能够读或写内存而去把每一个指令都覆盖为 <code>int $3</code>。有一组调试寄存器为了更有效的满足这个目的而被设计出来:</p>
|
||
<ul>
|
||
<li><code>DR0</code> 到 <code>DR3</code>:这些寄存器中的每个都包含一个地址(内存位置),调试器因为某种原因希望被跟踪者在那些地址那里停止。 其原因以掩码方式被设定在 <code>DR7</code> 寄存器中。</li>
|
||
<li><code>DR4</code> 和 <code>DR5</code>:这些分别是 <code>DR6</code> 和 <code>DR7</code>过时的别名。</li>
|
||
<li><code>DR6</code>:调试状态。包含有关 <code>DR0</code> 到 <code>DR3</code> 中的哪个寄存器导致调试异常被引发的信息。这被 Linux 用来计算与 <code>SIGTRAP</code> 信号一起传递给被跟踪者的信息。</li>
|
||
<li><code>DR7</code>:调试控制。通过使用这些寄存器中的位,调试器可以控制如何解释DR0至DR3中指定的地址。位掩码控制监视点的尺寸(监视1,2,4或8个字节)以及是否在执行、读取、写入时引发异常,或在读取或写入时引发异常。</li>
|
||
</ul>
|
||
<p>由于调试寄存器是进程的 <code>USER</code> 区域的一部分,调试器可以使用 <code>PTRACE_POKEUSER</code> 将值写入调试寄存器。调试寄存器只与特定进程相关,因此在进程抢占并重新获得 CPU 控制权之前,调试寄存器会被恢复。</p>
|
||
<h3><a id="user-content-冰山一角" class="anchor" aria-hidden="true" href="#冰山一角"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>冰山一角</h3>
|
||
<p>我们已经浏览了一个调试器的“冰山”:我们已经介绍了 <code>ptrace</code>,了解了它的一些功能,然后我们看到了 <code>ptrace</code> 是如何实现的。 <code>ptrace</code> 的某些部分可以用软件实现,但其它部分必须用硬件来实现,否则实现代价会非常高甚至无法实现。</p>
|
||
<p>当然有很多我们没有涉及。例如“调试器如何知道变量在内存中的位置?”等问题由于空间和时间限制而尚未解答,但我希望你从本文中学到了一些东西;如果它激起你的兴趣,网上有足够的资源可以了解更多。</p>
|
||
<p>想要了解更多,请查看 <a href="https://linux.conf.au/index.html" rel="nofollow">linux.conf.au</a> 中 Levente Kurusa 的演讲 <a href="https://rego.linux.conf.au/schedule/presentation/91/" rel="nofollow">Let's Write a Debugger!</a>,于一月 22-26 日在悉尼举办。</p>
|
||
<hr>
|
||
<p>via: <a href="https://opensource.com/article/18/1/how-debuggers-really-work" rel="nofollow">https://opensource.com/article/18/1/how-debuggers-really-work</a></p>
|
||
<p>作者:<a href="https://opensource.com/users/lkurusa" rel="nofollow">Levente Kurusa</a>
|
||
译者:<a href="https://github.com/stephenxs">stephenxs</a>
|
||
校对:<a href="https://github.com/%E6%A0%A1%E5%AF%B9%E8%80%85ID">校对者ID</a></p>
|
||
<p>本文由 <a href="https://github.com/LCTT/TranslateProject">LCTT</a> 原创编译,<a href="https://linux.cn/" rel="nofollow">Linux中国</a> 荣誉推出</p>
|
||
</article>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<button type="button" data-facebox="#jump-to-line" data-facebox-class="linejump" data-hotkey="l" class="d-none">Jump to Line</button>
|
||
<div id="jump-to-line" style="display:none">
|
||
<!-- '"` --><!-- </textarea></xmp> --></option></form><form class="js-jump-to-line-form" action="" accept-charset="UTF-8" method="get"><input name="utf8" type="hidden" value="✓" />
|
||
<input class="form-control linejump-input js-jump-to-line-field" type="text" placeholder="Jump to line…" aria-label="Jump to line" autofocus>
|
||
<button type="submit" class="btn">Go</button>
|
||
</form> </div>
|
||
|
||
|
||
</div>
|
||
<div class="modal-backdrop js-touch-events"></div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
|
||
<div class="footer container-lg px-3" role="contentinfo">
|
||
<div class="position-relative d-flex flex-justify-between pt-6 pb-2 mt-6 f6 text-gray border-top border-gray-light ">
|
||
<ul class="list-style-none d-flex flex-wrap ">
|
||
<li class="mr-3">© 2018 <span title="0.40935s from unicorn-f9bf79458-w4c5q">GitHub</span>, Inc.</li>
|
||
<li class="mr-3"><a data-ga-click="Footer, go to terms, text:terms" href="https://github.com/site/terms">Terms</a></li>
|
||
<li class="mr-3"><a data-ga-click="Footer, go to privacy, text:privacy" href="https://github.com/site/privacy">Privacy</a></li>
|
||
<li class="mr-3"><a href="https://help.github.com/articles/github-security/" data-ga-click="Footer, go to security, text:security">Security</a></li>
|
||
<li class="mr-3"><a href="https://status.github.com/" data-ga-click="Footer, go to status, text:status">Status</a></li>
|
||
<li><a data-ga-click="Footer, go to help, text:help" href="https://help.github.com">Help</a></li>
|
||
</ul>
|
||
|
||
<a aria-label="Homepage" title="GitHub" class="footer-octicon" href="https://github.com">
|
||
<svg height="24" class="octicon octicon-mark-github" viewBox="0 0 16 16" version="1.1" width="24" aria-hidden="true"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"/></svg>
|
||
</a>
|
||
<ul class="list-style-none d-flex flex-wrap ">
|
||
<li class="mr-3"><a data-ga-click="Footer, go to contact, text:contact" href="https://github.com/contact">Contact GitHub</a></li>
|
||
<li class="mr-3"><a href="https://developer.github.com" data-ga-click="Footer, go to api, text:api">API</a></li>
|
||
<li class="mr-3"><a href="https://training.github.com" data-ga-click="Footer, go to training, text:training">Training</a></li>
|
||
<li class="mr-3"><a href="https://shop.github.com" data-ga-click="Footer, go to shop, text:shop">Shop</a></li>
|
||
<li class="mr-3"><a href="https://blog.github.com" data-ga-click="Footer, go to blog, text:blog">Blog</a></li>
|
||
<li><a data-ga-click="Footer, go to about, text:about" href="https://github.com/about">About</a></li>
|
||
|
||
</ul>
|
||
</div>
|
||
<div class="d-flex flex-justify-center pb-6">
|
||
<span class="f6 text-gray-light"></span>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
<div id="ajax-error-message" class="ajax-error-message flash flash-error">
|
||
<svg class="octicon octicon-alert" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"/></svg>
|
||
<button type="button" class="flash-close js-ajax-error-dismiss" aria-label="Dismiss error">
|
||
<svg class="octicon octicon-x" viewBox="0 0 12 16" version="1.1" width="12" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48L7.48 8z"/></svg>
|
||
</button>
|
||
You can’t perform that action at this time.
|
||
</div>
|
||
|
||
|
||
<script crossorigin="anonymous" integrity="sha512-AJroIDzeBTsez82UXWwVAmoSz2nKhws/uQvJ8aKfadJZcvL83MIXMjRYm7MVZaKSNXvifa/OGpn54kiDBKpyLw==" type="application/javascript" src="https://assets-cdn.github.com/assets/compat-37e9ce8318a51dd51033283da82c8546.js"></script>
|
||
<script crossorigin="anonymous" integrity="sha512-yXdDCsnuszQP/Kev3bsmDhO0vw7+hDdRtqOv8ZqtWtG6pVapIqEQJ+WHntN6PU9BgXx1Y0AE386pTmd01AlSuA==" type="application/javascript" src="https://assets-cdn.github.com/assets/frameworks-215987af1fc2831b8b9806a99f0f56e0.js"></script>
|
||
|
||
<script crossorigin="anonymous" async="async" integrity="sha512-ORJFv+MbAalu7ppD7KnNV1XdRA059ouG2bozJ6tTdAzC9xB5vIbsiCA666gJmdwwWTzMobRHzxUKn1ywp1Onrg==" type="application/javascript" src="https://assets-cdn.github.com/assets/github-7980aa5e478c118f7f44e1202dc4e18d.js"></script>
|
||
|
||
|
||
|
||
<div class="js-stale-session-flash stale-session-flash flash flash-warn flash-banner d-none">
|
||
<svg class="octicon octicon-alert" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"/></svg>
|
||
<span class="signed-in-tab-flash">You signed in with another tab or window. <a href="">Reload</a> to refresh your session.</span>
|
||
<span class="signed-out-tab-flash">You signed out in another tab or window. <a href="">Reload</a> to refresh your session.</span>
|
||
</div>
|
||
<div class="facebox" id="facebox" style="display:none;">
|
||
<div class="facebox-popup">
|
||
<div class="facebox-content" role="dialog" aria-labelledby="facebox-header" aria-describedby="facebox-description">
|
||
</div>
|
||
<button type="button" class="facebox-close js-facebox-close" aria-label="Close modal">
|
||
<svg class="octicon octicon-x" viewBox="0 0 12 16" version="1.1" width="12" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48L7.48 8z"/></svg>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="Popover js-hovercard-content position-absolute" style="display: none; outline: none;" tabindex="0">
|
||
<div class="Popover-message Popover-message--bottom-left Popover-message--large Box box-shadow-large" style="width:360px;">
|
||
</div>
|
||
</div>
|
||
|
||
<div id="hovercard-aria-description" class="sr-only">
|
||
Press h to open a hovercard with more details.
|
||
</div>
|
||
|
||
|
||
</body>
|
||
</html>
|
||
|