TranslateProject/translated/tech/20180115 How debuggers really work.md
Stephen fdde73ff48
translation completed
translation completed 20180115 How debuggers really work
2018-06-21 22:21:24 +08:00

932 lines
71 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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&amp;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="/&lt;user-name&gt;/&lt;repo-name&gt;/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="&#x2713;" />
<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&amp;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="&#x2713;" /><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="&#x2713;" /><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="&#x2713;" /><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="&#x2713;" /><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="&#x2713;" /><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="&#x2713;" /><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="&#x2713;" /><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&amp;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&amp;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&amp;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&amp;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&amp;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="&#x2713;" /><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="&#x2713;" /><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="&#x2713;" />
<input class="form-control linejump-input js-jump-to-line-field" type="text" placeholder="Jump to line&hellip;" 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">&copy; 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 cant 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>