<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Morten's Dev</title><link href="https://www.mortens.dev/" rel="alternate"/><link href="https://www.mortens.dev/feeds/all.atom.xml" rel="self"/><id>https://www.mortens.dev/</id><updated>2020-04-21T20:45:03+02:00</updated><subtitle>C++, Cybersecurity, Python, Rust, Emacs, Clang, and other technobabble..</subtitle><entry><title>Emacs and the Language Server Protocol</title><link href="https://www.mortens.dev/blog/emacs-and-the-language-server-protocol/" rel="alternate"/><published>2019-03-28T21:56:01+02:00</published><updated>2020-04-21T20:45:03+02:00</updated><author><name>Morten</name></author><id>tag:www.mortens.dev,2019-03-28:/blog/emacs-and-the-language-server-protocol/</id><summary type="html">&lt;p>How to setup Emacs to use &lt;span class="caps">LSP&lt;/span> with C++, Python, and&amp;nbsp;Rust&lt;/p></summary><content type="html">&lt;p>Having used &lt;a href="https://www.gnu.org/software/emacs/">Emacs&lt;/a> since 2006, I never found a good, reliable, and general enough solution to code completion, symbol cross referencing, go-to definition until I stumbled upon the &lt;a href="https://langserver.org/">Language Server Protocol&lt;/a> (&lt;span class="caps">LSP&lt;/span>).&lt;/p> &lt;p>From the &lt;a href="https://microsoft.github.io/language-server-protocol/specification">specification&lt;/a>:&lt;/p> &lt;blockquote class="blockquote"> &lt;p>The Language Server protocol is used between a tool (the client) and a language smartness provider (the server) to integrate features like auto complete, go to definition, find all references and alike into the tool.&lt;/p> &lt;/blockquote> &lt;p>It tackles the code intelligence problem quite nicely: To support a given programming language with &lt;span class="caps">LSP&lt;/span>, a language server program must be implemented. When running, all editors and IDEs supporting &lt;span class="caps">LSP&lt;/span> will be able to employ its features. Adoption is already very good across the field. &lt;sup id="sf-emacs-and-the-language-server-protocol-1-back">&lt;a href="#sf-emacs-and-the-language-server-protocol-1" class="simple-footnote" title=" See lists of server implementations here and here, and client implementations. ">1&lt;/a>&lt;/sup>&lt;/p> &lt;p>&lt;span class="caps">LSP&lt;/span> reduces an &lt;span class="math">\(m \times n\)&lt;/span> complexity problem to &lt;span class="math">\(m + n\)&lt;/span>: the latter refers to only needing a language server for each language and a client for each &lt;span class="caps">IDE&lt;/span>, whereas the former means that for every language each &lt;span class="caps">IDE&lt;/span> would require, in most cases, standalone support.&lt;/p> &lt;h2>1. Prerequisites&lt;/h2> &lt;p>In this article, I will go over the configuration and setup of Emacs for &lt;span class="caps">LSP&lt;/span> support of C++, Python, and Rust. It is assumed that Emacs version 25.1 or later is already installed and setup for basic usage, and that you’re familiar with editing its config file. Additionally, I use macOS but the installation commands can easily be translated to other solutions and other OSs.&lt;/p> &lt;h2>2. Emacs configuration&lt;/h2> &lt;p>First install the &lt;a href="https://github.com/emacs-lsp/lsp-mode">lsp-mode&lt;/a> package, which is the &lt;span class="caps">LSP&lt;/span> client that we will be using:&lt;/p> &lt;p>&lt;kbd>M-x package-install ↵ lsp-mode ↵&lt;/kbd>&lt;/p> &lt;p>The initial configuration is very simple: &lt;sup id="sf-emacs-and-the-language-server-protocol-2-back">&lt;a href="#sf-emacs-and-the-language-server-protocol-2" class="simple-footnote" title=" use-package is great for automatically downloading and installing packages. ">2&lt;/a>&lt;/sup>&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="p">(&lt;/span>&lt;span class="nb">use-package&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-mode&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nb">:config&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nv">add-hook&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="ss">'c++-mode-hook&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">#'&lt;/span>&lt;span class="nv">lsp&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nv">add-hook&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="ss">'python-mode-hook&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">#'&lt;/span>&lt;span class="nv">lsp&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nv">add-hook&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="ss">'rust-mode-hook&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">#'&lt;/span>&lt;span class="nv">lsp&lt;/span>&lt;span class="p">))&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>&lt;code>lsp-mode&lt;/code> comes &lt;a href="https://github.com/emacs-lsp/lsp-mode#supported-languages">prepackaged&lt;/a> to use certain available &lt;span class="caps">LSP&lt;/span> servers, that it will automatically spin up when a mode requests it (by invoking &lt;code>lsp&lt;/code>). If &lt;span class="caps">LSP&lt;/span> servers were already installed at this point, then you would be all set.&lt;/p> &lt;h3>2.1. C++&lt;/h3> &lt;p>&lt;a href="https://clang.llvm.org/extra/clangd/">Clangd&lt;/a> is currently the best working language server for C++ for the projects I work on. Even though &lt;a href="https://github.com/cquery-project/cquery">cquery&lt;/a> comes as a default in &lt;code>lsp-mode&lt;/code>, and has more features than clangd, there were times that it would fail to find known symbols for large projects, and both the index generation time and size were longer and bigger than clangd’s.&lt;/p> &lt;p>The first working version of clangd is &lt;a href="https://llvm.org/">&lt;span class="caps">LLVM&lt;/span>&lt;/a> v7 but I’ve had the best results with v9 or later (at the time of writing v10 is default in Homebrew), so install &lt;span class="caps">LLVM&lt;/span> and thus clangd:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>brew&lt;span class="w"> &lt;/span>install&lt;span class="w"> &lt;/span>llvm %&lt;span class="w"> &lt;/span>which&lt;span class="w"> &lt;/span>clangd /usr/local/opt/llvm/bin/clangd &lt;/code>&lt;/pre>&lt;/div> &lt;p>&lt;strong>Edit 2020-04-21&lt;/strong>: No longer using &lt;code>--HEAD&lt;/code> since v10 is default.&lt;/p> &lt;p>Add the following to the &lt;code>lsp-mode&lt;/code> config:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="p">(&lt;/span>&lt;span class="nb">use-package&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-mode&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nb">:config&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="c1">;; `-background-index' requires clangd v8+!&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">setq&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-clients-clangd-args&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">'&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">"-j=4"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"-background-index"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"-log=error"&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="c1">;; ..&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">)&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>It tells clangd that it can use 4 concurrent jobs and to make a complete background index on disk. Without &lt;code>-background-index&lt;/code>, it will only keep an in-memory index of the files that are active in Emacs buffers, but to be able to find references and symbols in any project file the background index is recommended. The background index, named “.clangd” by default, is placed at the root of the project.&lt;/p> &lt;p>Clangd tries to locate the “compile_commands.json” file in the root of the project, but if you normally create separate build folders it is useful to place a symlink pointing to where “compile_commands.json” is located inside it. For instance, if the build folder is “build/debug/” the following symlink could be created at the project root:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="n">compile_commands&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">json&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">-&amp;gt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kr">build&lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="n">debug&lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="n">compile_commands&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">json&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Most build tools can output “compile_commands.json”. In &lt;a href="https://cmake.org">CMake&lt;/a> you write:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="nb">set&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">CMAKE_EXPORT_COMPILE_COMMANDS&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">ON&lt;/span>&lt;span class="p">)&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>&lt;strong>Edit 2020-04-21&lt;/strong>: Improved text referring to the background index and the symlinking of “compile_commands.json”.&lt;/p> &lt;h3>2.2. Python&lt;/h3> &lt;p>For Python, the default language server is &lt;a href="https://github.com/palantir/python-language-server">pyls&lt;/a>:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>pip&lt;span class="w"> &lt;/span>install&lt;span class="w"> &lt;/span>python-language-server %&lt;span class="w"> &lt;/span>which&lt;span class="w"> &lt;/span>pyls /usr/local/bin/pyls &lt;/code>&lt;/pre>&lt;/div> &lt;p>That’s it.&lt;/p> &lt;h3>2.3. Rust&lt;/h3> &lt;p>The default language server for Rust is &lt;a href="https://github.com/rust-lang/rls">rls&lt;/a> which is installed via &lt;a href="https://rustup.rs/">rustup&lt;/a>. Before installing rustup blindly, first download the shell script and look it over, then proceed:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>curl&lt;span class="w"> &lt;/span>https://sh.rustup.rs&lt;span class="w"> &lt;/span>-sSf&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="w"> &lt;/span>sh %&lt;span class="w"> &lt;/span>rustup&lt;span class="w"> &lt;/span>update %&lt;span class="w"> &lt;/span>rustup&lt;span class="w"> &lt;/span>component&lt;span class="w"> &lt;/span>add&lt;span class="w"> &lt;/span>rls&lt;span class="w"> &lt;/span>rust-analysis&lt;span class="w"> &lt;/span>rust-src %&lt;span class="w"> &lt;/span>which&lt;span class="w"> &lt;/span>rls ~/.cargo/bin/rls &lt;/code>&lt;/pre>&lt;/div> &lt;p>Skip the rustup installation if Rust is already installed.&lt;/p> &lt;h2>3. Usage&lt;/h2> &lt;p>Using &lt;span class="caps">LSP&lt;/span> is easy: open a source code file with one of the major modes associated the &lt;code>lsp&lt;/code> hook. If no running language server is handling the particular project, a new one will be spun up to communicate with &lt;code>lsp-mode&lt;/code>.&lt;/p> &lt;p>When &lt;span class="caps">LSP&lt;/span> does not know which project to associate a file, usually the first time visiting a file, it will ask what to do. In this case I’m testing using my &lt;a href="https://github.com/netromdk/vermin">vermin&lt;/a> project:&lt;/p> &lt;blockquote class="blockquote"> &lt;p>vermin.py is not part of any project. Select action:&lt;/p> &lt;/blockquote> &lt;p>The following actions are possible:&lt;/p> &lt;ul> &lt;li>Do not ask more for the current project (add “~/git/vermin/” to lsp-session-folder-blacklist)&lt;/li> &lt;li>Do not ask more for the current project (select ignore path interactively).&lt;/li> &lt;li>Do nothing and ask me again when opening other files from the folder.&lt;/li> &lt;li>Import project by selecting root directory interactively.&lt;/li> &lt;li>Import project root ~/git/vermin/&lt;/li> &lt;/ul> &lt;p>Usually the last option is what you want. Simply write &lt;kbd>Import ↹ root ↹ ↵&lt;/kbd>.&lt;/p> &lt;p>The minibuffer will display (the &lt;span class="caps">PID&lt;/span> will differ):&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>LSP :: Connected to [pyls:94242 status:starting]. &lt;/code>&lt;/pre>&lt;/div> &lt;p>To try out some &lt;span class="caps">LSP&lt;/span> functionality, take a look at the vermin’s entry point:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="ch">#!/usr/bin/env python&lt;/span> &lt;span class="kn">from&lt;/span> &lt;span class="nn">vermin.main&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">main&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="vm">__name__&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s2">"__main__"&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">main&lt;/span>&lt;span class="p">()&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Put the cursor at “main” right after &lt;code>import&lt;/code> on the second line. We want to find the definition of that function: &lt;kbd>M-x lsp-find-definition ↵&lt;/kbd>. Voila, that jumps to line 12 of “vermin/main.py”:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="c1"># ..&lt;/span> &lt;span class="k">def&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">():&lt;/span> &lt;span class="c1"># Cursor will be at 'm'.&lt;/span> &lt;span class="n">config&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Config&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="n">args&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">parse_args&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">sys&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">argv&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">:])&lt;/span> &lt;span class="c1"># ..&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>The minibuffer will show that it connected to the same pyls instance:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>LSP :: Connected to [pyls:94242]. &lt;/code>&lt;/pre>&lt;/div> &lt;p>Next, let’s try to find references of &lt;code>parse_args()&lt;/code> by placing the cursor on it and&lt;br>&lt;kbd>M-x lsp-find-references ↵&lt;/kbd>.&lt;/p> &lt;p>&lt;a href="https://www.mortens.dev/images/lsp-py-refs.png"> &lt;img alt="Results of lsp-find-references." class="img-fluid" src="https://www.mortens.dev/images/lsp-py-refs.png" width="400"> &lt;/a>&lt;/p> &lt;p>The results are displayed this way due to the &lt;a href="https://github.com/emacs-helm/helm">&lt;code>helm&lt;/code>&lt;/a> and &lt;a href="https://github.com/brotzeit/helm-xref">&lt;code>helm-xref&lt;/code>&lt;/a> packages.&lt;/p> &lt;p>Other useful commands:&lt;/p> &lt;ul> &lt;li>&lt;code>lsp-describe-thing-at-point&lt;/code>: displays the full documentation of the thing at point&lt;/li> &lt;li>&lt;code>lsp-rename&lt;/code>: renames the symbol (and all references to it) under point to a new name&lt;/li> &lt;li>&lt;code>lsp-execute-code-action&lt;/code>: executes code action, like “did you mean X instead of Y?”&lt;/li> &lt;li>&lt;code>lsp-describe-session&lt;/code>: describes current &lt;span class="caps">LSP&lt;/span> session and its capabilities&lt;/li> &lt;/ul> &lt;p>Take a look &lt;a href="https://github.com/emacs-lsp/lsp-mode#overview">here&lt;/a> for more information about extensions and features.&lt;/p> &lt;p>&lt;strong>Edit 2019-04-01&lt;/strong>: My &lt;a href="https://github.com/netromdk/.emacs.d">.emacs.d&lt;/a> is freely available for the complete &lt;span class="caps">LSP&lt;/span> configuration, and lots of other stuff related to Emacs.&lt;/p> &lt;h2>4. Extras&lt;/h2> &lt;p>This section is dedicated to extra features and niceties that I find makes &lt;span class="caps">LSP&lt;/span> more usable and powerful.&lt;/p> &lt;h3>4.1. &lt;code>lsp-ui&lt;/code>&lt;/h3> &lt;p>&lt;a href="https://github.com/emacs-lsp/lsp-ui">&lt;code>lsp-ui&lt;/code>&lt;/a> adds higher level &lt;span class="caps">UI&lt;/span> modules, like documentation child frame while hovering a symbol, integration with flycheck, and enables inline definition and references peeking - just to name a few things.&lt;/p> &lt;p>My configuration relies on &lt;a href="https://github.com/flycheck/flycheck">&lt;code>flycheck&lt;/code>&lt;/a> being set up:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="p">(&lt;/span>&lt;span class="nb">use-package&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-mode&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="c1">;; ..&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nb">:config&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">setq&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-prefer-flymake&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="no">nil&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">;; Prefer using lsp-ui (flycheck) over flymake.&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="c1">;; ..&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nb">use-package&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-ui&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nb">:requires&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-mode&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">flycheck&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nb">:config&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">setq&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-ui-doc-enable&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="no">t&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-ui-doc-use-childframe&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="no">t&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-ui-doc-position&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="ss">'top&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-ui-doc-include-signature&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="no">t&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-ui-sideline-enable&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="no">nil&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-ui-flycheck-enable&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="no">t&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-ui-flycheck-list-position&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="ss">'right&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-ui-flycheck-live-reporting&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="no">t&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-ui-peek-enable&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="no">t&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-ui-peek-list-width&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">60&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-ui-peek-peek-height&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">25&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nv">add-hook&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="ss">'lsp-mode-hook&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="ss">'lsp-ui-mode&lt;/span>&lt;span class="p">))&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;h3>4.2. &lt;code>hydra&lt;/code>&lt;/h3> &lt;p>Another thing that’s really useful, not just related to &lt;span class="caps">LSP&lt;/span>, is the &lt;a href="https://github.com/abo-abo/hydra">&lt;code>hydra&lt;/code>&lt;/a> package, which is described very well by its author:&lt;/p> &lt;blockquote class="blockquote"> &lt;p>The Hydra is vanquished once Hercules, any binding that isn’t the Hydra’s head, arrives. Note that Hercules, besides vanquishing the Hydra, will still serve his original purpose, calling his proper command. This makes the Hydra very seamless, it’s like a minor mode that disables itself auto-magically.&lt;/p> &lt;/blockquote> &lt;p>In essence, it yields a menu with keybindings in the minibuffer, a hydra, which won’t be shown if the bindings are pressed fast enough.&lt;/p> &lt;p>The following configuration is trimmed down to only show parts related to &lt;span class="caps">LSP&lt;/span>:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="p">(&lt;/span>&lt;span class="nb">use-package&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">hydra&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nb">use-package&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">helm&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nb">use-package&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">helm-lsp&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nb">:config&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nb">defun&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">netrom/helm-lsp-workspace-symbol-at-point&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">interactive&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">let&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">((&lt;/span>&lt;span class="nv">current-prefix-arg&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="no">t&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nf">call-interactively&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">#'&lt;/span>&lt;span class="nv">helm-lsp-workspace-symbol&lt;/span>&lt;span class="p">)))&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nb">defun&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">netrom/helm-lsp-global-workspace-symbol-at-point&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">interactive&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">let&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">((&lt;/span>&lt;span class="nv">current-prefix-arg&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="no">t&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nf">call-interactively&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">#'&lt;/span>&lt;span class="nv">helm-lsp-global-workspace-symbol&lt;/span>&lt;span class="p">))))&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nb">use-package&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-mode&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nb">:requires&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">hydra&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">helm&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">helm-lsp&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="c1">;; ..&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">setq&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">netrom--general-lsp-hydra-heads&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="o">'&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="c1">;; Xref&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">"d"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">xref-find-definitions&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"Definitions"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">:column&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"Xref"&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">"D"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">xref-find-definitions-other-window&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"-&amp;gt; other win"&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">"r"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">xref-find-references&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"References"&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">"s"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">netrom/helm-lsp-workspace-symbol-at-point&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"Helm search"&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">"S"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">netrom/helm-lsp-global-workspace-symbol-at-point&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"Helm global search"&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="c1">;; Peek&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">"C-d"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-ui-peek-find-definitions&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"Definitions"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">:column&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"Peek"&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">"C-r"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-ui-peek-find-references&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"References"&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">"C-i"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-ui-peek-find-implementation&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"Implementation"&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="c1">;; LSP&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">"p"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-describe-thing-at-point&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"Describe at point"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">:column&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"LSP"&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">"C-a"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-execute-code-action&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"Execute code action"&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">"R"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-rename&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"Rename"&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">"t"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-goto-type-definition&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"Type definition"&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">"i"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-goto-implementation&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"Implementation"&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">"f"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">helm-imenu&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"Filter funcs/classes (Helm)"&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">"C-c"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-describe-session&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"Describe session"&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="c1">;; Flycheck&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">"l"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">lsp-ui-flycheck-list&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"List errs/warns/notes"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">:column&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"Flycheck"&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nv">netrom--misc-lsp-hydra-heads&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="o">'&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="c1">;; Misc&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">"q"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="no">nil&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"Cancel"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">:column&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"Misc"&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">"b"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">pop-tag-mark&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"Back"&lt;/span>&lt;span class="p">)))&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="c1">;; Create general hydra.&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nf">eval&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">`&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nv">defhydra&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">netrom/lsp-hydra&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nb">:color&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">blue&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">:hint&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="no">nil&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="o">,@&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nf">append&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nv">netrom--general-lsp-hydra-heads&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nv">netrom--misc-lsp-hydra-heads&lt;/span>&lt;span class="p">)))&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nv">add-hook&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="ss">'lsp-mode-hook&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nb">lambda&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nv">local-set-key&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nv">kbd&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"C-c C-l"&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="ss">'netrom/lsp-hydra/body&lt;/span>&lt;span class="p">))))&lt;/span>&lt;span class="w"> &lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>To activate the hydra, press &lt;kbd>C-c C-l&lt;/kbd> with the cursor placed somewhere relevant:&lt;/p> &lt;p>&lt;a href="https://www.mortens.dev/images/lsp-hydra.png"> &lt;img alt="LSP hydra shown for C-c C-l." class="img-fluid" src="https://www.mortens.dev/images/lsp-hydra.png"> &lt;/a>&lt;/p> &lt;p>&lt;strong>Edit 2019-04-01&lt;/strong>: Using &lt;code>helm-imenu&lt;/code> instead of &lt;code>lsp-ui-imenu&lt;/code> because the former enables easy filtering via Helm.&lt;/p> &lt;h3>4.3. &lt;code>company-lsp&lt;/code>&lt;/h3> &lt;p>For completions at cursor, I use &lt;a href="https://github.com/company-mode/company-mode">&lt;code>company-mode&lt;/code>&lt;/a> with &lt;a href="https://github.com/tigersoldier/company-lsp">&lt;code>company-lsp&lt;/code>&lt;/a> for the purposes of &lt;span class="caps">LSP&lt;/span>:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="p">(&lt;/span>&lt;span class="nb">use-package&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">company&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nb">:config&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">setq&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">company-idle-delay&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">0.3&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nv">global-company-mode&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nv">global-set-key&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nv">kbd&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"C-&amp;lt;tab&amp;gt;"&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="ss">'company-complete&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nb">use-package&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">company-lsp&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nb">:requires&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">company&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nb">:config&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nb">push&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="ss">'company-lsp&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">company-backends&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="c1">;; Disable client-side cache because the LSP server does a better job.&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">setq&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">company-transformers&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="no">nil&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nv">company-lsp-async&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="no">t&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nv">company-lsp-cache-candidates&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="no">nil&lt;/span>&lt;span class="p">))&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;!-- To make the footnotes appear further down. --> &lt;p>&lt;br>&lt;br>&lt;/p> &lt;script type="text/javascript">if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) { var align = "center", indent = "0em", linebreak = "false"; if (true) { align = (screen.width &lt; 768) ? "left" : align; indent = (screen.width &lt; 768) ? "0em" : indent; linebreak = (screen.width &lt; 768) ? 'true' : linebreak; } var mathjaxscript = document.createElement('script'); mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#'; mathjaxscript.type = 'text/javascript'; mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=TeX-AMS-MML_HTMLorMML'; var configscript = document.createElement('script'); configscript.type = 'text/x-mathjax-config'; configscript[(window.opera ? "innerHTML" : "text")] = "MathJax.Hub.Config({" + " config: ['MMLorHTML.js']," + " TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'none' } }," + " jax: ['input/TeX','input/MathML','output/HTML-CSS']," + " extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," + " displayAlign: '"+ align +"'," + " displayIndent: '"+ indent +"'," + " showMathMenu: true," + " messageStyle: 'normal'," + " tex2jax: { " + " inlineMath: [ ['\\\\(','\\\\)'] ], " + " displayMath: [ ['$$','$$'] ]," + " processEscapes: true," + " preview: 'TeX'," + " }, " + " 'HTML-CSS': { " + " availableFonts: ['STIX', 'TeX']," + " preferredFont: 'STIX'," + " styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," + " linebreaks: { automatic: "+ linebreak +", width: '90% container' }," + " }, " + "}); " + "if ('default' !== 'default') {" + "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" + "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" + "VARIANT['normal'].fonts.unshift('MathJax_default');" + "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" + "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" + "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" + "});" + "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" + "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" + "VARIANT['normal'].fonts.unshift('MathJax_default');" + "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" + "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" + "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" + "});" + "}"; (document.body || document.getElementsByTagName('head')[0]).appendChild(configscript); (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript); } &lt;/script>&lt;ol class="simple-footnotes">&lt;li id="sf-emacs-and-the-language-server-protocol-1"> See lists of server implementations &lt;a href="https://langserver.org/#implementations-server">here&lt;/a> and &lt;a href="https://microsoft.github.io/language-server-protocol/implementors/servers/">here&lt;/a>, and &lt;a href="https://langserver.org/#implementations-client">client implementations&lt;/a>. &lt;a href="#sf-emacs-and-the-language-server-protocol-1-back" class="simple-footnote-back">↩︎&lt;/a>&lt;/li>&lt;li id="sf-emacs-and-the-language-server-protocol-2"> &lt;a href="https://github.com/jwiegley/use-package">use-package&lt;/a> is great for automatically downloading and installing packages. &lt;a href="#sf-emacs-and-the-language-server-protocol-2-back" class="simple-footnote-back">↩︎&lt;/a>&lt;/li>&lt;/ol></content><category term="IDE"/><category term="emacs"/><category term="lsp"/><category term="xref"/><category term="code-completion"/><category term="cpp"/><category term="python"/><category term="rust"/></entry><entry><title>Sigs: Migrating to C++17</title><link href="https://www.mortens.dev/blog/sigs-migrating-to-cpp17/" rel="alternate"/><published>2019-03-21T23:19:20+02:00</published><updated>2019-03-21T23:19:20+02:00</updated><author><name>Morten</name></author><id>tag:www.mortens.dev,2019-03-21:/blog/sigs-migrating-to-cpp17/</id><summary type="html">&lt;p>Migrating Sigs to&amp;nbsp;C++17&lt;/p></summary><content type="html">&lt;p>&lt;a href="https://github.com/netromdk/sigs">sigs&lt;/a> has been migrated to using C++17 from C++14. Didn’t take much doing other than some CMake configuration tweakings, and to update the &lt;a href="https://github.com/google/googletest">Google Test&lt;/a> framework to version 1.8.1.&lt;/p> &lt;h2>1. CMake configuration changes&lt;/h2> &lt;p>Setting the required C++ standard to C++17 was done with:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="nb">set&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">CMAKE_CXX_STANDARD&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">17&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="nb">set&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">CMAKE_CXX_STANDARD_REQUIRED&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">ON&lt;/span>&lt;span class="p">)&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>And was tested to work with Clang 6 + 7, &lt;span class="caps">GCC&lt;/span> 7 + 8, and &lt;span class="caps">VS&lt;/span> 2017.&lt;/p> &lt;h2>2. C++17 features&lt;/h2> &lt;p>The fun part was finding new features to put into action in the project.&lt;/p> &lt;h3>2.1. &lt;a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0189r1.pdf">[[nodiscard]]&lt;/a>&lt;/h3> &lt;p>In certain cases it is important that the returned value is not discarded, which is exactly what &lt;code>[[nodiscard]]&lt;/code> achieves. For example, in the following a warning will be shown if the return value of &lt;code>Signal::interface()&lt;/code> isn’t used:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="p">[[&lt;/span>&lt;span class="n">nodiscard&lt;/span>&lt;span class="p">]]&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kr">inline&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">unique_ptr&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Interface&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">interface&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">noexcept&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">make_unique&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Interface&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="p">}&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;h3>2.2. &lt;a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0305r1.html">Initializer statements&lt;/a>&lt;/h3> &lt;p>Having the means to include initialization in &lt;code>if&lt;/code> and &lt;code>switch&lt;/code> statements is a very nice, new feature that helps scoping variables for intent. If an initialization is made before the statement then it will be live in the parent scope of that statement, a scope that might span for more than what was intended.&lt;/p> &lt;p>There were no places in sigs where a scope of an initializer to an &lt;code>if&lt;/code> or &lt;code>switch&lt;/code> statement spanned more than was necessary, but still, there were four places to put it into effect. An example:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="k">if&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">auto&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="n">sig&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">entry&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">signal&lt;/span>&lt;span class="p">();&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">sig&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="n">sig&lt;/span>&lt;span class="p">)(&lt;/span>&lt;span class="n">retFunc&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">forward&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Args&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">args&lt;/span>&lt;span class="p">)...);&lt;/span> &lt;span class="p">}&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;h3>2.3. &lt;a href="https://en.cppreference.com/w/cpp/utility/optional">std::optional&lt;/a>&lt;/h3> &lt;p>The concept of an optional value is a nice abstraction that enables one to not use any value, from the return value space, to act as an indicator of null or an error. For instance, if the return type of a function is &lt;code>int&lt;/code> then an error might be signaled by using &lt;code>-1&lt;/code>, but that also means that the value cannot be used as a valid value. Instead, &lt;code>std::optional&amp;lt;T&amp;gt;&lt;/code> can be seen as a &lt;code>bool&lt;/code> for indicating an error and the encapsulated value &lt;code>T&lt;/code> if defined.&lt;/p> &lt;p>An example usage from the project:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="k">template&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="k">typename&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nc">Ret&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">typename&lt;/span>&lt;span class="p">...&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Args&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="k">class&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nc">Signal&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Ret&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">Args&lt;/span>&lt;span class="p">...)&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">final&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="c1">// ..&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="kt">void&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">disconnect&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">optional&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Connection&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">conn&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">noexcept&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="c1">// ..&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span> &lt;span class="c1">// ..&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>This solution is clearer and better than the previous one:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="kt">void&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">disconnect&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">Connection&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">conn&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">nullptr&lt;/span>&lt;span class="p">)&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;h3>2.4. &lt;a href="https://en.cppreference.com/w/cpp/types/is_void">std::is_void_v&lt;/a>&lt;/h3> &lt;p>&lt;code>std::is_void&lt;/code> was introduced already in C++11 and &lt;code>std::is_void_v&lt;/code> is basically just a helper variable template:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="k">template&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="k">typename&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nc">T&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="kr">inline&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">constexpr&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">bool&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">is_void_v&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">is_void&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">T&lt;/span>&lt;span class="o">&amp;gt;::&lt;/span>&lt;span class="n">value&lt;/span>&lt;span class="p">;&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>In sigs, I ended up replacing the local &lt;code>isVoidReturn()&lt;/code> with direct usage due to the shortness of the statement:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="k">static_assert&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">is_void_v&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">ReturnType&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"Must have non-void return type!"&lt;/span>&lt;span class="p">);&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;h3>2.5. &lt;a href="https://en.cppreference.com/w/cpp/language/noexcept_spec">noexcept&lt;/a>&lt;/h3> &lt;p>Every function in C++ is either potentially throwing or non-throwing. &lt;code>noexcept&lt;/code> is interesting because it marks a function as non-throwing, and informs that exceptions aren’t being used intentionally. If an exception is thrown anyway, &lt;a href="https://en.cppreference.com/w/cpp/error/terminate">&lt;code>std::terminate&lt;/code>&lt;/a> is invoked.&lt;/p> &lt;p>&lt;code>noexcept&lt;/code> was added in C++11 but I didn’t put it to use until now. It made it possible for the compiler to optimize further and reduced the size of the binaries somewhat. Can’t say no to that. I found 34 places to add it, like:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="n">Signal&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">noexcept&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">default&lt;/span>&lt;span class="p">;&lt;/span> &lt;/code>&lt;/pre>&lt;/div></content><category term="Projects"/><category term="sigs"/><category term="cpp"/><category term="cpp17"/></entry><entry><title>Sigs: Return Values</title><link href="https://www.mortens.dev/blog/sigs-return-values/" rel="alternate"/><published>2019-03-08T21:36:12+02:00</published><updated>2019-03-08T21:36:12+02:00</updated><author><name>Morten</name></author><id>tag:www.mortens.dev,2019-03-08:/blog/sigs-return-values/</id><summary type="html">&lt;p>Handling return values from slots with&amp;nbsp;Sigs&lt;/p></summary><content type="html">&lt;p>&lt;a href="https://github.com/netromdk/sigs">sigs&lt;/a>, my simple thread-safe signal/slot C++ library, has been extended to support slot functions with non-void return types. Such return values can be gathered by triggering the signal with a function. But the argument type must be the same as the return type!&lt;/p> &lt;p>The following example adds together the integers from each connected slot:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="n">sigs&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">Signal&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">s&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">s&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">connect&lt;/span>&lt;span class="p">([]&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">});&lt;/span> &lt;span class="n">s&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">connect&lt;/span>&lt;span class="p">([]&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">});&lt;/span> &lt;span class="n">s&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">connect&lt;/span>&lt;span class="p">([]&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">});&lt;/span> &lt;span class="kt">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">sum&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">s&lt;/span>&lt;span class="p">([&lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">sum&lt;/span>&lt;span class="p">](&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">retVal&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">sum&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">+=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">retVal&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">});&lt;/span> &lt;span class="c1">// sum is now = 1 + 2 + 3 = 6&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>This enables a way for each slot to contribute to a shared computation.&lt;/p> &lt;p>In order to implement this, the &lt;code>Signal::operator(..)&lt;/code> must be able to assert that the provided function either has no argument, representing a slot with no return type, or a non-void argument for a slot with one. Enter &lt;code>VoidableFunction&lt;/code>:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="k">template&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="k">typename&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nc">T&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="k">class&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nc">VoidableFunction&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="k">using&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">func&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">function&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">void&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">T&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">};&lt;/span> &lt;span class="c1">/// Specialization for void return types.&lt;/span> &lt;span class="k">template&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;gt;&lt;/span> &lt;span class="k">class&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nc">VoidableFunction&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">void&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="k">using&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">func&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">function&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">void&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">};&lt;/span> &lt;span class="k">template&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="k">typename&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nc">Ret&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">typename&lt;/span>&lt;span class="p">...&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Args&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="k">class&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nc">Signal&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Ret&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">Args&lt;/span>&lt;span class="p">...)&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="k">using&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Slot&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">function&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Ret&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">Args&lt;/span>&lt;span class="p">...)&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="c1">// ..&lt;/span> &lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="k">using&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">ReturnType&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Ret&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="c1">// ..&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="k">template&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="k">typename&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nc">RetFunc&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">typename&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nc">VoidableFunction&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">ReturnType&lt;/span>&lt;span class="o">&amp;gt;::&lt;/span>&lt;span class="n">func&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="kt">void&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">operator&lt;/span>&lt;span class="p">()(&lt;/span>&lt;span class="k">const&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">RetFunc&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">retFunc&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Args&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;amp;&amp;amp;&lt;/span>&lt;span class="p">...&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">args&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="c1">// ..&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>A specialization was necessary for void return types due to the lack of a value: a value is only be provided in the non-void case, which is what &lt;code>typename RetFunc = typename VoidableFunction&amp;lt;ReturnType&amp;gt;::func&lt;/code> yields.&lt;/p> &lt;p>The &lt;code>isVoidReturn()&lt;/code> is used to statically assert at compile-time that no void return type is used:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="w"> &lt;/span>&lt;span class="k">template&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="k">typename&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nc">RetFunc&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">typename&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nc">VoidableFunction&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">ReturnType&lt;/span>&lt;span class="o">&amp;gt;::&lt;/span>&lt;span class="n">func&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="kt">void&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">operator&lt;/span>&lt;span class="p">()(&lt;/span>&lt;span class="k">const&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">RetFunc&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">retFunc&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Args&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;amp;&amp;amp;&lt;/span>&lt;span class="p">...&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">args&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="k">static_assert&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="n">isVoidReturn&lt;/span>&lt;span class="p">(),&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"Must have non-void return type!"&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="c1">// ..&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span> &lt;span class="k">private&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="k">static&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">constexpr&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">bool&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">isVoidReturn&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">is_void&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">ReturnType&lt;/span>&lt;span class="o">&amp;gt;::&lt;/span>&lt;span class="n">value&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>This is necessary since the prototype must match both void and non-void types such that it can yield a sensible error in the former case.&lt;/p> &lt;p>For each connected slot, the return value function is called with the result of the slot function, or passed to chained signals:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="n">Lock&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">lock&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">entriesMutex&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">auto&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">entry&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">entries&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="k">auto&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="n">sig&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">entry&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">signal&lt;/span>&lt;span class="p">();&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="k">if&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">sig&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="n">sig&lt;/span>&lt;span class="p">)(&lt;/span>&lt;span class="n">retFunc&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">forward&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Args&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">args&lt;/span>&lt;span class="p">)...);&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="k">else&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="n">retFunc&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">entry&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">slot&lt;/span>&lt;span class="p">()(&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">forward&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Args&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">args&lt;/span>&lt;span class="p">)...));&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span> &lt;span class="p">}&lt;/span> &lt;/code>&lt;/pre>&lt;/div></content><category term="Projects"/><category term="sigs"/><category term="cpp"/><category term="cpp14"/></entry><entry><title>Revamped and new Domain</title><link href="https://www.mortens.dev/blog/revamped-and-new-domain/" rel="alternate"/><published>2019-03-03T13:30:08+02:00</published><updated>2019-03-03T13:30:08+02:00</updated><author><name>Morten</name></author><id>tag:www.mortens.dev,2019-03-03:/blog/revamped-and-new-domain/</id><summary type="html">&lt;p>New domain, new static page&amp;nbsp;generator&lt;/p></summary><content type="html">&lt;p>I moved my blog to the new domain &lt;a href="https://mortens.dev">mortens.dev&lt;/a> using &lt;a href="https://blog.getpelican.com/">Pelican&lt;/a> as the static page generator. The blog is still a collection of articles and ramblings about programming, security, algorithms, and technology in general.&lt;/p></content><category term="General"/><category term="pelican"/><category term="site generator"/></entry><entry><title>Patching Binaries: Live Modification</title><link href="https://www.mortens.dev/blog/patching-binaries-live-modification/" rel="alternate"/><published>2016-09-07T23:35:59+02:00</published><updated>2016-09-07T23:35:59+02:00</updated><author><name>Morten</name></author><id>tag:www.mortens.dev,2016-09-07:/blog/patching-binaries-live-modification/</id><summary type="html">&lt;p>How to do modification of running&amp;nbsp;programs&lt;/p></summary><content type="html">&lt;p>&lt;em>Patching Binaries&lt;/em> is a series of articles about how to extract information and modify program behavior. It focuses on the Mac &lt;a href="https://en.wikipedia.org/wiki/Mach-O">Mach-O&lt;/a> executable format for the &lt;a href="https://en.wikipedia.org/wiki/X86-64">x86-64&lt;/a> architecture, but the techniques are similar for other formats.&lt;/p> &lt;p>Before proceeding it is recommended reading the &lt;a href="https://www.mortens.dev/blog/patching-binaries-jumping-the-fence/">second part&lt;/a> about jumping and bypassing instructions.&lt;/p> &lt;p>&lt;em>The files used in this article can be found &lt;a href="https://github.com/netromdk/patching/tree/master/live">here&lt;/a>.&lt;/em>&lt;/p> &lt;p>This article is about how to change data values of a program and how to read from and write to memory of a live program to change its behavior.&lt;/p> &lt;p>Compile “score.cc” as “score” and strip it. Let’s see what it does:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>./score &lt;span class="nv">score&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Think of a game that displays your high score. We want to change it so use “lldb_entrypoint.sh” to start it up:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>./lldb_entrypoint.sh&lt;span class="w"> &lt;/span>score &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>target&lt;span class="w"> &lt;/span>create&lt;span class="w"> &lt;/span>&lt;span class="s2">"score"&lt;/span> Current&lt;span class="w"> &lt;/span>executable&lt;span class="w"> &lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="w"> &lt;/span>to&lt;span class="w"> &lt;/span>&lt;span class="s1">'score'&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>x86_64&lt;span class="o">)&lt;/span>. &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">command&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">source&lt;/span>&lt;span class="w"> &lt;/span>-s&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">'/tmp/.lldbcmds'&lt;/span> Executing&lt;span class="w"> &lt;/span>commands&lt;span class="w"> &lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">'/tmp/.lldbcmds'&lt;/span>. &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>b&lt;span class="w"> &lt;/span>0x0000000100001140 Breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>:&lt;span class="w"> &lt;/span>&lt;span class="nv">address&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>0x0000000100001140 &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>r Process&lt;span class="w"> &lt;/span>&lt;span class="m">38693&lt;/span>&lt;span class="w"> &lt;/span>launched:&lt;span class="w"> &lt;/span>&lt;span class="s1">'/Users/netrom/git/patching/live/score'&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>x86_64&lt;span class="o">)&lt;/span> Process&lt;span class="w"> &lt;/span>&lt;span class="m">38693&lt;/span>&lt;span class="w"> &lt;/span>stopped *&lt;span class="w"> &lt;/span>thread&lt;span class="w"> &lt;/span>&lt;span class="c1">#1: tid = 0x28e293, 0x0000000100001140 score`___lldb_unnamed_function1$$score, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1&lt;/span> &lt;span class="w"> &lt;/span>frame&lt;span class="w"> &lt;/span>&lt;span class="c1">#0: 0x0000000100001140 score`___lldb_unnamed_function1$$score&lt;/span> score&lt;span class="sb">`&lt;/span>___lldb_unnamed_function1&lt;span class="nv">$$&lt;/span>score: -&amp;gt;&lt;span class="w"> &lt;/span>0x100001140&lt;span class="w"> &lt;/span>&amp;lt;+0&amp;gt;:&lt;span class="w"> &lt;/span>pushq&lt;span class="w"> &lt;/span>%rbp &lt;span class="w"> &lt;/span>0x100001141&lt;span class="w"> &lt;/span>&amp;lt;+1&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rsp,&lt;span class="w"> &lt;/span>%rbp &lt;span class="w"> &lt;/span>0x100001144&lt;span class="w"> &lt;/span>&amp;lt;+4&amp;gt;:&lt;span class="w"> &lt;/span>subq&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x10,&lt;span class="w"> &lt;/span>%rsp &lt;span class="w"> &lt;/span>0x100001148&lt;span class="w"> &lt;/span>&amp;lt;+8&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>0xeb1&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rdi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>void&lt;span class="w"> &lt;/span>*&lt;span class="o">)&lt;/span>0x00007fff78ba32f8:&lt;span class="w"> &lt;/span>std::__1::cout &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>dis&lt;span class="w"> &lt;/span>-b score&lt;span class="sb">`&lt;/span>___lldb_unnamed_function1&lt;span class="nv">$$&lt;/span>score: -&amp;gt;&lt;span class="w"> &lt;/span>0x100001140&lt;span class="w"> &lt;/span>&amp;lt;+0&amp;gt;:&lt;span class="w"> &lt;/span>&lt;span class="m">55&lt;/span>&lt;span class="w"> &lt;/span>pushq&lt;span class="w"> &lt;/span>%rbp &lt;span class="w"> &lt;/span>0x100001141&lt;span class="w"> &lt;/span>&amp;lt;+1&amp;gt;:&lt;span class="w"> &lt;/span>&lt;span class="m">48&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">89&lt;/span>&lt;span class="w"> &lt;/span>e5&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rsp,&lt;span class="w"> &lt;/span>%rbp &lt;span class="w"> &lt;/span>0x100001144&lt;span class="w"> &lt;/span>&amp;lt;+4&amp;gt;:&lt;span class="w"> &lt;/span>&lt;span class="m">48&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">83&lt;/span>&lt;span class="w"> &lt;/span>ec&lt;span class="w"> &lt;/span>&lt;span class="m">10&lt;/span>&lt;span class="w"> &lt;/span>subq&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x10,&lt;span class="w"> &lt;/span>%rsp &lt;span class="w"> &lt;/span>0x100001148&lt;span class="w"> &lt;/span>&amp;lt;+8&amp;gt;:&lt;span class="w"> &lt;/span>&lt;span class="m">48&lt;/span>&lt;span class="w"> &lt;/span>8b&lt;span class="w"> &lt;/span>3d&lt;span class="w"> &lt;/span>b1&lt;span class="w"> &lt;/span>0e&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>0xeb1&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rdi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>void&lt;span class="w"> &lt;/span>*&lt;span class="o">)&lt;/span>0x00007fff78ba32f8:&lt;span class="w"> &lt;/span>std::__1::cout &lt;span class="w"> &lt;/span>0x10000114f&lt;span class="w"> &lt;/span>&amp;lt;+15&amp;gt;:&lt;span class="w"> &lt;/span>&lt;span class="m">48&lt;/span>&lt;span class="w"> &lt;/span>8d&lt;span class="w"> &lt;/span>&lt;span class="m">35&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">26&lt;/span>&lt;span class="w"> &lt;/span>0e&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>leaq&lt;span class="w"> &lt;/span>0xe26&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rsi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">"score = "&lt;/span> &lt;span class="w"> &lt;/span>0x100001156&lt;span class="w"> &lt;/span>&amp;lt;+22&amp;gt;:&lt;span class="w"> &lt;/span>c7&lt;span class="w"> &lt;/span>&lt;span class="m">45&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">fc&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>movl&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x0,&lt;span class="w"> &lt;/span>-0x4&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>0x10000115d&lt;span class="w"> &lt;/span>&amp;lt;+29&amp;gt;:&lt;span class="w"> &lt;/span>c7&lt;span class="w"> &lt;/span>&lt;span class="m">45&lt;/span>&lt;span class="w"> &lt;/span>f8&lt;span class="w"> &lt;/span>&lt;span class="m">01&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>movl&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x1,&lt;span class="w"> &lt;/span>-0x8&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>0x100001164&lt;span class="w"> &lt;/span>&amp;lt;+36&amp;gt;:&lt;span class="w"> &lt;/span>e8&lt;span class="w"> &lt;/span>&lt;span class="m">37&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x1000011a0&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>___lldb_unnamed_function2&lt;span class="nv">$$&lt;/span>score &lt;span class="w"> &lt;/span>0x100001169&lt;span class="w"> &lt;/span>&amp;lt;+41&amp;gt;:&lt;span class="w"> &lt;/span>8b&lt;span class="w"> &lt;/span>&lt;span class="m">75&lt;/span>&lt;span class="w"> &lt;/span>f8&lt;span class="w"> &lt;/span>movl&lt;span class="w"> &lt;/span>-0x8&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%esi &lt;span class="w"> &lt;/span>0x10000116c&lt;span class="w"> &lt;/span>&amp;lt;+44&amp;gt;:&lt;span class="w"> &lt;/span>&lt;span class="m">48&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">89&lt;/span>&lt;span class="w"> &lt;/span>c7&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rax,&lt;span class="w"> &lt;/span>%rdi &lt;span class="w"> &lt;/span>0x10000116f&lt;span class="w"> &lt;/span>&amp;lt;+47&amp;gt;:&lt;span class="w"> &lt;/span>e8&lt;span class="w"> &lt;/span>2c&lt;span class="w"> &lt;/span>0c&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x100001da0&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>symbol&lt;span class="w"> &lt;/span>stub&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>:&lt;span class="w"> &lt;/span>std::__1::basic_ostream&amp;lt;char,&lt;span class="w"> &lt;/span>std::__1::char_traits&amp;lt;char&amp;gt;&lt;span class="w"> &lt;/span>&amp;gt;::operator&amp;lt;&amp;lt;&lt;span class="o">(&lt;/span>int&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>0x100001174&lt;span class="w"> &lt;/span>&amp;lt;+52&amp;gt;:&lt;span class="w"> &lt;/span>&lt;span class="m">48&lt;/span>&lt;span class="w"> &lt;/span>8d&lt;span class="w"> &lt;/span>&lt;span class="m">35&lt;/span>&lt;span class="w"> &lt;/span>0a&lt;span class="w"> &lt;/span>0e&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>leaq&lt;span class="w"> &lt;/span>0xe0a&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rsi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">"'\n'"&lt;/span> &lt;span class="w"> &lt;/span>0x10000117b&lt;span class="w"> &lt;/span>&amp;lt;+59&amp;gt;:&lt;span class="w"> &lt;/span>&lt;span class="m">48&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">89&lt;/span>&lt;span class="w"> &lt;/span>c7&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rax,&lt;span class="w"> &lt;/span>%rdi &lt;span class="w"> &lt;/span>0x10000117e&lt;span class="w"> &lt;/span>&amp;lt;+62&amp;gt;:&lt;span class="w"> &lt;/span>e8&lt;span class="w"> &lt;/span>1d&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x1000011a0&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>___lldb_unnamed_function2&lt;span class="nv">$$&lt;/span>score &lt;span class="w"> &lt;/span>0x100001183&lt;span class="w"> &lt;/span>&amp;lt;+67&amp;gt;:&lt;span class="w"> &lt;/span>&lt;span class="m">31&lt;/span>&lt;span class="w"> &lt;/span>c9&lt;span class="w"> &lt;/span>xorl&lt;span class="w"> &lt;/span>%ecx,&lt;span class="w"> &lt;/span>%ecx &lt;span class="w"> &lt;/span>0x100001185&lt;span class="w"> &lt;/span>&amp;lt;+69&amp;gt;:&lt;span class="w"> &lt;/span>&lt;span class="m">48&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">89&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">45&lt;/span>&lt;span class="w"> &lt;/span>f0&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rax,&lt;span class="w"> &lt;/span>-0x10&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>0x100001189&lt;span class="w"> &lt;/span>&amp;lt;+73&amp;gt;:&lt;span class="w"> &lt;/span>&lt;span class="m">89&lt;/span>&lt;span class="w"> &lt;/span>c8&lt;span class="w"> &lt;/span>movl&lt;span class="w"> &lt;/span>%ecx,&lt;span class="w"> &lt;/span>%eax &lt;span class="w"> &lt;/span>0x10000118b&lt;span class="w"> &lt;/span>&amp;lt;+75&amp;gt;:&lt;span class="w"> &lt;/span>&lt;span class="m">48&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">83&lt;/span>&lt;span class="w"> &lt;/span>c4&lt;span class="w"> &lt;/span>&lt;span class="m">10&lt;/span>&lt;span class="w"> &lt;/span>addq&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x10,&lt;span class="w"> &lt;/span>%rsp &lt;span class="w"> &lt;/span>0x10000118f&lt;span class="w"> &lt;/span>&amp;lt;+79&amp;gt;:&lt;span class="w"> &lt;/span>5d&lt;span class="w"> &lt;/span>popq&lt;span class="w"> &lt;/span>%rbp &lt;span class="w"> &lt;/span>0x100001190&lt;span class="w"> &lt;/span>&amp;lt;+80&amp;gt;:&lt;span class="w"> &lt;/span>c3&lt;span class="w"> &lt;/span>retq &lt;/code>&lt;/pre>&lt;/div> &lt;p>The score of value &lt;code>1&lt;/code> is passed to to &lt;code>-0x8(%rbp)&lt;/code> at &lt;code>0x10000115d&lt;/code>. At offset &lt;code>0x115d+3=0x1160&lt;/code> an 32-bit integer is passed as 4 bytes &lt;code>1 0 0 0&lt;/code> (little endian).&lt;/p> &lt;p>Let’s say we want to change this value to &lt;code>0x4030201 = 67305985&lt;/code>. First the number must be split up into the 4 bytes: &lt;code>1 2 3 4&lt;/code> (remember the reverse order here!). Then we can patch the program:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>./patch_bytes.py&lt;span class="w"> &lt;/span>score&lt;span class="w"> &lt;/span>0x1160&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">2&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">3&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">4&lt;/span> Patching&lt;span class="w"> &lt;/span>&lt;span class="s2">"score"&lt;/span>&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>offset&lt;span class="w"> &lt;/span>&lt;span class="m">4448&lt;/span>&lt;span class="w"> &lt;/span>with:&lt;span class="w"> &lt;/span>&lt;span class="o">[&lt;/span>&lt;span class="m">1&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="m">2&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="m">3&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="m">4&lt;/span>&lt;span class="o">]&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="m">4&lt;/span>&lt;span class="w"> &lt;/span>bytes&lt;span class="o">)&lt;/span> Read&lt;span class="w"> &lt;/span>&lt;span class="m">14348&lt;/span>&lt;span class="w"> &lt;/span>bytes Changing&lt;span class="w"> &lt;/span>values&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>&lt;span class="m">4448&lt;/span>&lt;span class="w"> &lt;/span>to&lt;span class="w"> &lt;/span>&lt;span class="m">4452&lt;/span> Writing&lt;span class="w"> &lt;/span>new&lt;span class="w"> &lt;/span>data %&lt;span class="w"> &lt;/span>./score &lt;span class="nv">score&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">67305985&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Inspecting the instructions yields what we expect:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>dis&lt;span class="w"> &lt;/span>-b&lt;span class="w"> &lt;/span>-c&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="w"> &lt;/span>-s&lt;span class="w"> &lt;/span>0x10000115d score&lt;span class="sb">`&lt;/span>___lldb_unnamed_function1&lt;span class="nv">$$&lt;/span>score: &lt;span class="w"> &lt;/span>0x10000115d&lt;span class="w"> &lt;/span>&amp;lt;+29&amp;gt;:&lt;span class="w"> &lt;/span>c7&lt;span class="w"> &lt;/span>&lt;span class="m">45&lt;/span>&lt;span class="w"> &lt;/span>f8&lt;span class="w"> &lt;/span>&lt;span class="m">01&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">02&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">03&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">04&lt;/span>&lt;span class="w"> &lt;/span>movl&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x4030201,&lt;span class="w"> &lt;/span>-0x8&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">imm&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>0x4030201 &lt;/code>&lt;/pre>&lt;/div> &lt;p>Recompile and strip “score.cc” to get back to square one.&lt;/p> &lt;p>&lt;strong>We can also read and write registers of a program while it is running!&lt;/strong>&lt;/p> &lt;p>So let’s try changing the score right after it is set to &lt;code>1&lt;/code> but before being used. As we saw before the value is saved into &lt;code>-0x8(%rbp)&lt;/code> which we first have to understand what it means. The &lt;em>&lt;span class="caps">RBP&lt;/span>&lt;/em> (base pointer) register holds the pointer to the beginning of a stack frame while executing a function. Allocating on the stack is done by using a proper offset from the &lt;span class="caps">RBP&lt;/span>, and since addresses grow upwards we use a negative addressing of &lt;code>-0x8&lt;/code> in this case.&lt;/p> &lt;p>In order to go further we need the value of the &lt;span class="caps">RBP&lt;/span> register:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>lldb&lt;span class="w"> &lt;/span>score &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>target&lt;span class="w"> &lt;/span>create&lt;span class="w"> &lt;/span>&lt;span class="s2">"score"&lt;/span> Current&lt;span class="w"> &lt;/span>executable&lt;span class="w"> &lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="w"> &lt;/span>to&lt;span class="w"> &lt;/span>&lt;span class="s1">'score'&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>x86_64&lt;span class="o">)&lt;/span>. &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>b&lt;span class="w"> &lt;/span>0x100001164 Breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>:&lt;span class="w"> &lt;/span>&lt;span class="nv">address&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>0x0000000100001164 &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>r Process&lt;span class="w"> &lt;/span>&lt;span class="m">40054&lt;/span>&lt;span class="w"> &lt;/span>launched:&lt;span class="w"> &lt;/span>&lt;span class="s1">'/Users/netrom/git/patching/live/score'&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>x86_64&lt;span class="o">)&lt;/span> Process&lt;span class="w"> &lt;/span>&lt;span class="m">40054&lt;/span>&lt;span class="w"> &lt;/span>stopped *&lt;span class="w"> &lt;/span>thread&lt;span class="w"> &lt;/span>&lt;span class="c1">#1: tid = 0x298ab1, 0x0000000100001164 score`___lldb_unnamed_function1$$score + 36, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1&lt;/span> &lt;span class="w"> &lt;/span>frame&lt;span class="w"> &lt;/span>&lt;span class="c1">#0: 0x0000000100001164 score`___lldb_unnamed_function1$$score + 36&lt;/span> score&lt;span class="sb">`&lt;/span>___lldb_unnamed_function1&lt;span class="nv">$$&lt;/span>score: -&amp;gt;&lt;span class="w"> &lt;/span>0x100001164&lt;span class="w"> &lt;/span>&amp;lt;+36&amp;gt;:&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x1000011a0&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>___lldb_unnamed_function2&lt;span class="nv">$$&lt;/span>score &lt;span class="w"> &lt;/span>0x100001169&lt;span class="w"> &lt;/span>&amp;lt;+41&amp;gt;:&lt;span class="w"> &lt;/span>movl&lt;span class="w"> &lt;/span>-0x8&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%esi &lt;span class="w"> &lt;/span>0x10000116c&lt;span class="w"> &lt;/span>&amp;lt;+44&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rax,&lt;span class="w"> &lt;/span>%rdi &lt;span class="w"> &lt;/span>0x10000116f&lt;span class="w"> &lt;/span>&amp;lt;+47&amp;gt;:&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x100001da0&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>symbol&lt;span class="w"> &lt;/span>stub&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>:&lt;span class="w"> &lt;/span>std::__1::basic_ostream&amp;lt;char,&lt;span class="w"> &lt;/span>std::__1::char_traits&amp;lt;char&amp;gt;&lt;span class="w"> &lt;/span>&amp;gt;::operator&amp;lt;&amp;lt;&lt;span class="o">(&lt;/span>int&lt;span class="o">)&lt;/span> &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>reg&lt;span class="w"> &lt;/span>&lt;span class="nb">read&lt;/span>&lt;span class="w"> &lt;/span>rbp &lt;span class="w"> &lt;/span>&lt;span class="nv">rbp&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>0x00007fff5fbff5e0 &lt;/code>&lt;/pre>&lt;/div> &lt;p>Then we want to verify that &lt;code>-0x8(%rbp)&lt;/code> has value &lt;code>1&lt;/code>:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>p&lt;span class="w"> &lt;/span>*&lt;span class="o">(&lt;/span>int*&lt;span class="o">)(&lt;/span>0x00007fff5fbff5e0&lt;span class="w"> &lt;/span>-&lt;span class="w"> &lt;/span>0x8&lt;span class="o">)&lt;/span> &lt;span class="o">(&lt;/span>int&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>&lt;em>That might look obscure but the command means to print the deferenced value of an integer pointer address at &lt;code>-0x8(%rbp)&lt;/code>.&lt;/em>&lt;/p> &lt;p>Changing the value can be done in the following way:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>p&lt;span class="w"> &lt;/span>*&lt;span class="o">(&lt;/span>int*&lt;span class="o">)(&lt;/span>0x00007fff5fbff5e0&lt;span class="w"> &lt;/span>-&lt;span class="w"> &lt;/span>0x8&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">42&lt;/span> &lt;span class="o">(&lt;/span>int&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">$1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">42&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Letting the program continue will show that it worked:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>c Process&lt;span class="w"> &lt;/span>&lt;span class="m">40054&lt;/span>&lt;span class="w"> &lt;/span>resuming &lt;span class="nv">score&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">42&lt;/span> Process&lt;span class="w"> &lt;/span>&lt;span class="m">40054&lt;/span>&lt;span class="w"> &lt;/span>exited&lt;span class="w"> &lt;/span>with&lt;span class="w"> &lt;/span>&lt;span class="nv">status&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>0x00000000&lt;span class="o">)&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>&lt;em>Note that the way to change the value could also have been written as:&lt;/em>&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>(lldb) p &lt;span class="gs">*(int*&lt;/span>)(`$rbp`-0x8) = 42 &lt;/code>&lt;/pre>&lt;/div> &lt;p>Which makes it possible to read the register without copying the address by hand!&lt;/p> &lt;p>How much easier would it be if we could automate this? A lot, I agree. So create a file called “setvalue.lldb” with the following contents:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>b 0x100001164 r p &lt;span class="gs">*(int*&lt;/span>)(`$rbp`-0x8) = 42 c exit &lt;/code>&lt;/pre>&lt;/div> &lt;p>And run it like this:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>lldb&lt;span class="w"> &lt;/span>-s&lt;span class="w"> &lt;/span>setvalue.lldb&lt;span class="w"> &lt;/span>score &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>target&lt;span class="w"> &lt;/span>create&lt;span class="w"> &lt;/span>&lt;span class="s2">"score"&lt;/span> Current&lt;span class="w"> &lt;/span>executable&lt;span class="w"> &lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="w"> &lt;/span>to&lt;span class="w"> &lt;/span>&lt;span class="s1">'score'&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>x86_64&lt;span class="o">)&lt;/span>. &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">command&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">source&lt;/span>&lt;span class="w"> &lt;/span>-s&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">'setvalue.lldb'&lt;/span> Executing&lt;span class="w"> &lt;/span>commands&lt;span class="w"> &lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">'/Users/netrom/git/patching/live/setvalue.lldb'&lt;/span>. &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>b&lt;span class="w"> &lt;/span>0x100001164 Breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>:&lt;span class="w"> &lt;/span>&lt;span class="nv">address&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>0x0000000100001164 &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>r Process&lt;span class="w"> &lt;/span>&lt;span class="m">40286&lt;/span>&lt;span class="w"> &lt;/span>stopped *&lt;span class="w"> &lt;/span>thread&lt;span class="w"> &lt;/span>&lt;span class="c1">#1: tid = 0x29c96b, 0x0000000100001164 score`___lldb_unnamed_function1$$score + 36, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1&lt;/span> &lt;span class="w"> &lt;/span>frame&lt;span class="w"> &lt;/span>&lt;span class="c1">#0: 0x0000000100001164 score`___lldb_unnamed_function1$$score + 36&lt;/span> score&lt;span class="sb">`&lt;/span>___lldb_unnamed_function1&lt;span class="nv">$$&lt;/span>score: -&amp;gt;&lt;span class="w"> &lt;/span>0x100001164&lt;span class="w"> &lt;/span>&amp;lt;+36&amp;gt;:&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x1000011a0&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>___lldb_unnamed_function2&lt;span class="nv">$$&lt;/span>score &lt;span class="w"> &lt;/span>0x100001169&lt;span class="w"> &lt;/span>&amp;lt;+41&amp;gt;:&lt;span class="w"> &lt;/span>movl&lt;span class="w"> &lt;/span>-0x8&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%esi &lt;span class="w"> &lt;/span>0x10000116c&lt;span class="w"> &lt;/span>&amp;lt;+44&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rax,&lt;span class="w"> &lt;/span>%rdi &lt;span class="w"> &lt;/span>0x10000116f&lt;span class="w"> &lt;/span>&amp;lt;+47&amp;gt;:&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x100001da0&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>symbol&lt;span class="w"> &lt;/span>stub&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>:&lt;span class="w"> &lt;/span>std::__1::basic_ostream&amp;lt;char,&lt;span class="w"> &lt;/span>std::__1::char_traits&amp;lt;char&amp;gt;&lt;span class="w"> &lt;/span>&amp;gt;::operator&amp;lt;&amp;lt;&lt;span class="o">(&lt;/span>int&lt;span class="o">)&lt;/span> Process&lt;span class="w"> &lt;/span>&lt;span class="m">40286&lt;/span>&lt;span class="w"> &lt;/span>launched:&lt;span class="w"> &lt;/span>&lt;span class="s1">'/Users/netrom/git/patching/live/score'&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>x86_64&lt;span class="o">)&lt;/span> &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>p&lt;span class="w"> &lt;/span>*&lt;span class="o">(&lt;/span>int*&lt;span class="o">)(&lt;/span>&lt;span class="sb">`&lt;/span>&lt;span class="nv">$rbp&lt;/span>&lt;span class="sb">`&lt;/span>-0x8&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">42&lt;/span> &lt;span class="o">(&lt;/span>int&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">$1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">42&lt;/span> &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>c &lt;span class="nv">score&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">42&lt;/span> Process&lt;span class="w"> &lt;/span>&lt;span class="m">40286&lt;/span>&lt;span class="w"> &lt;/span>resuming Process&lt;span class="w"> &lt;/span>&lt;span class="m">40286&lt;/span>&lt;span class="w"> &lt;/span>exited&lt;span class="w"> &lt;/span>with&lt;span class="w"> &lt;/span>&lt;span class="nv">status&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>0x00000000&lt;span class="o">)&lt;/span> &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">exit&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Another approach is to start &lt;span class="caps">LLDB&lt;/span> in a wait-for-process state where it will attach once a program with the given process name has been started. Something to note, though, is that the address &lt;code>0x100001164&lt;/code> of before won’t work in this example due to how it attaches to the process. Instead we use the fact that &lt;code>main()&lt;/code> is the first function so we can name it in &lt;span class="caps">LLDB&lt;/span> as &lt;code>___lldb_unnamed_function1$$score&lt;/code>. Also, since it attaches to a running program we don’t have to start the process so we just continue after setting the break point. Finally, because we know that the original &lt;code>0x100001164&lt;/code> is 36 instructions after the start of &lt;code>main()&lt;/code> we set a break point using the &lt;span class="caps">RIP&lt;/span> (instruction pointer) register with &lt;code>$rip+36&lt;/code>.&lt;/p> &lt;p>Create file “waitsetvalue.lldb” with the following contents:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>b score`___lldb_unnamed_function1$$score c b &lt;span class="sb">`$rip+36`&lt;/span> c p &lt;span class="gs">*(int*&lt;/span>)(`$rbp`-0x8) = 42 c exit &lt;/code>&lt;/pre>&lt;/div> &lt;p>Next we fire up &lt;span class="caps">LLDB&lt;/span> in one terminal (note it has to run as root/sudo to have privileges):&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>sudo&lt;span class="w"> &lt;/span>lldb&lt;span class="w"> &lt;/span>-w&lt;span class="w"> &lt;/span>-s&lt;span class="w"> &lt;/span>waitsetvalue.lldb&lt;span class="w"> &lt;/span>-n&lt;span class="w"> &lt;/span>score &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>process&lt;span class="w"> &lt;/span>attach&lt;span class="w"> &lt;/span>--name&lt;span class="w"> &lt;/span>&lt;span class="s2">"score"&lt;/span>&lt;span class="w"> &lt;/span>--waitfor &lt;/code>&lt;/pre>&lt;/div> &lt;p>It is now in a waiting mode, so in the second terminal we simply start the program:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>./score &lt;/code>&lt;/pre>&lt;/div> &lt;p>&lt;span class="caps">LLDB&lt;/span> will immediately attach in the other terminal:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">command&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">source&lt;/span>&lt;span class="w"> &lt;/span>-s&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">'waitsetvalue.lldb'&lt;/span> Executing&lt;span class="w"> &lt;/span>commands&lt;span class="w"> &lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">'/Users/netrom/git/patching/live/waitsetvalue.lldb'&lt;/span>. &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>b&lt;span class="w"> &lt;/span>score&lt;span class="sb">`&lt;/span>___lldb_unnamed_function1&lt;span class="nv">$$&lt;/span>score Breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>:&lt;span class="w"> &lt;/span>&lt;span class="nv">where&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>score&lt;span class="sb">`&lt;/span>___lldb_unnamed_function1&lt;span class="nv">$$&lt;/span>score,&lt;span class="w"> &lt;/span>&lt;span class="nv">address&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>0x000000010ec6c140 &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>c Process&lt;span class="w"> &lt;/span>&lt;span class="m">44506&lt;/span>&lt;span class="w"> &lt;/span>resuming Process&lt;span class="w"> &lt;/span>&lt;span class="m">44506&lt;/span>&lt;span class="w"> &lt;/span>stopped *&lt;span class="w"> &lt;/span>thread&lt;span class="w"> &lt;/span>&lt;span class="c1">#1: tid = 0x2a93a3, 0x000000010ec6c140 score`___lldb_unnamed_function1$$score, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1&lt;/span> &lt;span class="w"> &lt;/span>frame&lt;span class="w"> &lt;/span>&lt;span class="c1">#0: 0x000000010ec6c140 score`___lldb_unnamed_function1$$score&lt;/span> score&lt;span class="sb">`&lt;/span>___lldb_unnamed_function1&lt;span class="nv">$$&lt;/span>score: -&amp;gt;&lt;span class="w"> &lt;/span>0x10ec6c140&lt;span class="w"> &lt;/span>&amp;lt;+0&amp;gt;:&lt;span class="w"> &lt;/span>pushq&lt;span class="w"> &lt;/span>%rbp &lt;span class="w"> &lt;/span>0x10ec6c141&lt;span class="w"> &lt;/span>&amp;lt;+1&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rsp,&lt;span class="w"> &lt;/span>%rbp &lt;span class="w"> &lt;/span>0x10ec6c144&lt;span class="w"> &lt;/span>&amp;lt;+4&amp;gt;:&lt;span class="w"> &lt;/span>subq&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x10,&lt;span class="w"> &lt;/span>%rsp &lt;span class="w"> &lt;/span>0x10ec6c148&lt;span class="w"> &lt;/span>&amp;lt;+8&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>0xeb1&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rdi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>void&lt;span class="w"> &lt;/span>*&lt;span class="o">)&lt;/span>0x00007fff78ba32f8:&lt;span class="w"> &lt;/span>std::__1::cout &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>b&lt;span class="w"> &lt;/span>&lt;span class="sb">`&lt;/span>&lt;span class="nv">$rip&lt;/span>+36&lt;span class="sb">`&lt;/span> Breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">2&lt;/span>:&lt;span class="w"> &lt;/span>&lt;span class="nv">where&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>score&lt;span class="sb">`&lt;/span>___lldb_unnamed_function1&lt;span class="nv">$$&lt;/span>score&lt;span class="w"> &lt;/span>+&lt;span class="w"> &lt;/span>&lt;span class="m">36&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="nv">address&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>0x000000010ec6c164 &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>c Process&lt;span class="w"> &lt;/span>&lt;span class="m">44506&lt;/span>&lt;span class="w"> &lt;/span>resuming Process&lt;span class="w"> &lt;/span>&lt;span class="m">44506&lt;/span>&lt;span class="w"> &lt;/span>stopped *&lt;span class="w"> &lt;/span>thread&lt;span class="w"> &lt;/span>&lt;span class="c1">#1: tid = 0x2a93a3, 0x000000010ec6c164 score`___lldb_unnamed_function1$$score + 36, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1&lt;/span> &lt;span class="w"> &lt;/span>frame&lt;span class="w"> &lt;/span>&lt;span class="c1">#0: 0x000000010ec6c164 score`___lldb_unnamed_function1$$score + 36&lt;/span> score&lt;span class="sb">`&lt;/span>___lldb_unnamed_function1&lt;span class="nv">$$&lt;/span>score: -&amp;gt;&lt;span class="w"> &lt;/span>0x10ec6c164&lt;span class="w"> &lt;/span>&amp;lt;+36&amp;gt;:&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x10ec6c1a0&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>___lldb_unnamed_function2&lt;span class="nv">$$&lt;/span>score &lt;span class="w"> &lt;/span>0x10ec6c169&lt;span class="w"> &lt;/span>&amp;lt;+41&amp;gt;:&lt;span class="w"> &lt;/span>movl&lt;span class="w"> &lt;/span>-0x8&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%esi &lt;span class="w"> &lt;/span>0x10ec6c16c&lt;span class="w"> &lt;/span>&amp;lt;+44&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rax,&lt;span class="w"> &lt;/span>%rdi &lt;span class="w"> &lt;/span>0x10ec6c16f&lt;span class="w"> &lt;/span>&amp;lt;+47&amp;gt;:&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x10ec6cda0&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>symbol&lt;span class="w"> &lt;/span>stub&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>:&lt;span class="w"> &lt;/span>std::__1::basic_ostream&amp;lt;char,&lt;span class="w"> &lt;/span>std::__1::char_traits&amp;lt;char&amp;gt;&lt;span class="w"> &lt;/span>&amp;gt;::operator&amp;lt;&amp;lt;&lt;span class="o">(&lt;/span>int&lt;span class="o">)&lt;/span> &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>p&lt;span class="w"> &lt;/span>*&lt;span class="o">(&lt;/span>int*&lt;span class="o">)(&lt;/span>&lt;span class="sb">`&lt;/span>&lt;span class="nv">$rbp&lt;/span>&lt;span class="sb">`&lt;/span>-0x8&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">42&lt;/span> &lt;span class="o">(&lt;/span>int&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">$2&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">42&lt;/span> &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>c Process&lt;span class="w"> &lt;/span>&lt;span class="m">44506&lt;/span>&lt;span class="w"> &lt;/span>resuming Process&lt;span class="w"> &lt;/span>&lt;span class="m">44506&lt;/span>&lt;span class="w"> &lt;/span>exited&lt;span class="w"> &lt;/span>with&lt;span class="w"> &lt;/span>&lt;span class="nv">status&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>0x00000000&lt;span class="o">)&lt;/span> &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">exit&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Finally, in the second terminal, it will output:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>score = 42 &lt;/code>&lt;/pre>&lt;/div> &lt;p>Phew!&lt;/p> &lt;p>The last example is attaching to a program after it has started. Compile “looper.cc” as “looper” and strip it. Then run it in a terminal:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>./looper &lt;span class="nv">score&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">20&lt;/span> &lt;span class="nv">score&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">20&lt;/span> &lt;span class="nv">score&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">20&lt;/span> ... &lt;/code>&lt;/pre>&lt;/div> &lt;p>Open another terminal and attach to the process:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>lldb&lt;span class="w"> &lt;/span>-p&lt;span class="w"> &lt;/span>&lt;span class="sb">`&lt;/span>pgrep&lt;span class="w"> &lt;/span>looper&lt;span class="sb">`&lt;/span> &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>process&lt;span class="w"> &lt;/span>attach&lt;span class="w"> &lt;/span>--pid&lt;span class="w"> &lt;/span>&lt;span class="m">49530&lt;/span> Process&lt;span class="w"> &lt;/span>&lt;span class="m">49530&lt;/span>&lt;span class="w"> &lt;/span>stopped *&lt;span class="w"> &lt;/span>thread&lt;span class="w"> &lt;/span>&lt;span class="c1">#1: tid = 0x2b5010, 0x00007fff9218e10a libsystem_kernel.dylib`__semwait_signal + 10, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP&lt;/span> &lt;span class="w"> &lt;/span>frame&lt;span class="w"> &lt;/span>&lt;span class="c1">#0: 0x00007fff9218e10a libsystem_kernel.dylib`__semwait_signal + 10&lt;/span> libsystem_kernel.dylib&lt;span class="sb">`&lt;/span>__semwait_signal: -&amp;gt;&lt;span class="w"> &lt;/span>0x7fff9218e10a&lt;span class="w"> &lt;/span>&amp;lt;+10&amp;gt;:&lt;span class="w"> &lt;/span>jae&lt;span class="w"> &lt;/span>0x7fff9218e114&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&amp;lt;+20&amp;gt; &lt;span class="w"> &lt;/span>0x7fff9218e10c&lt;span class="w"> &lt;/span>&amp;lt;+12&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rax,&lt;span class="w"> &lt;/span>%rdi &lt;span class="w"> &lt;/span>0x7fff9218e10f&lt;span class="w"> &lt;/span>&amp;lt;+15&amp;gt;:&lt;span class="w"> &lt;/span>jmp&lt;span class="w"> &lt;/span>0x7fff921887f2&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>cerror &lt;span class="w"> &lt;/span>0x7fff9218e114&lt;span class="w"> &lt;/span>&amp;lt;+20&amp;gt;:&lt;span class="w"> &lt;/span>retq Executable&lt;span class="w"> &lt;/span>module&lt;span class="w"> &lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="w"> &lt;/span>to&lt;span class="w"> &lt;/span>&lt;span class="s2">"/Users/netrom/git/patching/live/./looper"&lt;/span>. Architecture&lt;span class="w"> &lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="w"> &lt;/span>to:&lt;span class="w"> &lt;/span>x86_64h-apple-macosx. &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>To get our bearings we backtrace, select the main &lt;code>looper&lt;/code> function and disassemble:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>bt *&lt;span class="w"> &lt;/span>thread&lt;span class="w"> &lt;/span>&lt;span class="c1">#1: tid = 0x2b5010, 0x00007fff9218e10a libsystem_kernel.dylib`__semwait_signal + 10, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP&lt;/span> &lt;span class="w"> &lt;/span>*&lt;span class="w"> &lt;/span>frame&lt;span class="w"> &lt;/span>&lt;span class="c1">#0: 0x00007fff9218e10a libsystem_kernel.dylib`__semwait_signal + 10&lt;/span> &lt;span class="w"> &lt;/span>frame&lt;span class="w"> &lt;/span>&lt;span class="c1">#1: 0x00007fff8d13ed0f libsystem_c.dylib`nanosleep + 199&lt;/span> &lt;span class="w"> &lt;/span>frame&lt;span class="w"> &lt;/span>&lt;span class="c1">#2: 0x00007fff8d13eb6f libsystem_c.dylib`sleep + 42&lt;/span> &lt;span class="w"> &lt;/span>frame&lt;span class="w"> &lt;/span>&lt;span class="c1">#3: 0x000000010aa3c171 looper`___lldb_unnamed_function1$$looper + 81&lt;/span> &lt;span class="w"> &lt;/span>frame&lt;span class="w"> &lt;/span>&lt;span class="c1">#4: 0x00007fff9a14a5ad libdyld.dylib`start + 1&lt;/span> &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>f&lt;span class="w"> &lt;/span>&lt;span class="m">3&lt;/span> frame&lt;span class="w"> &lt;/span>&lt;span class="c1">#3: 0x000000010aa3c171 looper`___lldb_unnamed_function1$$looper + 81&lt;/span> looper&lt;span class="sb">`&lt;/span>___lldb_unnamed_function1&lt;span class="nv">$$&lt;/span>looper: &lt;span class="w"> &lt;/span>0x10aa3c171&lt;span class="w"> &lt;/span>&amp;lt;+81&amp;gt;:&lt;span class="w"> &lt;/span>movl&lt;span class="w"> &lt;/span>%eax,&lt;span class="w"> &lt;/span>-0x14&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>0x10aa3c174&lt;span class="w"> &lt;/span>&amp;lt;+84&amp;gt;:&lt;span class="w"> &lt;/span>jmp&lt;span class="w"> &lt;/span>0x10aa3c136&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&amp;lt;+22&amp;gt; &lt;span class="w"> &lt;/span>0x10aa3c179&lt;span class="w"> &lt;/span>&amp;lt;+89&amp;gt;:&lt;span class="w"> &lt;/span>nop &lt;span class="w"> &lt;/span>0x10aa3c17a&lt;span class="w"> &lt;/span>&amp;lt;+90&amp;gt;:&lt;span class="w"> &lt;/span>nop &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>dis looper&lt;span class="sb">`&lt;/span>___lldb_unnamed_function1&lt;span class="nv">$$&lt;/span>looper: &lt;span class="w"> &lt;/span>0x10aa3c120&lt;span class="w"> &lt;/span>&amp;lt;+0&amp;gt;:&lt;span class="w"> &lt;/span>pushq&lt;span class="w"> &lt;/span>%rbp &lt;span class="w"> &lt;/span>0x10aa3c121&lt;span class="w"> &lt;/span>&amp;lt;+1&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rsp,&lt;span class="w"> &lt;/span>%rbp &lt;span class="w"> &lt;/span>0x10aa3c124&lt;span class="w"> &lt;/span>&amp;lt;+4&amp;gt;:&lt;span class="w"> &lt;/span>subq&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x20,&lt;span class="w"> &lt;/span>%rsp &lt;span class="w"> &lt;/span>0x10aa3c128&lt;span class="w"> &lt;/span>&amp;lt;+8&amp;gt;:&lt;span class="w"> &lt;/span>movl&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x0,&lt;span class="w"> &lt;/span>-0x4&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>0x10aa3c12f&lt;span class="w"> &lt;/span>&amp;lt;+15&amp;gt;:&lt;span class="w"> &lt;/span>movl&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x14,&lt;span class="w"> &lt;/span>-0x8&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>0x10aa3c136&lt;span class="w"> &lt;/span>&amp;lt;+22&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>0xec3&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rdi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>void&lt;span class="w"> &lt;/span>*&lt;span class="o">)&lt;/span>0x00007fff78ba32f8:&lt;span class="w"> &lt;/span>std::__1::cout &lt;span class="w"> &lt;/span>0x10aa3c13d&lt;span class="w"> &lt;/span>&amp;lt;+29&amp;gt;:&lt;span class="w"> &lt;/span>leaq&lt;span class="w"> &lt;/span>0xe2c&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rsi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">"score = "&lt;/span> &lt;span class="w"> &lt;/span>0x10aa3c144&lt;span class="w"> &lt;/span>&amp;lt;+36&amp;gt;:&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x10aa3c180&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>___lldb_unnamed_function2&lt;span class="nv">$$&lt;/span>looper &lt;span class="w"> &lt;/span>0x10aa3c149&lt;span class="w"> &lt;/span>&amp;lt;+41&amp;gt;:&lt;span class="w"> &lt;/span>movl&lt;span class="w"> &lt;/span>-0x8&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%esi &lt;span class="w"> &lt;/span>0x10aa3c14c&lt;span class="w"> &lt;/span>&amp;lt;+44&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rax,&lt;span class="w"> &lt;/span>%rdi &lt;span class="w"> &lt;/span>0x10aa3c14f&lt;span class="w"> &lt;/span>&amp;lt;+47&amp;gt;:&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x10aa3cd80&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>symbol&lt;span class="w"> &lt;/span>stub&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>:&lt;span class="w"> &lt;/span>std::__1::basic_ostream&amp;lt;char,&lt;span class="w"> &lt;/span>std::__1::char_traits&amp;lt;char&amp;gt;&lt;span class="w"> &lt;/span>&amp;gt;::operator&amp;lt;&amp;lt;&lt;span class="o">(&lt;/span>int&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>0x10aa3c154&lt;span class="w"> &lt;/span>&amp;lt;+52&amp;gt;:&lt;span class="w"> &lt;/span>leaq&lt;span class="w"> &lt;/span>0xe1e&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rsi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">"'\n'"&lt;/span> &lt;span class="w"> &lt;/span>0x10aa3c15b&lt;span class="w"> &lt;/span>&amp;lt;+59&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rax,&lt;span class="w"> &lt;/span>%rdi &lt;span class="w"> &lt;/span>0x10aa3c15e&lt;span class="w"> &lt;/span>&amp;lt;+62&amp;gt;:&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x10aa3c180&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>___lldb_unnamed_function2&lt;span class="nv">$$&lt;/span>looper &lt;span class="w"> &lt;/span>0x10aa3c163&lt;span class="w"> &lt;/span>&amp;lt;+67&amp;gt;:&lt;span class="w"> &lt;/span>movl&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x1,&lt;span class="w"> &lt;/span>%edi &lt;span class="w"> &lt;/span>0x10aa3c168&lt;span class="w"> &lt;/span>&amp;lt;+72&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rax,&lt;span class="w"> &lt;/span>-0x10&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>0x10aa3c16c&lt;span class="w"> &lt;/span>&amp;lt;+76&amp;gt;:&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x10aa3cdb6&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>symbol&lt;span class="w"> &lt;/span>stub&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>:&lt;span class="w"> &lt;/span>sleep &lt;span class="w"> &lt;/span>0x10aa3c171&lt;span class="w"> &lt;/span>&amp;lt;+81&amp;gt;:&lt;span class="w"> &lt;/span>movl&lt;span class="w"> &lt;/span>%eax,&lt;span class="w"> &lt;/span>-0x14&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>0x10aa3c174&lt;span class="w"> &lt;/span>&amp;lt;+84&amp;gt;:&lt;span class="w"> &lt;/span>jmp&lt;span class="w"> &lt;/span>0x10aa3c136&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&amp;lt;+22&amp;gt; &lt;/code>&lt;/pre>&lt;/div> &lt;p>Since the program is already doing loops we have to break somewhere inside it, and it makes most sense to do it right where it reads the score value:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>dis&lt;span class="w"> &lt;/span>-b&lt;span class="w"> &lt;/span>-c&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="w"> &lt;/span>-s&lt;span class="w"> &lt;/span>0x10aa3c149 looper&lt;span class="sb">`&lt;/span>___lldb_unnamed_function1&lt;span class="nv">$$&lt;/span>looper: &lt;span class="w"> &lt;/span>0x10aa3c149&lt;span class="w"> &lt;/span>&amp;lt;+41&amp;gt;:&lt;span class="w"> &lt;/span>8b&lt;span class="w"> &lt;/span>&lt;span class="m">75&lt;/span>&lt;span class="w"> &lt;/span>f8&lt;span class="w"> &lt;/span>movl&lt;span class="w"> &lt;/span>-0x8&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%esi &lt;/code>&lt;/pre>&lt;/div> &lt;p>So we set a break point at &lt;code>0x10aa3c149&lt;/code> and reach it:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>b&lt;span class="w"> &lt;/span>0x10aa3c149 Breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>:&lt;span class="w"> &lt;/span>&lt;span class="nv">where&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>looper&lt;span class="sb">`&lt;/span>___lldb_unnamed_function1&lt;span class="nv">$$&lt;/span>looper&lt;span class="w"> &lt;/span>+&lt;span class="w"> &lt;/span>&lt;span class="m">41&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="nv">address&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>0x000000010aa3c149 &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>c Process&lt;span class="w"> &lt;/span>&lt;span class="m">49530&lt;/span>&lt;span class="w"> &lt;/span>resuming Process&lt;span class="w"> &lt;/span>&lt;span class="m">49530&lt;/span>&lt;span class="w"> &lt;/span>stopped *&lt;span class="w"> &lt;/span>thread&lt;span class="w"> &lt;/span>&lt;span class="c1">#1: tid = 0x2b5010, 0x000000010aa3c149 looper`___lldb_unnamed_function1$$looper + 41, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1&lt;/span> &lt;span class="w"> &lt;/span>frame&lt;span class="w"> &lt;/span>&lt;span class="c1">#0: 0x000000010aa3c149 looper`___lldb_unnamed_function1$$looper + 41&lt;/span> looper&lt;span class="sb">`&lt;/span>___lldb_unnamed_function1&lt;span class="nv">$$&lt;/span>looper: -&amp;gt;&lt;span class="w"> &lt;/span>0x10aa3c149&lt;span class="w"> &lt;/span>&amp;lt;+41&amp;gt;:&lt;span class="w"> &lt;/span>movl&lt;span class="w"> &lt;/span>-0x8&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%esi &lt;span class="w"> &lt;/span>0x10aa3c14c&lt;span class="w"> &lt;/span>&amp;lt;+44&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rax,&lt;span class="w"> &lt;/span>%rdi &lt;span class="w"> &lt;/span>0x10aa3c14f&lt;span class="w"> &lt;/span>&amp;lt;+47&amp;gt;:&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x10aa3cd80&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>symbol&lt;span class="w"> &lt;/span>stub&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>:&lt;span class="w"> &lt;/span>std::__1::basic_ostream&amp;lt;char,&lt;span class="w"> &lt;/span>std::__1::char_traits&amp;lt;char&amp;gt;&lt;span class="w"> &lt;/span>&amp;gt;::operator&amp;lt;&amp;lt;&lt;span class="o">(&lt;/span>int&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>0x10aa3c154&lt;span class="w"> &lt;/span>&amp;lt;+52&amp;gt;:&lt;span class="w"> &lt;/span>leaq&lt;span class="w"> &lt;/span>0xe1e&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rsi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">"'\n'"&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>The last thing to do is change the value and detach from the process:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>p&lt;span class="w"> &lt;/span>*&lt;span class="o">(&lt;/span>int*&lt;span class="o">)(&lt;/span>&lt;span class="sb">`&lt;/span>&lt;span class="nv">$rbp&lt;/span>&lt;span class="sb">`&lt;/span>-8&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">42&lt;/span> &lt;span class="o">(&lt;/span>int&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">$1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">42&lt;/span> &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>detach Process&lt;span class="w"> &lt;/span>&lt;span class="m">49530&lt;/span>&lt;span class="w"> &lt;/span>detached &lt;/code>&lt;/pre>&lt;/div> &lt;p>Finally, in the first terminal, it continually uses the changed value:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>... &lt;span class="nv">score&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">20&lt;/span> &lt;span class="nv">score&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">42&lt;/span> &lt;span class="nv">score&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">42&lt;/span> &lt;span class="nv">score&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">42&lt;/span> ... &lt;/code>&lt;/pre>&lt;/div> &lt;p>That concludes data manipulation of live processes.&lt;/p></content><category term="Patching"/><category term="patching"/><category term="x86-64"/><category term="cpp"/><category term="python"/><category term="lldb"/><category term="disassembling"/></entry><entry><title>Patching Binaries: Jumping The Fence</title><link href="https://www.mortens.dev/blog/patching-binaries-jumping-the-fence/" rel="alternate"/><published>2016-09-06T21:43:55+02:00</published><updated>2016-09-06T21:43:55+02:00</updated><author><name>Morten</name></author><id>tag:www.mortens.dev,2016-09-06:/blog/patching-binaries-jumping-the-fence/</id><summary type="html">&lt;p>How to patch binaries to jump the&amp;nbsp;fence&lt;/p></summary><content type="html">&lt;p>&lt;em>Patching Binaries&lt;/em> is a series of articles about how to extract information and modify program behavior. It focuses on the Mac &lt;a href="https://en.wikipedia.org/wiki/Mach-O">Mach-O&lt;/a> executable format for the &lt;a href="https://en.wikipedia.org/wiki/X86-64">x86-64&lt;/a> architecture, but the techniques are similar for other formats.&lt;/p> &lt;p>Before proceeding it is recommended reading the &lt;a href="https://www.mortens.dev/blog/patching-binaries-strings/">first part&lt;/a> about the fundamentals of finding and changing constant strings in binaries.&lt;/p> &lt;p>&lt;em>The files used in this article can be found &lt;a href="https://github.com/netromdk/patching/tree/master/jumps/">here&lt;/a>.&lt;/em>&lt;/p> &lt;p>An approach to change the behavior of a program is to jump or bypass instructions. Or in other words: &lt;em>jumping the fence!&lt;/em>&lt;/p> &lt;p>Compile and strip example program “verify.cc” as “verify” and run it:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>./verify Serial&lt;span class="w"> &lt;/span>number:&lt;span class="w"> &lt;/span>&lt;span class="m">83&lt;/span> Incorrect! %&lt;span class="w"> &lt;/span>./verify Serial&lt;span class="w"> &lt;/span>number:&lt;span class="w"> &lt;/span>&lt;span class="m">90&lt;/span> Correct! &lt;/code>&lt;/pre>&lt;/div> &lt;p>If we disregard knowing from the source code how the numbers are verified, we would like to somehow bypass the check so that all inputs are deemed correct. There are numerous ways of doing this but the easiest is putting &lt;em>&lt;span class="caps">NOP&lt;/span>&lt;/em> (No Operation - opcode &lt;code>0x90&lt;/code>) instructions at tactical places in the program. They are a means of masking out functionality because they simply do nothing.&lt;/p> &lt;p>First we need to find out where to place the NOPs. And as a preliminary deviation we will look at how to determine a program’s entry point address; where the first program instruction resides. When dealing with stripped executables we can’t break at &lt;code>main&lt;/code> anymore.&lt;/p> &lt;p>In Mach-O binaries the program instructions are located in section &lt;code>__text&lt;/code> of segment &lt;code>__TEXT&lt;/code>:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>otool&lt;span class="w"> &lt;/span>-s&lt;span class="w"> &lt;/span>__TEXT&lt;span class="w"> &lt;/span>__text&lt;span class="w"> &lt;/span>verify&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="w"> &lt;/span>head&lt;span class="w"> &lt;/span>-n&lt;span class="w"> &lt;/span>&lt;span class="m">3&lt;/span> verify: Contents&lt;span class="w"> &lt;/span>of&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>__TEXT,__text&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>section 00000001000010c0&lt;span class="w"> &lt;/span>&lt;span class="m">55&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">48&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">89&lt;/span>&lt;span class="w"> &lt;/span>e5&lt;span class="w"> &lt;/span>&lt;span class="m">48&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">83&lt;/span>&lt;span class="w"> &lt;/span>ec&lt;span class="w"> &lt;/span>&lt;span class="m">30&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">48&lt;/span>&lt;span class="w"> &lt;/span>8b&lt;span class="w"> &lt;/span>3d&lt;span class="w"> &lt;/span>&lt;span class="m">39&lt;/span>&lt;span class="w"> &lt;/span>0f&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">48&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>To easily retrieve the entry point and start &lt;a href="http://lldb.llvm.org">&lt;span class="caps">LLDB&lt;/span>&lt;/a> with a break point on that address, take a look at “lldb_entrypoint.sh”:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="ch">#!/bin/sh&lt;/span> &lt;span class="nv">ADDR&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="sb">`&lt;/span>otool&lt;span class="w"> &lt;/span>-s&lt;span class="w"> &lt;/span>__TEXT&lt;span class="w"> &lt;/span>__text&lt;span class="w"> &lt;/span>&lt;span class="nv">$1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="w"> &lt;/span>head&lt;span class="w"> &lt;/span>-n&lt;span class="w"> &lt;/span>&lt;span class="m">3&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="w"> &lt;/span>tail&lt;span class="w"> &lt;/span>-n&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="w"> &lt;/span>awk&lt;span class="w"> &lt;/span>&lt;span class="s1">'{print $1;}'&lt;/span>&lt;span class="sb">`&lt;/span> &lt;span class="nb">echo&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">"b 0x&lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="nv">ADDR&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">"&lt;/span>&lt;span class="w"> &lt;/span>&amp;gt;&lt;span class="w"> &lt;/span>/tmp/.lldbcmds lldb&lt;span class="w"> &lt;/span>-s&lt;span class="w"> &lt;/span>/tmp/.lldbcmds&lt;span class="w"> &lt;/span>&lt;span class="nv">$1&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>With that let’s start up the debugger with our program and reach the break point:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>./lldb_entrypoint.sh&lt;span class="w"> &lt;/span>verify &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>target&lt;span class="w"> &lt;/span>create&lt;span class="w"> &lt;/span>&lt;span class="s2">"verify"&lt;/span> Current&lt;span class="w"> &lt;/span>executable&lt;span class="w"> &lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="w"> &lt;/span>to&lt;span class="w"> &lt;/span>&lt;span class="s1">'verify'&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>x86_64&lt;span class="o">)&lt;/span>. &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">command&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">source&lt;/span>&lt;span class="w"> &lt;/span>-s&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">'/tmp/.lldbcmds'&lt;/span> Executing&lt;span class="w"> &lt;/span>commands&lt;span class="w"> &lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">'/tmp/.lldbcmds'&lt;/span>. &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>b&lt;span class="w"> &lt;/span>0x00000001000010c0 Breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>:&lt;span class="w"> &lt;/span>&lt;span class="nv">address&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>0x00000001000010c0 &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>r Process&lt;span class="w"> &lt;/span>&lt;span class="m">88913&lt;/span>&lt;span class="w"> &lt;/span>launched:&lt;span class="w"> &lt;/span>&lt;span class="s1">'/Users/netrom/git/patching/jumps/verify'&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>x86_64&lt;span class="o">)&lt;/span> Process&lt;span class="w"> &lt;/span>&lt;span class="m">88913&lt;/span>&lt;span class="w"> &lt;/span>stopped *&lt;span class="w"> &lt;/span>thread&lt;span class="w"> &lt;/span>&lt;span class="c1">#1: tid = 0x233953, 0x00000001000010c0 verify`___lldb_unnamed_symbol1$$verify, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1&lt;/span> &lt;span class="w"> &lt;/span>frame&lt;span class="w"> &lt;/span>&lt;span class="c1">#0: 0x00000001000010c0 verify`___lldb_unnamed_symbol1$$verify&lt;/span> verify&lt;span class="sb">`&lt;/span>___lldb_unnamed_symbol1&lt;span class="nv">$$&lt;/span>verify: -&amp;gt;&lt;span class="w"> &lt;/span>0x1000010c0&lt;span class="w"> &lt;/span>&amp;lt;+0&amp;gt;:&lt;span class="w"> &lt;/span>pushq&lt;span class="w"> &lt;/span>%rbp &lt;span class="w"> &lt;/span>0x1000010c1&lt;span class="w"> &lt;/span>&amp;lt;+1&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rsp,&lt;span class="w"> &lt;/span>%rbp &lt;span class="w"> &lt;/span>0x1000010c4&lt;span class="w"> &lt;/span>&amp;lt;+4&amp;gt;:&lt;span class="w"> &lt;/span>subq&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x30,&lt;span class="w"> &lt;/span>%rsp &lt;span class="w"> &lt;/span>0x1000010c8&lt;span class="w"> &lt;/span>&amp;lt;+8&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>0xf39&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rdi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>void&lt;span class="w"> &lt;/span>*&lt;span class="o">)&lt;/span>0x00007fff78ba32f8:&lt;span class="w"> &lt;/span>std::__1::cout &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>The next step is to disassemble to get an overview:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>dis verify&lt;span class="sb">`&lt;/span>___lldb_unnamed_symbol1&lt;span class="nv">$$&lt;/span>verify: -&amp;gt;&lt;span class="w"> &lt;/span>0x1000010c0&lt;span class="w"> &lt;/span>&amp;lt;+0&amp;gt;:&lt;span class="w"> &lt;/span>pushq&lt;span class="w"> &lt;/span>%rbp &lt;span class="w"> &lt;/span>0x1000010c1&lt;span class="w"> &lt;/span>&amp;lt;+1&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rsp,&lt;span class="w"> &lt;/span>%rbp &lt;span class="w"> &lt;/span>0x1000010c4&lt;span class="w"> &lt;/span>&amp;lt;+4&amp;gt;:&lt;span class="w"> &lt;/span>subq&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x30,&lt;span class="w"> &lt;/span>%rsp &lt;span class="w"> &lt;/span>0x1000010c8&lt;span class="w"> &lt;/span>&amp;lt;+8&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>0xf39&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rdi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>void&lt;span class="w"> &lt;/span>*&lt;span class="o">)&lt;/span>0x00007fff78ba32f8:&lt;span class="w"> &lt;/span>std::__1::cout &lt;span class="w"> &lt;/span>0x1000010cf&lt;span class="w"> &lt;/span>&amp;lt;+15&amp;gt;:&lt;span class="w"> &lt;/span>leaq&lt;span class="w"> &lt;/span>0xe86&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rsi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">"Serial number: "&lt;/span> &lt;span class="w"> &lt;/span>0x1000010d6&lt;span class="w"> &lt;/span>&amp;lt;+22&amp;gt;:&lt;span class="w"> &lt;/span>movl&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x0,&lt;span class="w"> &lt;/span>-0x4&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>0x1000010dd&lt;span class="w"> &lt;/span>&amp;lt;+29&amp;gt;:&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x100001150&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>___lldb_unnamed_symbol2&lt;span class="nv">$$&lt;/span>verify &lt;span class="w"> &lt;/span>0x1000010e2&lt;span class="w"> &lt;/span>&amp;lt;+34&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>0xf17&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rdi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>void&lt;span class="w"> &lt;/span>*&lt;span class="o">)&lt;/span>0x00007fff78ba3250:&lt;span class="w"> &lt;/span>std::__1::cin &lt;span class="w"> &lt;/span>0x1000010e9&lt;span class="w"> &lt;/span>&amp;lt;+41&amp;gt;:&lt;span class="w"> &lt;/span>leaq&lt;span class="w"> &lt;/span>-0x8&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rsi &lt;span class="w"> &lt;/span>0x1000010ed&lt;span class="w"> &lt;/span>&amp;lt;+45&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rax,&lt;span class="w"> &lt;/span>-0x10&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>0x1000010f1&lt;span class="w"> &lt;/span>&amp;lt;+49&amp;gt;:&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x100001d74&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>symbol&lt;span class="w"> &lt;/span>stub&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>:&lt;span class="w"> &lt;/span>std::__1::basic_istream&amp;lt;char,&lt;span class="w"> &lt;/span>std::__1::char_traits&amp;lt;char&amp;gt;&lt;span class="w"> &lt;/span>&amp;gt;::operator&amp;gt;&amp;gt;&lt;span class="o">(&lt;/span>int&lt;span class="p">&amp;amp;&lt;/span>&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>0x1000010f6&lt;span class="w"> &lt;/span>&amp;lt;+54&amp;gt;:&lt;span class="w"> &lt;/span>movl&lt;span class="w"> &lt;/span>-0x8&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%edi &lt;span class="w"> &lt;/span>0x1000010f9&lt;span class="w"> &lt;/span>&amp;lt;+57&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rax,&lt;span class="w"> &lt;/span>-0x18&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>0x1000010fd&lt;span class="w"> &lt;/span>&amp;lt;+61&amp;gt;:&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x1000011a0&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>___lldb_unnamed_symbol3&lt;span class="nv">$$&lt;/span>verify &lt;span class="w"> &lt;/span>0x100001102&lt;span class="w"> &lt;/span>&amp;lt;+66&amp;gt;:&lt;span class="w"> &lt;/span>testb&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x1,&lt;span class="w"> &lt;/span>%al &lt;span class="w"> &lt;/span>0x100001104&lt;span class="w"> &lt;/span>&amp;lt;+68&amp;gt;:&lt;span class="w"> &lt;/span>jne&lt;span class="w"> &lt;/span>0x10000110f&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&amp;lt;+79&amp;gt; &lt;span class="w"> &lt;/span>0x10000110a&lt;span class="w"> &lt;/span>&amp;lt;+74&amp;gt;:&lt;span class="w"> &lt;/span>jmp&lt;span class="w"> &lt;/span>0x10000112b&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&amp;lt;+107&amp;gt; &lt;span class="w"> &lt;/span>0x10000110f&lt;span class="w"> &lt;/span>&amp;lt;+79&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>0xef2&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rdi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>void&lt;span class="w"> &lt;/span>*&lt;span class="o">)&lt;/span>0x00007fff78ba32f8:&lt;span class="w"> &lt;/span>std::__1::cout &lt;span class="w"> &lt;/span>0x100001116&lt;span class="w"> &lt;/span>&amp;lt;+86&amp;gt;:&lt;span class="w"> &lt;/span>leaq&lt;span class="w"> &lt;/span>0xe4f&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rsi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">"Correct!\n"&lt;/span> &lt;span class="w"> &lt;/span>0x10000111d&lt;span class="w"> &lt;/span>&amp;lt;+93&amp;gt;:&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x100001150&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>___lldb_unnamed_symbol2&lt;span class="nv">$$&lt;/span>verify &lt;span class="w"> &lt;/span>0x100001122&lt;span class="w"> &lt;/span>&amp;lt;+98&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rax,&lt;span class="w"> &lt;/span>-0x20&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>0x100001126&lt;span class="w"> &lt;/span>&amp;lt;+102&amp;gt;:&lt;span class="w"> &lt;/span>jmp&lt;span class="w"> &lt;/span>0x100001142&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&amp;lt;+130&amp;gt; &lt;span class="w"> &lt;/span>0x10000112b&lt;span class="w"> &lt;/span>&amp;lt;+107&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>0xed6&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rdi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>void&lt;span class="w"> &lt;/span>*&lt;span class="o">)&lt;/span>0x00007fff78ba32f8:&lt;span class="w"> &lt;/span>std::__1::cout &lt;span class="w"> &lt;/span>0x100001132&lt;span class="w"> &lt;/span>&amp;lt;+114&amp;gt;:&lt;span class="w"> &lt;/span>leaq&lt;span class="w"> &lt;/span>0xe3d&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rsi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">"Incorrect!\n"&lt;/span> &lt;span class="w"> &lt;/span>0x100001139&lt;span class="w"> &lt;/span>&amp;lt;+121&amp;gt;:&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x100001150&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>___lldb_unnamed_symbol2&lt;span class="nv">$$&lt;/span>verify &lt;span class="w"> &lt;/span>0x10000113e&lt;span class="w"> &lt;/span>&amp;lt;+126&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rax,&lt;span class="w"> &lt;/span>-0x28&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>0x100001142&lt;span class="w"> &lt;/span>&amp;lt;+130&amp;gt;:&lt;span class="w"> &lt;/span>xorl&lt;span class="w"> &lt;/span>%eax,&lt;span class="w"> &lt;/span>%eax &lt;span class="w"> &lt;/span>0x100001144&lt;span class="w"> &lt;/span>&amp;lt;+132&amp;gt;:&lt;span class="w"> &lt;/span>addq&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x30,&lt;span class="w"> &lt;/span>%rsp &lt;span class="w"> &lt;/span>0x100001148&lt;span class="w"> &lt;/span>&amp;lt;+136&amp;gt;:&lt;span class="w"> &lt;/span>popq&lt;span class="w"> &lt;/span>%rbp &lt;span class="w"> &lt;/span>0x100001149&lt;span class="w"> &lt;/span>&amp;lt;+137&amp;gt;:&lt;span class="w"> &lt;/span>retq &lt;span class="w"> &lt;/span>0x10000114a&lt;span class="w"> &lt;/span>&amp;lt;+138&amp;gt;:&lt;span class="w"> &lt;/span>nopw&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>%rax,%rax&lt;span class="o">)&lt;/span> &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>The &lt;code>verify&lt;/code> function is called at &lt;code>0x1000010fd&lt;/code> if afterwards it jumps to &lt;code>0x10000110f&lt;/code> then the number is verified correctly, and if not it jumps to &lt;code>0x10000112b&lt;/code>. We still want it to ask for a number but completely skip the verification. The crude way is to insert NOPs from &lt;code>0x1000010f6&lt;/code> to &lt;code>0x10000110f&lt;/code> because it will arrive straight at the part where it prints &lt;code>"Correct!"&lt;/code>. That means 25 NOPs.&lt;/p> &lt;p>I created the “nop.py” script to insert NOPs:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>./nop.py&lt;span class="w"> &lt;/span>verify&lt;span class="w"> &lt;/span>0x10f6&lt;span class="w"> &lt;/span>&lt;span class="m">25&lt;/span> Patching&lt;span class="w"> &lt;/span>&lt;span class="s2">"verify"&lt;/span>&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>offset&lt;span class="w"> &lt;/span>&lt;span class="m">4342&lt;/span>&lt;span class="w"> &lt;/span>with&lt;span class="w"> &lt;/span>&lt;span class="m">25&lt;/span>&lt;span class="w"> &lt;/span>NOPs Read&lt;span class="w"> &lt;/span>&lt;span class="m">14416&lt;/span>&lt;span class="w"> &lt;/span>bytes Changing&lt;span class="w"> &lt;/span>values&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>&lt;span class="m">4342&lt;/span>&lt;span class="w"> &lt;/span>to&lt;span class="w"> &lt;/span>&lt;span class="m">4367&lt;/span> Writing&lt;span class="w"> &lt;/span>new&lt;span class="w"> &lt;/span>data %&lt;span class="w"> &lt;/span>./verify Serial&lt;span class="w"> &lt;/span>number:&lt;span class="w"> &lt;/span>&lt;span class="m">83&lt;/span> Correct! &lt;/code>&lt;/pre>&lt;/div> &lt;p>&lt;em>Thus 83 is now deemed correct!&lt;/em>&lt;/p> &lt;p>Let’s take a look at the actual contents of the binary now:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>dis verify&lt;span class="sb">`&lt;/span>___lldb_unnamed_symbol1&lt;span class="nv">$$&lt;/span>verify: -&amp;gt;&lt;span class="w"> &lt;/span>0x1000010c0&lt;span class="w"> &lt;/span>&amp;lt;+0&amp;gt;:&lt;span class="w"> &lt;/span>pushq&lt;span class="w"> &lt;/span>%rbp &lt;span class="w"> &lt;/span>0x1000010c1&lt;span class="w"> &lt;/span>&amp;lt;+1&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rsp,&lt;span class="w"> &lt;/span>%rbp &lt;span class="w"> &lt;/span>0x1000010c4&lt;span class="w"> &lt;/span>&amp;lt;+4&amp;gt;:&lt;span class="w"> &lt;/span>subq&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x30,&lt;span class="w"> &lt;/span>%rsp &lt;span class="w"> &lt;/span>0x1000010c8&lt;span class="w"> &lt;/span>&amp;lt;+8&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>0xf39&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rdi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>void&lt;span class="w"> &lt;/span>*&lt;span class="o">)&lt;/span>0x00007fff78ba32f8:&lt;span class="w"> &lt;/span>std::__1::cout &lt;span class="w"> &lt;/span>0x1000010cf&lt;span class="w"> &lt;/span>&amp;lt;+15&amp;gt;:&lt;span class="w"> &lt;/span>leaq&lt;span class="w"> &lt;/span>0xe86&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rsi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">"Serial number: "&lt;/span> &lt;span class="w"> &lt;/span>0x1000010d6&lt;span class="w"> &lt;/span>&amp;lt;+22&amp;gt;:&lt;span class="w"> &lt;/span>movl&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x0,&lt;span class="w"> &lt;/span>-0x4&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>0x1000010dd&lt;span class="w"> &lt;/span>&amp;lt;+29&amp;gt;:&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x100001150&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>___lldb_unnamed_symbol2&lt;span class="nv">$$&lt;/span>verify &lt;span class="w"> &lt;/span>0x1000010e2&lt;span class="w"> &lt;/span>&amp;lt;+34&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>0xf17&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rdi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>void&lt;span class="w"> &lt;/span>*&lt;span class="o">)&lt;/span>0x00007fff78ba3250:&lt;span class="w"> &lt;/span>std::__1::cin &lt;span class="w"> &lt;/span>0x1000010e9&lt;span class="w"> &lt;/span>&amp;lt;+41&amp;gt;:&lt;span class="w"> &lt;/span>leaq&lt;span class="w"> &lt;/span>-0x8&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rsi &lt;span class="w"> &lt;/span>0x1000010ed&lt;span class="w"> &lt;/span>&amp;lt;+45&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rax,&lt;span class="w"> &lt;/span>-0x10&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>0x1000010f1&lt;span class="w"> &lt;/span>&amp;lt;+49&amp;gt;:&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x100001d74&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>symbol&lt;span class="w"> &lt;/span>stub&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>:&lt;span class="w"> &lt;/span>std::__1::basic_istream&amp;lt;char,&lt;span class="w"> &lt;/span>std::__1::char_traits&amp;lt;char&amp;gt;&lt;span class="w"> &lt;/span>&amp;gt;::operator&amp;gt;&amp;gt;&lt;span class="o">(&lt;/span>int&lt;span class="p">&amp;amp;&lt;/span>&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>0x1000010f6&lt;span class="w"> &lt;/span>&amp;lt;+54&amp;gt;:&lt;span class="w"> &lt;/span>nop &lt;span class="w"> &lt;/span>0x1000010f7&lt;span class="w"> &lt;/span>&amp;lt;+55&amp;gt;:&lt;span class="w"> &lt;/span>nop &lt;span class="w"> &lt;/span>0x1000010f8&lt;span class="w"> &lt;/span>&amp;lt;+56&amp;gt;:&lt;span class="w"> &lt;/span>nop &lt;span class="w"> &lt;/span>... &lt;span class="w"> &lt;/span>0x10000110c&lt;span class="w"> &lt;/span>&amp;lt;+76&amp;gt;:&lt;span class="w"> &lt;/span>nop &lt;span class="w"> &lt;/span>0x10000110d&lt;span class="w"> &lt;/span>&amp;lt;+77&amp;gt;:&lt;span class="w"> &lt;/span>nop &lt;span class="w"> &lt;/span>0x10000110e&lt;span class="w"> &lt;/span>&amp;lt;+78&amp;gt;:&lt;span class="w"> &lt;/span>nop &lt;span class="w"> &lt;/span>0x10000110f&lt;span class="w"> &lt;/span>&amp;lt;+79&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>0xef2&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rdi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>void&lt;span class="w"> &lt;/span>*&lt;span class="o">)&lt;/span>0x00007fff78ba32f8:&lt;span class="w"> &lt;/span>std::__1::cout &lt;span class="w"> &lt;/span>0x100001116&lt;span class="w"> &lt;/span>&amp;lt;+86&amp;gt;:&lt;span class="w"> &lt;/span>leaq&lt;span class="w"> &lt;/span>0xe4f&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rsi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">"Correct!\n"&lt;/span> &lt;span class="w"> &lt;/span>0x10000111d&lt;span class="w"> &lt;/span>&amp;lt;+93&amp;gt;:&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x100001150&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>___lldb_unnamed_symbol2&lt;span class="nv">$$&lt;/span>verify &lt;span class="w"> &lt;/span>0x100001122&lt;span class="w"> &lt;/span>&amp;lt;+98&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rax,&lt;span class="w"> &lt;/span>-0x20&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>0x100001126&lt;span class="w"> &lt;/span>&amp;lt;+102&amp;gt;:&lt;span class="w"> &lt;/span>jmp&lt;span class="w"> &lt;/span>0x100001142&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&amp;lt;+130&amp;gt; &lt;span class="w"> &lt;/span>0x10000112b&lt;span class="w"> &lt;/span>&amp;lt;+107&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>0xed6&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rdi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>void&lt;span class="w"> &lt;/span>*&lt;span class="o">)&lt;/span>0x00007fff78ba32f8:&lt;span class="w"> &lt;/span>std::__1::cout &lt;span class="w"> &lt;/span>0x100001132&lt;span class="w"> &lt;/span>&amp;lt;+114&amp;gt;:&lt;span class="w"> &lt;/span>leaq&lt;span class="w"> &lt;/span>0xe3d&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rsi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">"Incorrect!\n"&lt;/span> &lt;span class="w"> &lt;/span>0x100001139&lt;span class="w"> &lt;/span>&amp;lt;+121&amp;gt;:&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x100001150&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>___lldb_unnamed_symbol2&lt;span class="nv">$$&lt;/span>verify &lt;span class="w"> &lt;/span>0x10000113e&lt;span class="w"> &lt;/span>&amp;lt;+126&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rax,&lt;span class="w"> &lt;/span>-0x28&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>0x100001142&lt;span class="w"> &lt;/span>&amp;lt;+130&amp;gt;:&lt;span class="w"> &lt;/span>xorl&lt;span class="w"> &lt;/span>%eax,&lt;span class="w"> &lt;/span>%eax &lt;span class="w"> &lt;/span>0x100001144&lt;span class="w"> &lt;/span>&amp;lt;+132&amp;gt;:&lt;span class="w"> &lt;/span>addq&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x30,&lt;span class="w"> &lt;/span>%rsp &lt;span class="w"> &lt;/span>0x100001148&lt;span class="w"> &lt;/span>&amp;lt;+136&amp;gt;:&lt;span class="w"> &lt;/span>popq&lt;span class="w"> &lt;/span>%rbp &lt;span class="w"> &lt;/span>0x100001149&lt;span class="w"> &lt;/span>&amp;lt;+137&amp;gt;:&lt;span class="w"> &lt;/span>retq &lt;span class="w"> &lt;/span>0x10000114a&lt;span class="w"> &lt;/span>&amp;lt;+138&amp;gt;:&lt;span class="w"> &lt;/span>nopw&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>%rax,%rax&lt;span class="o">)&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>The 25 NOPs are easily spotted.&lt;/p> &lt;p>Recompile and strip the “verify” program again to get rid of the NOPs.&lt;/p> &lt;p>Another approach is to insert a jump instruction that takes us directly to &lt;code>0x10000110f&lt;/code>. We want to insert the jump at &lt;code>0x1000010f6&lt;/code> where we have 3 bytes of room to change, so a relative jump would count from the next instruction (after inserting) to &lt;code>0x10000110f&lt;/code>. Since we are within a one-byte short jump distance of +/-128 we can use a &lt;code>JMP rel8&lt;/code> with jump instruction opcode &lt;code>0xeb&lt;/code> (for other jump instructions take a look &lt;a href="http://x86.renejeschke.de/html/file_module_x86_id_147.html">here&lt;/a>). This leaves one byte dangling which we will fill with a &lt;span class="caps">NOP&lt;/span>. However, this effectively will change the address of the next instruction after our &lt;span class="caps">JMP&lt;/span> to be &lt;code>0x1000010f8&lt;/code>. The distance from that to &lt;code>0x10000110f&lt;/code> is &lt;code>0x17=23&lt;/code>, which means we will insert the bytes &lt;code>eb 17 90&lt;/code> at &lt;code>0x1000010f6&lt;/code>.&lt;/p> &lt;p>I wrote another script, “patch_bytes.py”, that will allow us to insert those bytes:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>./patch_bytes.py&lt;span class="w"> &lt;/span>verify&lt;span class="w"> &lt;/span>0x10f6&lt;span class="w"> &lt;/span>0xeb&lt;span class="w"> &lt;/span>0x17&lt;span class="w"> &lt;/span>0x90 Patching&lt;span class="w"> &lt;/span>&lt;span class="s2">"verify"&lt;/span>&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>offset&lt;span class="w"> &lt;/span>&lt;span class="m">4342&lt;/span>&lt;span class="w"> &lt;/span>with:&lt;span class="w"> &lt;/span>&lt;span class="o">[&lt;/span>&lt;span class="m">235&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="m">23&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="m">144&lt;/span>&lt;span class="o">]&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="m">3&lt;/span>&lt;span class="w"> &lt;/span>bytes&lt;span class="o">)&lt;/span> Read&lt;span class="w"> &lt;/span>&lt;span class="m">14416&lt;/span>&lt;span class="w"> &lt;/span>bytes Changing&lt;span class="w"> &lt;/span>values&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>&lt;span class="m">4342&lt;/span>&lt;span class="w"> &lt;/span>to&lt;span class="w"> &lt;/span>&lt;span class="m">4345&lt;/span> Writing&lt;span class="w"> &lt;/span>new&lt;span class="w"> &lt;/span>data %&lt;span class="w"> &lt;/span>./verify Serial&lt;span class="w"> &lt;/span>number:&lt;span class="w"> &lt;/span>&lt;span class="m">83&lt;/span> Correct! &lt;/code>&lt;/pre>&lt;/div> &lt;p>Let’s take a look at the resulting binary:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>dis&lt;span class="w"> &lt;/span>-b verify&lt;span class="sb">`&lt;/span>___lldb_unnamed_symbol1&lt;span class="nv">$$&lt;/span>verify: -&amp;gt;&lt;span class="w"> &lt;/span>0x1000010c0&lt;span class="w"> &lt;/span>&amp;lt;+0&amp;gt;:&lt;span class="w"> &lt;/span>&lt;span class="m">55&lt;/span>&lt;span class="w"> &lt;/span>pushq&lt;span class="w"> &lt;/span>%rbp &lt;span class="w"> &lt;/span>0x1000010c1&lt;span class="w"> &lt;/span>&amp;lt;+1&amp;gt;:&lt;span class="w"> &lt;/span>&lt;span class="m">48&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">89&lt;/span>&lt;span class="w"> &lt;/span>e5&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rsp,&lt;span class="w"> &lt;/span>%rbp &lt;span class="w"> &lt;/span>... &lt;span class="w"> &lt;/span>0x1000010f6&lt;span class="w"> &lt;/span>&amp;lt;+54&amp;gt;:&lt;span class="w"> &lt;/span>eb&lt;span class="w"> &lt;/span>&lt;span class="m">17&lt;/span>&lt;span class="w"> &lt;/span>jmp&lt;span class="w"> &lt;/span>0x10000110f&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&amp;lt;+79&amp;gt; &lt;span class="w"> &lt;/span>0x1000010f8&lt;span class="w"> &lt;/span>&amp;lt;+56&amp;gt;:&lt;span class="w"> &lt;/span>&lt;span class="m">90&lt;/span>&lt;span class="w"> &lt;/span>nop &lt;span class="w"> &lt;/span>0x1000010f9&lt;span class="w"> &lt;/span>&amp;lt;+57&amp;gt;:&lt;span class="w"> &lt;/span>&lt;span class="m">48&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">89&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">45&lt;/span>&lt;span class="w"> &lt;/span>e8&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rax,&lt;span class="w"> &lt;/span>-0x18&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>... &lt;span class="w"> &lt;/span>0x10000110f&lt;span class="w"> &lt;/span>&amp;lt;+79&amp;gt;:&lt;span class="w"> &lt;/span>&lt;span class="m">48&lt;/span>&lt;span class="w"> &lt;/span>8b&lt;span class="w"> &lt;/span>3d&lt;span class="w"> &lt;/span>f2&lt;span class="w"> &lt;/span>0e&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>0xef2&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rdi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>void&lt;span class="w"> &lt;/span>*&lt;span class="o">)&lt;/span>0x00007fff78ba32f8:&lt;span class="w"> &lt;/span>std::__1::cout &lt;span class="w"> &lt;/span>0x100001116&lt;span class="w"> &lt;/span>&amp;lt;+86&amp;gt;:&lt;span class="w"> &lt;/span>&lt;span class="m">48&lt;/span>&lt;span class="w"> &lt;/span>8d&lt;span class="w"> &lt;/span>&lt;span class="m">35&lt;/span>&lt;span class="w"> &lt;/span>4f&lt;span class="w"> &lt;/span>0e&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>leaq&lt;span class="w"> &lt;/span>0xe4f&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rsi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">"Correct!\n"&lt;/span> &lt;span class="w"> &lt;/span>0x10000111d&lt;span class="w"> &lt;/span>&amp;lt;+93&amp;gt;:&lt;span class="w"> &lt;/span>e8&lt;span class="w"> &lt;/span>2e&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x100001150&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>___lldb_unnamed_symbol2&lt;span class="nv">$$&lt;/span>verify &lt;span class="w"> &lt;/span>0x100001122&lt;span class="w"> &lt;/span>&amp;lt;+98&amp;gt;:&lt;span class="w"> &lt;/span>&lt;span class="m">48&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">89&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">45&lt;/span>&lt;span class="w"> &lt;/span>e0&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rax,&lt;span class="w"> &lt;/span>-0x20&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>0x100001126&lt;span class="w"> &lt;/span>&amp;lt;+102&amp;gt;:&lt;span class="w"> &lt;/span>e9&lt;span class="w"> &lt;/span>&lt;span class="m">17&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>jmp&lt;span class="w"> &lt;/span>0x100001142&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&amp;lt;+130&amp;gt; &lt;span class="w"> &lt;/span>0x10000112b&lt;span class="w"> &lt;/span>&amp;lt;+107&amp;gt;:&lt;span class="w"> &lt;/span>&lt;span class="m">48&lt;/span>&lt;span class="w"> &lt;/span>8b&lt;span class="w"> &lt;/span>3d&lt;span class="w"> &lt;/span>d6&lt;span class="w"> &lt;/span>0e&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>0xed6&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rdi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>void&lt;span class="w"> &lt;/span>*&lt;span class="o">)&lt;/span>0x00007fff78ba32f8:&lt;span class="w"> &lt;/span>std::__1::cout &lt;span class="w"> &lt;/span>0x100001132&lt;span class="w"> &lt;/span>&amp;lt;+114&amp;gt;:&lt;span class="w"> &lt;/span>&lt;span class="m">48&lt;/span>&lt;span class="w"> &lt;/span>8d&lt;span class="w"> &lt;/span>&lt;span class="m">35&lt;/span>&lt;span class="w"> &lt;/span>3d&lt;span class="w"> &lt;/span>0e&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>leaq&lt;span class="w"> &lt;/span>0xe3d&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rsi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">"Incorrect!\n"&lt;/span> &lt;span class="w"> &lt;/span>0x100001139&lt;span class="w"> &lt;/span>&amp;lt;+121&amp;gt;:&lt;span class="w"> &lt;/span>e8&lt;span class="w"> &lt;/span>&lt;span class="m">12&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x100001150&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>___lldb_unnamed_symbol2&lt;span class="nv">$$&lt;/span>verify &lt;span class="w"> &lt;/span>0x10000113e&lt;span class="w"> &lt;/span>&amp;lt;+126&amp;gt;:&lt;span class="w"> &lt;/span>&lt;span class="m">48&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">89&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">45&lt;/span>&lt;span class="w"> &lt;/span>d8&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rax,&lt;span class="w"> &lt;/span>-0x28&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>0x100001142&lt;span class="w"> &lt;/span>&amp;lt;+130&amp;gt;:&lt;span class="w"> &lt;/span>&lt;span class="m">31&lt;/span>&lt;span class="w"> &lt;/span>c0&lt;span class="w"> &lt;/span>xorl&lt;span class="w"> &lt;/span>%eax,&lt;span class="w"> &lt;/span>%eax &lt;span class="w"> &lt;/span>0x100001144&lt;span class="w"> &lt;/span>&amp;lt;+132&amp;gt;:&lt;span class="w"> &lt;/span>&lt;span class="m">48&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">83&lt;/span>&lt;span class="w"> &lt;/span>c4&lt;span class="w"> &lt;/span>&lt;span class="m">30&lt;/span>&lt;span class="w"> &lt;/span>addq&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x30,&lt;span class="w"> &lt;/span>%rsp &lt;span class="w"> &lt;/span>0x100001148&lt;span class="w"> &lt;/span>&amp;lt;+136&amp;gt;:&lt;span class="w"> &lt;/span>5d&lt;span class="w"> &lt;/span>popq&lt;span class="w"> &lt;/span>%rbp &lt;span class="w"> &lt;/span>0x100001149&lt;span class="w"> &lt;/span>&amp;lt;+137&amp;gt;:&lt;span class="w"> &lt;/span>c3&lt;span class="w"> &lt;/span>retq &lt;span class="w"> &lt;/span>0x10000114a&lt;span class="w"> &lt;/span>&amp;lt;+138&amp;gt;:&lt;span class="w"> &lt;/span>&lt;span class="m">66&lt;/span>&lt;span class="w"> &lt;/span>0f&lt;span class="w"> &lt;/span>1f&lt;span class="w"> &lt;/span>&lt;span class="m">44&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>nopw&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>%rax,%rax&lt;span class="o">)&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Take a look in particular at the following to view our inserted instructions:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>0x1000010f6&lt;span class="w"> &lt;/span>&amp;lt;+54&amp;gt;:&lt;span class="w"> &lt;/span>eb&lt;span class="w"> &lt;/span>&lt;span class="m">17&lt;/span>&lt;span class="w"> &lt;/span>jmp&lt;span class="w"> &lt;/span>0x10000110f&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&amp;lt;+79&amp;gt; 0x1000010f8&lt;span class="w"> &lt;/span>&amp;lt;+56&amp;gt;:&lt;span class="w"> &lt;/span>&lt;span class="m">90&lt;/span>&lt;span class="w"> &lt;/span>nop &lt;/code>&lt;/pre>&lt;/div> &lt;p>Continue to read the &lt;a href="https://www.mortens.dev/blog/patching-binaries-live-modification/">third part&lt;/a> about changing values in a program, and live modification of the memory of a running program.&lt;/p></content><category term="Patching"/><category term="patching"/><category term="x86-64"/><category term="cpp"/><category term="python"/><category term="lldb"/><category term="disassembling"/></entry><entry><title>Patching Binaries: Strings</title><link href="https://www.mortens.dev/blog/patching-binaries-strings/" rel="alternate"/><published>2016-09-05T22:31:40+02:00</published><updated>2016-09-05T22:31:40+02:00</updated><author><name>Morten</name></author><id>tag:www.mortens.dev,2016-09-05:/blog/patching-binaries-strings/</id><summary type="html">&lt;p>How to patch strings in&amp;nbsp;binaries&lt;/p></summary><content type="html">&lt;p>&lt;em>Patching Binaries&lt;/em> will be a series of articles about how to extract information and modify program behavior. It focuses on the Mac &lt;a href="https://en.wikipedia.org/wiki/Mach-O">Mach-O&lt;/a> executable format for the &lt;a href="https://en.wikipedia.org/wiki/X86-64">x86-64&lt;/a> architecture, but the techniques are similar for other formats.&lt;/p> &lt;p>&lt;em>The files used in this article can be found &lt;a href="https://github.com/netromdk/patching/tree/master/strings">here&lt;/a>.&lt;/em>&lt;/p> &lt;p>One of the first things to look at in a binary, when trying to determine information about it, is the constant strings saved within it. In Mach-O binaries these can be found in section &lt;code>__cstring&lt;/code> of segment &lt;code>__TEXT&lt;/code>.&lt;/p> &lt;p>Compile the example program “test.cc” as “test” and run it:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>./test std::string&lt;span class="w"> &lt;/span>example. And&lt;span class="w"> &lt;/span>a&lt;span class="w"> &lt;/span>char*&lt;span class="w"> &lt;/span>string,&lt;span class="w"> &lt;/span>too. &lt;/code>&lt;/pre>&lt;/div> &lt;p>To list a programs’ strings there are at least two programs to help us do that; &lt;code>otool&lt;/code> and &lt;code>strings&lt;/code>.&lt;/p> &lt;p>The most simple is using &lt;code>strings&lt;/code>:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>strings&lt;span class="w"> &lt;/span>-o&lt;span class="w"> &lt;/span>-t&lt;span class="w"> &lt;/span>x&lt;span class="w"> &lt;/span>&lt;span class="nb">test&lt;/span> 1f50&lt;span class="w"> &lt;/span>std::string&lt;span class="w"> &lt;/span>example. 1f65&lt;span class="w"> &lt;/span>And&lt;span class="w"> &lt;/span>a&lt;span class="w"> &lt;/span>char*&lt;span class="w"> &lt;/span>string,&lt;span class="w"> &lt;/span>too. &lt;/code>&lt;/pre>&lt;/div> &lt;p>It shows the strings and their hexadecimal offsets in the binary.&lt;/p> &lt;p>A little more detail can be obtained with &lt;code>otool&lt;/code> though:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>otool&lt;span class="w"> &lt;/span>-s&lt;span class="w"> &lt;/span>__TEXT&lt;span class="w"> &lt;/span>__cstring&lt;span class="w"> &lt;/span>&lt;span class="nb">test&lt;/span> test: Contents&lt;span class="w"> &lt;/span>of&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>__TEXT,__cstring&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>section 0000000100001f50&lt;span class="w"> &lt;/span>&lt;span class="m">73&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">74&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">64&lt;/span>&lt;span class="w"> &lt;/span>3a&lt;span class="w"> &lt;/span>3a&lt;span class="w"> &lt;/span>&lt;span class="m">73&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">74&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">72&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">69&lt;/span>&lt;span class="w"> &lt;/span>6e&lt;span class="w"> &lt;/span>&lt;span class="m">67&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">20&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">65&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">78&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">61&lt;/span>&lt;span class="w"> &lt;/span>6d 0000000100001f60&lt;span class="w"> &lt;/span>&lt;span class="m">70&lt;/span>&lt;span class="w"> &lt;/span>6c&lt;span class="w"> &lt;/span>&lt;span class="m">65&lt;/span>&lt;span class="w"> &lt;/span>2e&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">41&lt;/span>&lt;span class="w"> &lt;/span>6e&lt;span class="w"> &lt;/span>&lt;span class="m">64&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">20&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">61&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">20&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">63&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">68&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">61&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">72&lt;/span>&lt;span class="w"> &lt;/span>2a 0000000100001f70&lt;span class="w"> &lt;/span>&lt;span class="m">20&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">73&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">74&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">72&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">69&lt;/span>&lt;span class="w"> &lt;/span>6e&lt;span class="w"> &lt;/span>&lt;span class="m">67&lt;/span>&lt;span class="w"> &lt;/span>2c&lt;span class="w"> &lt;/span>&lt;span class="m">20&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">74&lt;/span>&lt;span class="w"> &lt;/span>6f&lt;span class="w"> &lt;/span>6f&lt;span class="w"> &lt;/span>2e&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>0a&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span> %&lt;span class="w"> &lt;/span>otool&lt;span class="w"> &lt;/span>-v&lt;span class="w"> &lt;/span>-s&lt;span class="w"> &lt;/span>__TEXT&lt;span class="w"> &lt;/span>__cstring&lt;span class="w"> &lt;/span>&lt;span class="nb">test&lt;/span> test: Contents&lt;span class="w"> &lt;/span>of&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>__TEXT,__cstring&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>section 0000000100001f50&lt;span class="w"> &lt;/span>std::string&lt;span class="w"> &lt;/span>example. 0000000100001f65&lt;span class="w"> &lt;/span>And&lt;span class="w"> &lt;/span>a&lt;span class="w"> &lt;/span>char*&lt;span class="w"> &lt;/span>string,&lt;span class="w"> &lt;/span>too. 0000000100001f7e&lt;span class="w"> &lt;/span>&lt;span class="se">\n&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>To understand the layout of the binary block above the strings are end-to-end:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="mf">0000000100001&lt;/span>&lt;span class="n">f50&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">73&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">74&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">64&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">3&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">3&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">73&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">74&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">72&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">69&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">6&lt;/span>&lt;span class="n">e&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">67&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">20&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">65&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">78&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">61&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">6&lt;/span>&lt;span class="n">d&lt;/span> &lt;span class="mf">0000000100001&lt;/span>&lt;span class="n">f60&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">70&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">6&lt;/span>&lt;span class="n">c&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">65&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">2&lt;/span>&lt;span class="n">e&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">00&lt;/span> &lt;span class="mf">0000000100001&lt;/span>&lt;span class="n">f65&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">41&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">6&lt;/span>&lt;span class="n">e&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">64&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">20&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">61&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">20&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">63&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">68&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">61&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">72&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">2&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">20&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">73&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">74&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">72&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">69&lt;/span> &lt;span class="mf">0000000100001&lt;/span>&lt;span class="n">f75&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">6&lt;/span>&lt;span class="n">e&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">67&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">2&lt;/span>&lt;span class="n">c&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">20&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">74&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">6&lt;/span>&lt;span class="n">f&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">6&lt;/span>&lt;span class="n">f&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">2&lt;/span>&lt;span class="n">e&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">00&lt;/span> &lt;span class="mf">0000000100001&lt;/span>&lt;span class="n">f7e&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">0&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">00&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>&lt;em>Notice the zero byte for termination at the end of each string!&lt;/em>&lt;/p> &lt;p>We now know that there are two “interesting” strings at offset &lt;code>1f50&lt;/code> and &lt;code>1f65&lt;/code>, which means if we read the binary’s data at those positions we will find the strings.&lt;/p> &lt;p>The next natural thing to do is modifying the strings. I wrote a python script “patch.py” to patch a binary at an offset with a new string.&lt;/p> &lt;p>Let’s change the first string to become &lt;code>"Hello, World!"&lt;/code>:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>./patch.py&lt;span class="w"> &lt;/span>&lt;span class="nb">test&lt;/span>&lt;span class="w"> &lt;/span>0x1f50&lt;span class="w"> &lt;/span>&lt;span class="s2">"Hello, World! "&lt;/span> Patching&lt;span class="w"> &lt;/span>&lt;span class="s2">"test"&lt;/span>&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>offset&lt;span class="w"> &lt;/span>&lt;span class="m">8016&lt;/span>&lt;span class="w"> &lt;/span>with:&lt;span class="w"> &lt;/span>&lt;span class="s2">"Hello, World! "&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="m">20&lt;/span>&lt;span class="w"> &lt;/span>bytes&lt;span class="o">)&lt;/span> Read&lt;span class="w"> &lt;/span>&lt;span class="m">15392&lt;/span>&lt;span class="w"> &lt;/span>bytes Size&lt;span class="w"> &lt;/span>of&lt;span class="w"> &lt;/span>string&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>&lt;span class="m">8016&lt;/span>&lt;span class="w"> &lt;/span>is&lt;span class="w"> &lt;/span>&lt;span class="m">20&lt;/span>&lt;span class="w"> &lt;/span>bytes Changing&lt;span class="w"> &lt;/span>values&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>&lt;span class="m">8016&lt;/span>&lt;span class="w"> &lt;/span>to&lt;span class="w"> &lt;/span>&lt;span class="m">8036&lt;/span> Writing&lt;span class="w"> &lt;/span>new&lt;span class="w"> &lt;/span>data %&lt;span class="w"> &lt;/span>./test Hello,&lt;span class="w"> &lt;/span>World! And&lt;span class="w"> &lt;/span>a&lt;span class="w"> &lt;/span>char*&lt;span class="w"> &lt;/span>string,&lt;span class="w"> &lt;/span>too. &lt;/code>&lt;/pre>&lt;/div> &lt;p>Voila!&lt;/p> &lt;p>Note that the size of the string we patched is 20 bytes, which means the value to overwrite it cannot be longer than that. To visually clear the old value we put spaces as padding at the end. &lt;/p> &lt;p>The contents of the binary are now changed to the following:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>otool&lt;span class="w"> &lt;/span>-s&lt;span class="w"> &lt;/span>__TEXT&lt;span class="w"> &lt;/span>__cstring&lt;span class="w"> &lt;/span>&lt;span class="nb">test&lt;/span> test: Contents&lt;span class="w"> &lt;/span>of&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>__TEXT,__cstring&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>section 0000000100001f50&lt;span class="w"> &lt;/span>&lt;span class="m">48&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">65&lt;/span>&lt;span class="w"> &lt;/span>6c&lt;span class="w"> &lt;/span>6c&lt;span class="w"> &lt;/span>6f&lt;span class="w"> &lt;/span>2c&lt;span class="w"> &lt;/span>&lt;span class="m">20&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">57&lt;/span>&lt;span class="w"> &lt;/span>6f&lt;span class="w"> &lt;/span>&lt;span class="m">72&lt;/span>&lt;span class="w"> &lt;/span>6c&lt;span class="w"> &lt;/span>&lt;span class="m">64&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">21&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">20&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">20&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">20&lt;/span> 0000000100001f60&lt;span class="w"> &lt;/span>&lt;span class="m">20&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">20&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">20&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">20&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">41&lt;/span>&lt;span class="w"> &lt;/span>6e&lt;span class="w"> &lt;/span>&lt;span class="m">64&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">20&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">61&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">20&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">63&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">68&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">61&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">72&lt;/span>&lt;span class="w"> &lt;/span>2a 0000000100001f70&lt;span class="w"> &lt;/span>&lt;span class="m">20&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">73&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">74&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">72&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">69&lt;/span>&lt;span class="w"> &lt;/span>6e&lt;span class="w"> &lt;/span>&lt;span class="m">67&lt;/span>&lt;span class="w"> &lt;/span>2c&lt;span class="w"> &lt;/span>&lt;span class="m">20&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">74&lt;/span>&lt;span class="w"> &lt;/span>6f&lt;span class="w"> &lt;/span>6f&lt;span class="w"> &lt;/span>2e&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>0a&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Notice the 7 spaces (byte &lt;code>20&lt;/code>) after our string.&lt;/p> &lt;p>As a second example compile “password.cc” into “password” and run it:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>./password Password:&lt;span class="w"> &lt;/span>&lt;span class="nb">test&lt;/span> Invalid! Password:&lt;span class="w"> &lt;/span>password Invalid! Password:&lt;span class="w"> &lt;/span>&lt;span class="m">1234&lt;/span> Invalid! Password:&lt;span class="w"> &lt;/span>^C &lt;/code>&lt;/pre>&lt;/div> &lt;p>Okay, so maybe we can’t just outright guess it. Let’s look at the strings in the binary instead for clues:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>otool&lt;span class="w"> &lt;/span>-v&lt;span class="w"> &lt;/span>-s&lt;span class="w"> &lt;/span>__TEXT&lt;span class="w"> &lt;/span>__cstring&lt;span class="w"> &lt;/span>password password: Contents&lt;span class="w"> &lt;/span>of&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>__TEXT,__cstring&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>section 0000000100001f28&lt;span class="w"> &lt;/span>Password: 0000000100001f33&lt;span class="w"> &lt;/span>AK9FJ31P 0000000100001f3c&lt;span class="w"> &lt;/span>You&lt;span class="err">'&lt;/span>ve&lt;span class="w"> &lt;/span>entered&lt;span class="w"> &lt;/span>the&lt;span class="w"> &lt;/span>correct&lt;span class="w"> &lt;/span>password!&lt;span class="se">\n&lt;/span> 0000000100001f62&lt;span class="w"> &lt;/span>Invalid!&lt;span class="se">\n&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>One value looks curious: “&lt;span class="caps">AK9FJ31P&lt;/span>”&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>./password Password:&lt;span class="w"> &lt;/span>AK9FJ31P You&lt;span class="err">'&lt;/span>ve&lt;span class="w"> &lt;/span>entered&lt;span class="w"> &lt;/span>the&lt;span class="w"> &lt;/span>correct&lt;span class="w"> &lt;/span>password! &lt;/code>&lt;/pre>&lt;/div> &lt;p>&lt;em>Keep in mind that this is a very simple example and nothing akin to a real-world example.&lt;/em> It just illustrates the technique of finding constant strings in a binary that can be used in different ways.&lt;/p> &lt;p>Lastly we will briefly see how the offsets to the constant strings relate to the machine code instructions of the executable. We will do this by using the debugger &lt;a href="http://lldb.llvm.org">&lt;span class="caps">LLDB&lt;/span>&lt;/a> to find the spot where the password of the previous example is loaded into memory.&lt;/p> &lt;p>We start by running &lt;span class="caps">LLDB&lt;/span> and braking when the &lt;code>main()&lt;/code> is called:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>lldb&lt;span class="w"> &lt;/span>./password &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>target&lt;span class="w"> &lt;/span>create&lt;span class="w"> &lt;/span>&lt;span class="s2">"./password"&lt;/span> Current&lt;span class="w"> &lt;/span>executable&lt;span class="w"> &lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="w"> &lt;/span>to&lt;span class="w"> &lt;/span>&lt;span class="s1">'./password'&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>x86_64&lt;span class="o">)&lt;/span>. &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>b&lt;span class="w"> &lt;/span>main Breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>:&lt;span class="w"> &lt;/span>&lt;span class="nv">where&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>password&lt;span class="sb">`&lt;/span>main,&lt;span class="w"> &lt;/span>&lt;span class="nv">address&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>0x0000000100000650 &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>r Process&lt;span class="w"> &lt;/span>&lt;span class="m">84336&lt;/span>&lt;span class="w"> &lt;/span>launched:&lt;span class="w"> &lt;/span>&lt;span class="s1">'./password'&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>x86_64&lt;span class="o">)&lt;/span> Process&lt;span class="w"> &lt;/span>&lt;span class="m">84336&lt;/span>&lt;span class="w"> &lt;/span>stopped *&lt;span class="w"> &lt;/span>thread&lt;span class="w"> &lt;/span>&lt;span class="c1">#1: tid = 0x212d03, 0x0000000100000650 password`main, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1&lt;/span> &lt;span class="w"> &lt;/span>frame&lt;span class="w"> &lt;/span>&lt;span class="c1">#0: 0x0000000100000650 password`main&lt;/span> password&lt;span class="sb">`&lt;/span>main: -&amp;gt;&lt;span class="w"> &lt;/span>0x100000650&lt;span class="w"> &lt;/span>&amp;lt;+0&amp;gt;:&lt;span class="w"> &lt;/span>pushq&lt;span class="w"> &lt;/span>%rbp &lt;span class="w"> &lt;/span>0x100000651&lt;span class="w"> &lt;/span>&amp;lt;+1&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rsp,&lt;span class="w"> &lt;/span>%rbp &lt;span class="w"> &lt;/span>0x100000654&lt;span class="w"> &lt;/span>&amp;lt;+4&amp;gt;:&lt;span class="w"> &lt;/span>subq&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>xd0,&lt;span class="w"> &lt;/span>%rsp &lt;span class="w"> &lt;/span>0x10000065b&lt;span class="w"> &lt;/span>&amp;lt;+11&amp;gt;:&lt;span class="w"> &lt;/span>xorl&lt;span class="w"> &lt;/span>%esi,&lt;span class="w"> &lt;/span>%esi &lt;/code>&lt;/pre>&lt;/div> &lt;p>Since we do not know the address of the instructions that loads the string we have to step through the program until we find it. To get a better overview we will disassemble the &lt;code>main()&lt;/code>:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>dis password&lt;span class="sb">`&lt;/span>main: -&amp;gt;&lt;span class="w"> &lt;/span>0x100000650&lt;span class="w"> &lt;/span>&amp;lt;+0&amp;gt;:&lt;span class="w"> &lt;/span>pushq&lt;span class="w"> &lt;/span>%rbp &lt;span class="w"> &lt;/span>0x100000651&lt;span class="w"> &lt;/span>&amp;lt;+1&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rsp,&lt;span class="w"> &lt;/span>%rbp &lt;span class="w"> &lt;/span>0x100000654&lt;span class="w"> &lt;/span>&amp;lt;+4&amp;gt;:&lt;span class="w"> &lt;/span>subq&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>xd0,&lt;span class="w"> &lt;/span>%rsp &lt;span class="w"> &lt;/span>0x10000065b&lt;span class="w"> &lt;/span>&amp;lt;+11&amp;gt;:&lt;span class="w"> &lt;/span>xorl&lt;span class="w"> &lt;/span>%esi,&lt;span class="w"> &lt;/span>%esi &lt;span class="w"> &lt;/span>0x10000065d&lt;span class="w"> &lt;/span>&amp;lt;+13&amp;gt;:&lt;span class="w"> &lt;/span>movl&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x18,&lt;span class="w"> &lt;/span>%eax ...... &lt;span class="w"> &lt;/span>0x1000006fb&lt;span class="w"> &lt;/span>&amp;lt;+171&amp;gt;:&lt;span class="w"> &lt;/span>jmp&lt;span class="w"> &lt;/span>0x1000006d7&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&amp;lt;+135&amp;gt; &lt;span class="w"> &lt;/span>0x100000700&lt;span class="w"> &lt;/span>&amp;lt;+176&amp;gt;:&lt;span class="w"> &lt;/span>jmp&lt;span class="w"> &lt;/span>0x100000705&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&amp;lt;+181&amp;gt; &lt;span class="w"> &lt;/span>0x100000705&lt;span class="w"> &lt;/span>&amp;lt;+181&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>0x18fc&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rdi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>void&lt;span class="w"> &lt;/span>*&lt;span class="o">)&lt;/span>0x00007fff78ba32f8:&lt;span class="w"> &lt;/span>std::__1::cout &lt;span class="w"> &lt;/span>0x10000070c&lt;span class="w"> &lt;/span>&amp;lt;+188&amp;gt;:&lt;span class="w"> &lt;/span>leaq&lt;span class="w"> &lt;/span>0x1815&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rsi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">"Password: "&lt;/span> &lt;span class="w"> &lt;/span>0x100000713&lt;span class="w"> &lt;/span>&amp;lt;+195&amp;gt;:&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x100000820&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>std::__1::basic_ostream&amp;lt;char,&lt;span class="w"> &lt;/span>std::__1::char_traits&amp;lt;char&amp;gt;&lt;span class="w"> &lt;/span>&amp;gt;&lt;span class="p">&amp;amp;&lt;/span>&lt;span class="w"> &lt;/span>std::__1::operator&lt;span class="o">&amp;lt;&amp;lt;&amp;lt;&lt;/span>std::__1::char_traits&amp;lt;char&amp;gt;&lt;span class="w"> &lt;/span>&amp;gt;&lt;span class="o">(&lt;/span>std::__1::basic_ostream&amp;lt;char,&lt;span class="w"> &lt;/span>std::__1::char_traits&amp;lt;char&amp;gt;&lt;span class="w"> &lt;/span>&amp;gt;&lt;span class="p">&amp;amp;&lt;/span>,&lt;span class="w"> &lt;/span>char&lt;span class="w"> &lt;/span>const*&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>0x100000718&lt;span class="w"> &lt;/span>&amp;lt;+200&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rax,&lt;span class="w"> &lt;/span>-0xa8&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>0x10000071f&lt;span class="w"> &lt;/span>&amp;lt;+207&amp;gt;:&lt;span class="w"> &lt;/span>jmp&lt;span class="w"> &lt;/span>0x100000724&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&amp;lt;+212&amp;gt; &lt;span class="w"> &lt;/span>0x100000724&lt;span class="w"> &lt;/span>&amp;lt;+212&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>0x18d5&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rdi&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>void&lt;span class="w"> &lt;/span>*&lt;span class="o">)&lt;/span>0x00007fff78ba3250:&lt;span class="w"> &lt;/span>std::__1::cin ...... &lt;span class="w"> &lt;/span>0x100000737&lt;span class="w"> &lt;/span>&amp;lt;+231&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rax,&lt;span class="w"> &lt;/span>-0xb0&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>0x10000073e&lt;span class="w"> &lt;/span>&amp;lt;+238&amp;gt;:&lt;span class="w"> &lt;/span>jmp&lt;span class="w"> &lt;/span>0x100000743&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&amp;lt;+243&amp;gt; &lt;span class="w"> &lt;/span>0x100000743&lt;span class="w"> &lt;/span>&amp;lt;+243&amp;gt;:&lt;span class="w"> &lt;/span>leaq&lt;span class="w"> &lt;/span>0x17e9&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rax&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">"AK9FJ31P"&lt;/span> ...... &lt;/code>&lt;/pre>&lt;/div> &lt;p>From the above excerpt it is shown that the &lt;code>"Password: "&lt;/code> text is loaded at &lt;code>0x10000070c&lt;/code>, and that the input of &lt;code>std::cin&lt;/code> at &lt;code>0x100000724&lt;/code> is compared with the real password &lt;code>"AK9FJ31P"&lt;/code> on &lt;code>0x100000743&lt;/code>. But let’s look closer at that last address:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>dis&lt;span class="w"> &lt;/span>-b&lt;span class="w"> &lt;/span>-c&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="w"> &lt;/span>-s&lt;span class="w"> &lt;/span>0x100000743 password&lt;span class="sb">`&lt;/span>main: &lt;span class="w"> &lt;/span>0x100000743&lt;span class="w"> &lt;/span>&amp;lt;+243&amp;gt;:&lt;span class="w"> &lt;/span>&lt;span class="m">48&lt;/span>&lt;span class="w"> &lt;/span>8d&lt;span class="w"> &lt;/span>&lt;span class="m">05&lt;/span>&lt;span class="w"> &lt;/span>e9&lt;span class="w"> &lt;/span>&lt;span class="m">17&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w"> &lt;/span>leaq&lt;span class="w"> &lt;/span>0x17e9&lt;span class="o">(&lt;/span>%rip&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>%rax&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">"AK9FJ31P"&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>We know that &lt;code>"AK9FJ31P"&lt;/code> resides at offset &lt;code>1f33&lt;/code> but here it uses &lt;code>17e9&lt;/code>, why? To understand this it is necessary to know that it uses relative addressing. So the &lt;code>leaq&lt;/code> (load effective address) is invoked at &lt;code>743&lt;/code> and if we add that to &lt;code>17e9&lt;/code> then we get &lt;code>1f2c&lt;/code>. That’s still not the correct offset! However, looking at the assembly code we see that it uses 7 bytes, and now the equation fits: &lt;code>743+7+17e9=1f33&lt;/code>!&lt;/p> &lt;p>&lt;em>Note that we used an unstripped binary for this example, which means it still contains useful information. However, with a real-world example it will most likely be stripped of symbols.&lt;/em>&lt;/p> &lt;p>Let’s remove the symbols:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>strip&lt;span class="w"> &lt;/span>password &lt;/code>&lt;/pre>&lt;/div> &lt;p>Now when we try to hook up on the &lt;code>main()&lt;/code> it is evident that we can’t because the symbol is not known:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>lldb&lt;span class="w"> &lt;/span>./password &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>target&lt;span class="w"> &lt;/span>create&lt;span class="w"> &lt;/span>&lt;span class="s2">"./password"&lt;/span> Current&lt;span class="w"> &lt;/span>executable&lt;span class="w"> &lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="w"> &lt;/span>to&lt;span class="w"> &lt;/span>&lt;span class="s1">'./password'&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>x86_64&lt;span class="o">)&lt;/span>. &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>b&lt;span class="w"> &lt;/span>main Breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>:&lt;span class="w"> &lt;/span>no&lt;span class="w"> &lt;/span>locations&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>pending&lt;span class="o">)&lt;/span>. WARNING:&lt;span class="w"> &lt;/span>Unable&lt;span class="w"> &lt;/span>to&lt;span class="w"> &lt;/span>resolve&lt;span class="w"> &lt;/span>breakpoint&lt;span class="w"> &lt;/span>to&lt;span class="w"> &lt;/span>any&lt;span class="w"> &lt;/span>actual&lt;span class="w"> &lt;/span>locations. &lt;/code>&lt;/pre>&lt;/div> &lt;p>Instead we will run the program until it asks for the password and then break to see a backtrace to get our bearings:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>r Process&lt;span class="w"> &lt;/span>&lt;span class="m">86636&lt;/span>&lt;span class="w"> &lt;/span>launched:&lt;span class="w"> &lt;/span>&lt;span class="s1">'./password'&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>x86_64&lt;span class="o">)&lt;/span> Password:&lt;span class="w"> &lt;/span>Process&lt;span class="w"> &lt;/span>&lt;span class="m">86636&lt;/span>&lt;span class="w"> &lt;/span>stopped *&lt;span class="w"> &lt;/span>thread&lt;span class="w"> &lt;/span>&lt;span class="c1">#1: tid = 0x225927, 0x00007fff9218df8a libsystem_kernel.dylib`__read_nocancel + 10, stop reason = signal SIGSTOP&lt;/span> &lt;span class="w"> &lt;/span>frame&lt;span class="w"> &lt;/span>&lt;span class="c1">#0: 0x00007fff9218df8a libsystem_kernel.dylib`__read_nocancel + 10&lt;/span> libsystem_kernel.dylib&lt;span class="sb">`&lt;/span>__read_nocancel: -&amp;gt;&lt;span class="w"> &lt;/span>0x7fff9218df8a&lt;span class="w"> &lt;/span>&amp;lt;+10&amp;gt;:&lt;span class="w"> &lt;/span>jae&lt;span class="w"> &lt;/span>0x7fff9218df94&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&amp;lt;+20&amp;gt; &lt;span class="w"> &lt;/span>0x7fff9218df8c&lt;span class="w"> &lt;/span>&amp;lt;+12&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>%rax,&lt;span class="w"> &lt;/span>%rdi &lt;span class="w"> &lt;/span>0x7fff9218df8f&lt;span class="w"> &lt;/span>&amp;lt;+15&amp;gt;:&lt;span class="w"> &lt;/span>jmp&lt;span class="w"> &lt;/span>0x7fff921887cd&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>cerror_nocancel &lt;span class="w"> &lt;/span>0x7fff9218df94&lt;span class="w"> &lt;/span>&amp;lt;+20&amp;gt;:&lt;span class="w"> &lt;/span>retq &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>bt *&lt;span class="w"> &lt;/span>thread&lt;span class="w"> &lt;/span>&lt;span class="c1">#1: tid = 0x225927, 0x00007fff9218df8a libsystem_kernel.dylib`__read_nocancel + 10, stop reason = signal SIGSTOP&lt;/span> &lt;span class="w"> &lt;/span>*&lt;span class="w"> &lt;/span>frame&lt;span class="w"> &lt;/span>&lt;span class="c1">#0: 0x00007fff9218df8a libsystem_kernel.dylib`__read_nocancel + 10&lt;/span> &lt;span class="w"> &lt;/span>frame&lt;span class="w"> &lt;/span>&lt;span class="c1">#1: 0x00007fff8d103155 libsystem_c.dylib`_sread + 16&lt;/span> &lt;span class="w"> &lt;/span>frame&lt;span class="w"> &lt;/span>&lt;span class="c1">#2: 0x00007fff8d102769 libsystem_c.dylib`__srefill1 + 24&lt;/span> &lt;span class="w"> &lt;/span>frame&lt;span class="w"> &lt;/span>&lt;span class="c1">#3: 0x00007fff8d102884 libsystem_c.dylib`__srget + 14&lt;/span> &lt;span class="w"> &lt;/span>frame&lt;span class="w"> &lt;/span>&lt;span class="c1">#4: 0x00007fff8d0fe52b libsystem_c.dylib`getc + 52&lt;/span> &lt;span class="w"> &lt;/span>frame&lt;span class="w"> &lt;/span>&lt;span class="c1">#5: 0x00007fff8dd38051 libc++.1.dylib`std::__1::__stdinbuf&amp;lt;char&amp;gt;::__getchar(bool) + 119&lt;/span> &lt;span class="w"> &lt;/span>frame&lt;span class="w"> &lt;/span>&lt;span class="c1">#6: 0x00007fff8dd2ee4c libc++.1.dylib`std::__1::basic_istream&amp;lt;char, std::__1::char_traits&amp;lt;char&amp;gt; &amp;gt;::sentry::sentry(std::__1::basic_istream&amp;lt;char, std::__1::char_traits&amp;lt;char&amp;gt; &amp;gt;&amp;amp;, bool) + 200&lt;/span> &lt;span class="w"> &lt;/span>frame&lt;span class="w"> &lt;/span>&lt;span class="c1">#7: 0x000000010000089e password`___lldb_unnamed_symbol3$$password + 46&lt;/span> &lt;span class="w"> &lt;/span>frame&lt;span class="w"> &lt;/span>&lt;span class="c1">#8: 0x0000000100000737 password`___lldb_unnamed_symbol1$$password + 231&lt;/span> &lt;span class="w"> &lt;/span>frame&lt;span class="w"> &lt;/span>&lt;span class="c1">#9: 0x00007fff9a14a5ad libdyld.dylib`start + 1&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>The backtrace shows two function calls in our &lt;code>password&lt;/code> executable. Taking a look at frame 8 shows the same location we used previously to argument about the address of the constant string being loaded:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>&lt;span class="nt">lldb&lt;/span>&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">f&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">8&lt;/span> &lt;span class="nt">frame&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">#&lt;/span>&lt;span class="nn">8&lt;/span>&lt;span class="o">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">0x0000000100000737&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">password&lt;/span>&lt;span class="err">`&lt;/span>&lt;span class="nt">___lldb_unnamed_symbol1&lt;/span>&lt;span class="o">$$&lt;/span>&lt;span class="nt">password&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">+&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">231&lt;/span> &lt;span class="nt">password&lt;/span>&lt;span class="err">`&lt;/span>&lt;span class="nt">___lldb_unnamed_symbol1&lt;/span>&lt;span class="o">$$&lt;/span>&lt;span class="nt">password&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nt">0x100000737&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;+&lt;/span>&lt;span class="nt">231&lt;/span>&lt;span class="o">&amp;gt;:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">movq&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">%&lt;/span>&lt;span class="nt">rax&lt;/span>&lt;span class="o">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">-0xb0&lt;/span>&lt;span class="o">(%&lt;/span>&lt;span class="nt">rbp&lt;/span>&lt;span class="o">)&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nt">0x10000073e&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;+&lt;/span>&lt;span class="nt">238&lt;/span>&lt;span class="o">&amp;gt;:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">jmp&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">0x100000743&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;+&lt;/span>&lt;span class="nt">243&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nt">0x100000743&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;+&lt;/span>&lt;span class="nt">243&lt;/span>&lt;span class="o">&amp;gt;:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">leaq&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">0x17e9&lt;/span>&lt;span class="o">(%&lt;/span>&lt;span class="nt">rip&lt;/span>&lt;span class="o">),&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">%&lt;/span>&lt;span class="nt">rax&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">"AK9FJ31P"&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nt">0x10000074a&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;+&lt;/span>&lt;span class="nt">250&lt;/span>&lt;span class="o">&amp;gt;:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">leaq&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">-0x88&lt;/span>&lt;span class="o">(%&lt;/span>&lt;span class="nt">rbp&lt;/span>&lt;span class="o">),&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">%&lt;/span>&lt;span class="nt">rcx&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Continue to read the &lt;a href="https://www.mortens.dev/blog/patching-binaries-jumping-the-fence/">second part&lt;/a> about “jumping the fence” by employing jumps and bypassing instructions.&lt;/p></content><category term="Patching"/><category term="patching"/><category term="x86-64"/><category term="cpp"/><category term="python"/><category term="lldb"/><category term="disassembling"/></entry><entry><title>Sigs: Ambiguous Member Functions</title><link href="https://www.mortens.dev/blog/sigs-ambiguous-member-functions/" rel="alternate"/><published>2016-09-04T13:02:42+02:00</published><updated>2016-09-04T13:02:42+02:00</updated><author><name>Morten</name></author><id>tag:www.mortens.dev,2016-09-04:/blog/sigs-ambiguous-member-functions/</id><summary type="html">&lt;p>Handling ambiguous member functions with&amp;nbsp;Sigs&lt;/p></summary><content type="html">&lt;p>I recently updated my &lt;a href="https://github.com/netromdk/sigs">sigs&lt;/a> project (simple thread-safe signal/slot C++ library) with support for ambiguous member functions by use of the &lt;code>sigs::Use&amp;lt;&amp;gt;::overloadOf()&lt;/code>:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="k">template&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="k">typename&lt;/span>&lt;span class="p">...&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Args&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="k">struct&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nc">Use&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="k">template&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="k">typename&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nc">Cls&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">typename&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nc">Ret&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="k">static&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">auto&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">overloadOf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">Ret&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">Cls&lt;/span>&lt;span class="o">::*&lt;/span>&lt;span class="n">MembFunc&lt;/span>&lt;span class="p">)(&lt;/span>&lt;span class="n">Args&lt;/span>&lt;span class="p">...))&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">MembFunc&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span> &lt;span class="p">};&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>&lt;em>It makes use of variadic templates and auto return type deduction so the compiler must be C++14 compliant.&lt;/em>&lt;/p> &lt;p>To illustrate why it was needed consider this: Sometimes there are several overloads for a given function and then it’s not enough to just specify &lt;code>&amp;amp;Class::functionName&lt;/code> because the compiler does not know which overload to choose.&lt;/p> &lt;p>The &lt;code>Ambiguous&lt;/code> class has two overloads of &lt;code>foo&lt;/code>:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="k">class&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nc">Ambiguous&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="kt">void&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">foo&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">j&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"Ambiguous::foo(int, int)&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">"&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="kt">void&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">foo&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">float&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">j&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"Ambiguous::foo(int, float)&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">"&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span> &lt;span class="p">};&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Without the new construct the following would result in compilation failure:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="n">sigs&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">Signal&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">void&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">s&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">Ambiguous&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">amb&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">s&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">connect&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">amb&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">Ambiguous&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">foo&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">// &amp;lt;-- Will fail!&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>The error would look something similar to this:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="nt">test&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nc">cc&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="nd">147&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="nd">7&lt;/span>&lt;span class="o">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">error&lt;/span>&lt;span class="o">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">no&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">matching&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">member&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">function&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">call&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">to&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">'connect'&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nt">s&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nc">connect&lt;/span>&lt;span class="o">(&amp;amp;&lt;/span>&lt;span class="nt">amb&lt;/span>&lt;span class="o">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="nt">Ambiguous&lt;/span>&lt;span class="p">::&lt;/span>&lt;span class="nd">foo&lt;/span>&lt;span class="o">);&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="o">~~^~~~~~~&lt;/span> &lt;span class="o">./&lt;/span>&lt;span class="nt">sigs&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nc">h&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="nd">144&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="nd">16&lt;/span>&lt;span class="o">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">note&lt;/span>&lt;span class="o">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">candidate&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">template&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">ignored&lt;/span>&lt;span class="o">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">couldn&lt;/span>&lt;span class="s1">'t infer template argument '&lt;/span>&lt;span class="nt">MembFunc&lt;/span>&lt;span class="err">'&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nt">Connection&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">connect&lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="nt">Instance&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="nt">instance&lt;/span>&lt;span class="o">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">MembFunc&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nt">Instance&lt;/span>&lt;span class="o">::*&lt;/span>&lt;span class="nt">mf&lt;/span>&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>To fix it we must use &lt;code>sigs::Use&amp;lt;&amp;gt;::overloadOf()&lt;/code>:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="n">s&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">connect&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">amb&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">sigs&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">Use&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="o">&amp;gt;::&lt;/span>&lt;span class="n">overloadOf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">Ambiguous&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">foo&lt;/span>&lt;span class="p">));&lt;/span> &lt;span class="n">s&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">42&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">48&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="cm">/* Prints:&lt;/span> &lt;span class="cm">Ambiguous::foo(int, int)&lt;/span> &lt;span class="cm">*/&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Without changing the signal we can also connect the second overload &lt;code>foo(int, float)&lt;/code>:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="c1">// This one only works because int can be coerced into float!&lt;/span> &lt;span class="n">s&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">connect&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">amb&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">sigs&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">Use&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">float&lt;/span>&lt;span class="o">&amp;gt;::&lt;/span>&lt;span class="n">overloadOf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">Ambiguous&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">foo&lt;/span>&lt;span class="p">));&lt;/span> &lt;span class="n">s&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">12&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">34&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="cm">/* Prints:&lt;/span> &lt;span class="cm">Ambiguous::foo(int, int)&lt;/span> &lt;span class="cm">Ambiguous::foo(int, float)&lt;/span> &lt;span class="cm">*/&lt;/span> &lt;/code>&lt;/pre>&lt;/div></content><category term="Projects"/><category term="sigs"/><category term="cpp"/><category term="cpp14"/></entry><entry><title>LLDB: Debugging Smart Pointers</title><link href="https://www.mortens.dev/blog/lldb-debugging-smart-pointers/" rel="alternate"/><published>2016-09-02T23:36:02+02:00</published><updated>2016-09-02T23:36:02+02:00</updated><author><name>Morten</name></author><id>tag:www.mortens.dev,2016-09-02:/blog/lldb-debugging-smart-pointers/</id><summary type="html">&lt;p>Debugging Smart Pointers with &lt;span class="caps">LLDB&lt;/span>&lt;/p></summary><content type="html">&lt;p>In recent years I have switched to using &lt;a href="http://lldb.llvm.org">&lt;span class="caps">LLDB&lt;/span>&lt;/a> (of the &lt;a href="http://llvm.org">&lt;span class="caps">LLVM&lt;/span>&lt;/a> project) as my primary debugger. In this post I’ll show how to debug instances of &lt;a href="http://en.cppreference.com/w/cpp/memory/shared_ptr">std::shared_ptr&lt;/a> and &lt;a href="http://en.cppreference.com/w/cpp/memory/unique_ptr">std::unique_ptr&lt;/a>, and what the differences are.&lt;/p> &lt;p>Create “pointers.cc” with the following contents:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="cp">#include&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="cpf">&amp;lt;memory&amp;gt;&lt;/span> &lt;span class="k">class&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nc">Test&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="n">Test&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">),&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">b&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">),&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">c&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">b&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">c&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">};&lt;/span> &lt;span class="kt">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="k">auto&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">sptr&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">make_shared&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Test&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">();&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="k">auto&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">uptr&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">make_unique&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Test&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">();&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Compile the program as &lt;code>pointers&lt;/code> with debugging symbols. The compiler must be &lt;a href="https://isocpp.org/wiki/faq/cpp14">C++14&lt;/a> compliant like &lt;a href="http://clang.llvm.org">Clang 3.4+&lt;/a> or &lt;a href="https://gcc.gnu.org">&lt;span class="caps">GCC&lt;/span> 4.9+&lt;/a> due to the usage of &lt;a href="http://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique">std::make_unique&lt;/a>. Let’s load it up with &lt;span class="caps">LLDB&lt;/span>:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>%&lt;span class="w"> &lt;/span>lldb&lt;span class="w"> &lt;/span>./pointers &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>target&lt;span class="w"> &lt;/span>create&lt;span class="w"> &lt;/span>&lt;span class="s2">"./pointers"&lt;/span> Current&lt;span class="w"> &lt;/span>executable&lt;span class="w"> &lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="w"> &lt;/span>to&lt;span class="w"> &lt;/span>&lt;span class="s1">'./pointers'&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>x86_64&lt;span class="o">)&lt;/span>. &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>b&lt;span class="w"> &lt;/span>&lt;span class="m">13&lt;/span> Breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>:&lt;span class="w"> &lt;/span>&lt;span class="nv">where&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>pointers&lt;span class="sb">`&lt;/span>main&lt;span class="w"> &lt;/span>+&lt;span class="w"> &lt;/span>&lt;span class="m">343&lt;/span>&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>pointers.cc:13,&lt;span class="w"> &lt;/span>&lt;span class="nv">address&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>0x0000000100001357 &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>r Process&lt;span class="w"> &lt;/span>&lt;span class="m">65102&lt;/span>&lt;span class="w"> &lt;/span>launched:&lt;span class="w"> &lt;/span>&lt;span class="s1">'./pointers'&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>x86_64&lt;span class="o">)&lt;/span> Process&lt;span class="w"> &lt;/span>&lt;span class="m">65102&lt;/span>&lt;span class="w"> &lt;/span>stopped *&lt;span class="w"> &lt;/span>thread&lt;span class="w"> &lt;/span>&lt;span class="c1">#1: tid = 0x18881d, 0x0000000100001357 pointers`main + 343 at pointers.cc:13, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1&lt;/span> &lt;span class="w"> &lt;/span>frame&lt;span class="w"> &lt;/span>&lt;span class="c1">#0: 0x0000000100001357 pointers`main + 343 at pointers.cc:13&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="m">10&lt;/span>&lt;span class="w"> &lt;/span>int&lt;span class="w"> &lt;/span>main&lt;span class="o">()&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="m">11&lt;/span>&lt;span class="w"> &lt;/span>auto&lt;span class="w"> &lt;/span>&lt;span class="nv">sptr&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>std::make_shared&amp;lt;Test&amp;gt;&lt;span class="o">()&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="m">12&lt;/span>&lt;span class="w"> &lt;/span>auto&lt;span class="w"> &lt;/span>&lt;span class="nv">uptr&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>std::make_unique&amp;lt;Test&amp;gt;&lt;span class="o">()&lt;/span>&lt;span class="p">;&lt;/span> -&amp;gt;&lt;span class="w"> &lt;/span>&lt;span class="m">13&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="m">14&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">}&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>We want to find out what the member variables of the two pointers are. If we just print the value it won’t help much:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>p&lt;span class="w"> &lt;/span>sptr &lt;span class="o">(&lt;/span>std::__1::shared_ptr&amp;lt;Test&amp;gt;&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>std::__1::shared_ptr&amp;lt;Test&amp;gt;::element_type&lt;span class="w"> &lt;/span>@&lt;span class="w"> &lt;/span>0x00000001001037f8&lt;span class="w"> &lt;/span>&lt;span class="nv">strong&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">weak&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nv">__ptr_&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>0x00000001001037f8 &lt;span class="o">}&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>We observe that &lt;code>sptr&lt;/code> has the member &lt;code>__ptr_&lt;/code> with address &lt;code>0x00000001001037f8&lt;/code>, which is how we access its members:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>p&lt;span class="w"> &lt;/span>sptr.__ptr_ &lt;span class="o">(&lt;/span>element_type&lt;span class="w"> &lt;/span>*&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">$1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>0x00000001001037f8 &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>p&lt;span class="w"> &lt;/span>*sptr.__ptr_ &lt;span class="o">(&lt;/span>std::__1::shared_ptr&amp;lt;Test&amp;gt;::element_type&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">$2&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="nv">a&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="nv">b&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">2&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="nv">c&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">3&lt;/span>&lt;span class="o">)&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>The &lt;code>::element_type&lt;/code> has type &lt;code>Test&lt;/code> so the following is equivalent:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>p&lt;span class="w"> &lt;/span>*&lt;span class="o">(&lt;/span>Test*&lt;span class="o">)&lt;/span>sptr.__ptr_ &lt;span class="o">(&lt;/span>Test&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">$3&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="nv">a&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="nv">b&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">2&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="nv">c&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">3&lt;/span>&lt;span class="o">)&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>The address can also be used directly:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>p&lt;span class="w"> &lt;/span>*&lt;span class="o">(&lt;/span>Test*&lt;span class="o">)&lt;/span>0x00000001001037f8 &lt;span class="o">(&lt;/span>Test&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">$4&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="nv">a&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="nv">b&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">2&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="nv">c&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">3&lt;/span>&lt;span class="o">)&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Now, &lt;code>uptr&lt;/code> is a little different:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>p&lt;span class="w"> &lt;/span>uptr &lt;span class="o">(&lt;/span>std::__1::unique_ptr&amp;lt;Test,&lt;span class="w"> &lt;/span>std::__1::default_delete&amp;lt;Test&amp;gt;&lt;span class="w"> &lt;/span>&amp;gt;&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">$5&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nv">__ptr_&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span> &lt;span class="w"> &lt;/span>std::__1::__libcpp_compressed_pair_imp&amp;lt;Test&lt;span class="w"> &lt;/span>*,&lt;span class="w"> &lt;/span>std::__1::default_delete&amp;lt;Test&amp;gt;,&lt;span class="w"> &lt;/span>&lt;span class="m">2&lt;/span>&amp;gt;&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nv">__first_&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>0x0000000100101490 &lt;span class="w"> &lt;/span>&lt;span class="o">}&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="o">}&lt;/span> &lt;span class="o">}&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>It also has the &lt;code>__ptr_&lt;/code> but it doesn’t point directly to its value like &lt;code>sptr.__ptr_&lt;/code> does:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>p&lt;span class="w"> &lt;/span>uptr.__ptr_ &lt;span class="o">(&lt;/span>std::__1::__compressed_pair&amp;lt;Test&lt;span class="w"> &lt;/span>*,&lt;span class="w"> &lt;/span>std::__1::default_delete&amp;lt;Test&amp;gt;&lt;span class="w"> &lt;/span>&amp;gt;&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">$6&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span> &lt;span class="w"> &lt;/span>std::__1::__libcpp_compressed_pair_imp&amp;lt;Test&lt;span class="w"> &lt;/span>*,&lt;span class="w"> &lt;/span>std::__1::default_delete&amp;lt;Test&amp;gt;,&lt;span class="w"> &lt;/span>&lt;span class="m">2&lt;/span>&amp;gt;&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nv">__first_&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>0x0000000100101490 &lt;span class="w"> &lt;/span>&lt;span class="o">}&lt;/span> &lt;span class="o">}&lt;/span> &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>p&lt;span class="w"> &lt;/span>*uptr.__ptr_ error:&lt;span class="w"> &lt;/span>indirection&lt;span class="w"> &lt;/span>requires&lt;span class="w"> &lt;/span>pointer&lt;span class="w"> &lt;/span>operand&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="s1">'std::__1::__compressed_pair&amp;lt;Test *, std::__1::default_delete&amp;lt;Test&amp;gt; &amp;gt;'&lt;/span>&lt;span class="w"> &lt;/span>invalid&lt;span class="o">)&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Instead we have to reference the &lt;code>__first_&lt;/code> member, but can still use the address directly, of course:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>p&lt;span class="w"> &lt;/span>uptr.__ptr_.__first_ &lt;span class="o">(&lt;/span>Test&lt;span class="w"> &lt;/span>*&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">$7&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>0x0000000100101490 &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>p&lt;span class="w"> &lt;/span>*uptr.__ptr_.__first_ &lt;span class="o">(&lt;/span>Test&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">$8&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="nv">a&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="nv">b&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">2&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="nv">c&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">3&lt;/span>&lt;span class="o">)&lt;/span> &lt;span class="o">(&lt;/span>lldb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>p&lt;span class="w"> &lt;/span>*&lt;span class="o">(&lt;/span>Test*&lt;span class="o">)&lt;/span>0x0000000100101490 &lt;span class="o">(&lt;/span>Test&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">$9&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="nv">a&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="nv">b&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">2&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="nv">c&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">3&lt;/span>&lt;span class="o">)&lt;/span> &lt;/code>&lt;/pre>&lt;/div></content><category term="Debugging"/><category term="lldb"/><category term="debugging"/><category term="cpp"/><category term="cpp14"/><category term="clang"/><category term="gcc"/></entry><entry><title>Proper usage of QThread</title><link href="https://www.mortens.dev/blog/proper-usage-of-qthread/" rel="alternate"/><published>2013-03-06T16:13:10+02:00</published><updated>2013-03-06T16:13:10+02:00</updated><author><name>Morten</name></author><id>tag:www.mortens.dev,2013-03-06:/blog/proper-usage-of-qthread/</id><summary type="html">&lt;p>Proper usage of&amp;nbsp;QThread&lt;/p></summary><content type="html">&lt;p>&lt;strong>QThread&lt;/strong> should be viewed as the mediator with the &lt;span class="caps">OS&lt;/span> of the new thread and not as being the actual thread itself!&lt;/p> &lt;ul> &lt;li>Don’t subclass QThread only to extend the actual thread implementation which is hardly ever necessary.&lt;/li> &lt;li>Create a QObject custom class that does what should be done and has a public slot for processing.&lt;/li> &lt;li>Create a QThread and custom instance, call &lt;code>custom-&amp;gt;moveToThread(thread)&lt;/code>.&lt;/li> &lt;li>Connect signals from thread to custom instance, started/finished along with &lt;code>deleteLater()&lt;/code> invocations.&lt;/li> &lt;li>Finally call &lt;code>thread-&amp;gt;start()&lt;/code>.&lt;/li> &lt;/ul> &lt;p>&lt;span class="caps">AND&lt;/span> very important to not allocate on heap in the constructor of the custom class only on the stack. Objects can be allocated on the heap when the public slot is called, and thus the context is the new thread and not the “home thread”.&lt;/p></content><category term="Development"/><category term="qt"/><category term="concurrency"/><category term="cpp"/></entry><entry><title>Unleashing the Power of GDB (part 2)</title><link href="https://www.mortens.dev/blog/unleashing-the-power-of-gdb-part-2/" rel="alternate"/><published>2013-03-03T14:27:49+02:00</published><updated>2013-03-03T14:27:49+02:00</updated><author><name>Morten</name></author><id>tag:www.mortens.dev,2013-03-03:/blog/unleashing-the-power-of-gdb-part-2/</id><summary type="html">&lt;p>Unleashing the Power of &lt;span class="caps">GDB&lt;/span> to debug programs (part&amp;nbsp;2)&lt;/p></summary><content type="html">&lt;p>The &lt;span class="caps">GNU&lt;/span> Debugger&lt;a href="http://sourceware.org/gdb/current/onlinedocs/gdb/index.html#Top" target="_blank">&lt;sup>[1]&lt;/sup>&lt;/a> is my favorite debugging tool and I personally think it’s essential for any *nix developer to know how to use it properly if you’re working with C/C++, D, Go, Obj-C, Fortran, Pascal, Modula-2 or Ada&lt;a href="http://sourceware.org/gdb/current/onlinedocs/gdb/Supported-Languages.html#Supported-Languages">&lt;sup>[2]&lt;/sup>&lt;/a>.&lt;/p> &lt;p>This is the second part of &lt;em>Unleashing the power of &lt;span class="caps">GDB&lt;/span>&lt;/em>. It is recommended reading the &lt;a href="https://www.mortens.dev/blog/unleashing-the-power-of-gdb/">first part&lt;/a> before proceeding. First section is about integrating &lt;span class="caps">GDB&lt;/span> with Emacs, the second is about how to debug errors as they occur with common cases and the last section is about debugging without any debug symbols.&lt;/p> &lt;h4>1. Integration with Emacs&lt;/h4> &lt;p>&lt;span class="caps">GDB&lt;/span> is taken to the next level when used together with my favorite editor Emacs&lt;a href="http://www.gnu.org/software/emacs/" target="_blank">&lt;sup>[3]&lt;/sup>&lt;/a> because it adds autocompletion of commands and arguments, and easy stepping in the command history - saves a lot of time. But perhaps even more important: If the program is compiled with debugging symbols it will also load and show the source code. Thus hitting breakpoints and stepping through the program will show the placement in the source code as well.&lt;/p> &lt;p>Let’s take the first snippet of code from the previous article:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="cp">#include&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="cpf">&amp;lt;string&amp;gt;&lt;/span> &lt;span class="cp">#include&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span> &lt;span class="k">using&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">namespace&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nn">std&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="kt">void&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">func2&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">string&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">str&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="n">cout&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"func2 says: "&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">str&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="kt">void&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">func1&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="n">string&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">str&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"$"&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="n">func2&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">str&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="kt">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">main&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">argc&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">char&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">**&lt;/span>&lt;span class="n">argv&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="n">func1&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">5&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>And compile it:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>g++&lt;span class="w"> &lt;/span>-g&lt;span class="w"> &lt;/span>-o&lt;span class="w"> &lt;/span>&lt;span class="nb">test&lt;/span>&lt;span class="w"> &lt;/span>test.cpp &lt;/code>&lt;/pre>&lt;/div> &lt;p>Open Emacs if you didn’t use it already to save the file. Hit &lt;code>M-x gdb &amp;lt;RET&amp;gt;&lt;/code> to fire up the &lt;span class="caps">GDB&lt;/span> mode. I recommend using the most recent &lt;span class="caps">GDB&lt;/span> (7.5+) together with Emacs because it works better. &lt;/p> &lt;p>Give the following arguments to the &lt;span class="caps">GDB&lt;/span> mode:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>gdb&lt;span class="w"> &lt;/span>-i&lt;span class="o">=&lt;/span>mi&lt;span class="w"> &lt;/span>/path/to/program &lt;/code>&lt;/pre>&lt;/div> &lt;p>The current working directory is the directory of the file being edited when going into &lt;span class="caps">GDB&lt;/span> mode. So if editing &lt;code>/tmp/test.cpp&lt;/code> then &lt;code>gdb -i=mi test&lt;/code> will run &lt;code>/tmp/test&lt;/code>.&lt;/p> &lt;p>Note that the above assumed Emacs version 24. If you are running previous versions you can use this instead:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>gdb&lt;span class="w"> &lt;/span>--annotate&lt;span class="o">=&lt;/span>&lt;span class="m">3&lt;/span>&lt;span class="w"> &lt;/span>/path/to/program &lt;/code>&lt;/pre>&lt;/div> &lt;p>Thanks to &lt;em>Paw&lt;/em> for pointing that out.&lt;/p> &lt;p>Let’s break at the main function:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>b&lt;span class="w"> &lt;/span>main &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>r &lt;/code>&lt;/pre>&lt;/div> &lt;p>If you see the following error while running on &lt;span class="caps">OSX&lt;/span>:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>Starting&lt;span class="w"> &lt;/span>program:&lt;span class="w"> &lt;/span>/x/y/foo Unable&lt;span class="w"> &lt;/span>to&lt;span class="w"> &lt;/span>find&lt;span class="w"> &lt;/span>Mach&lt;span class="w"> &lt;/span>task&lt;span class="w"> &lt;/span>port&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>process-id&lt;span class="w"> &lt;/span>&lt;span class="m">76352&lt;/span>:&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>os/kern&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>failure&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>0x5&lt;span class="o">)&lt;/span>. &lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>please&lt;span class="w"> &lt;/span>check&lt;span class="w"> &lt;/span>gdb&lt;span class="w"> &lt;/span>is&lt;span class="w"> &lt;/span>codesigned&lt;span class="w"> &lt;/span>-&lt;span class="w"> &lt;/span>see&lt;span class="w"> &lt;/span>taskgated&lt;span class="o">(&lt;/span>&lt;span class="m">8&lt;/span>&lt;span class="o">))&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Then you might want to follow &lt;a href="http://sourceware.org/gdb/wiki/BuildingOnDarwin" target="_blank">these instructions&lt;/a> to give &lt;span class="caps">GDB&lt;/span> the necessary rights for debugging (you have to sign the &lt;span class="caps">GDB&lt;/span> executable). &lt;/p> &lt;p>This is how it looks with my Emacs configuration: &lt;a href="https://www.mortens.dev/images/gdb-emacs.png">&lt;img alt="GDB in Emacs" class="img-fluid" src="https://www.mortens.dev/images/gdb-emacs.png"/>&lt;/a>&lt;/p> &lt;h4>2. Inspecting actual bugs&lt;/h4> &lt;p>Now I’ll show some typical programming bugs and how to spot and fix them using &lt;span class="caps">GDB&lt;/span>. Suppose you have written a program but you get the following error when running it:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>./prog1 segmentation&lt;span class="w"> &lt;/span>fault&lt;span class="w"> &lt;/span>./prog1 &lt;/code>&lt;/pre>&lt;/div> &lt;p>Note that the error might be displayed in various of ways. A segmentation fault happens but you will be wondering what caused it so we fire up &lt;span class="caps">GDB&lt;/span>:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>gdb&lt;span class="w"> &lt;/span>./prog1 Reading&lt;span class="w"> &lt;/span>symbols&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>shared&lt;span class="w"> &lt;/span>libraries&lt;span class="w"> &lt;/span>...&lt;span class="w"> &lt;/span>&lt;span class="k">done&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>r Starting&lt;span class="w"> &lt;/span>program:&lt;span class="w"> &lt;/span>/private/tmp/prog1&lt;span class="w"> &lt;/span> Reading&lt;span class="w"> &lt;/span>symbols&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>shared&lt;span class="w"> &lt;/span>libraries&lt;span class="w"> &lt;/span>++.............................&lt;span class="w"> &lt;/span>&lt;span class="k">done&lt;/span> Program&lt;span class="w"> &lt;/span>received&lt;span class="w"> &lt;/span>signal&lt;span class="w"> &lt;/span>EXC_BAD_ACCESS,&lt;span class="w"> &lt;/span>Could&lt;span class="w"> &lt;/span>not&lt;span class="w"> &lt;/span>access&lt;span class="w"> &lt;/span>memory. Reason:&lt;span class="w"> &lt;/span>KERN_INVALID_ADDRESS&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>address:&lt;span class="w"> &lt;/span>0x0000000000000000 0x0000000100000f27&lt;span class="w"> &lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="w"> &lt;/span>main&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="nv">argc&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="m">1&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="nv">argv&lt;/span>&lt;span class="o">=&lt;/span>0x7fff5fbffa78&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>prog1.cpp:3 &lt;span class="m">3&lt;/span>&lt;span class="w"> &lt;/span>*ptr&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>p&lt;span class="w"> &lt;/span>ptr &lt;span class="nv">$1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>int&lt;span class="w"> &lt;/span>*&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>0x0 &lt;/code>&lt;/pre>&lt;/div> &lt;p>First it is observed that we are denied access to some memory at address &lt;code>0x0..0&lt;/code> and that it’s the line &lt;code>*ptr = 1&lt;/code> (prog1.cpp:3) that caused it. So we already know from the error message that &lt;code>ptr&lt;/code> must then be a null-pointer but we double-check by inspecting it with &lt;code>p ptr&lt;/code>.&lt;/p> &lt;p>Another example might be the following:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>./prog2 prog2&lt;span class="o">(&lt;/span>&lt;span class="m">12673&lt;/span>&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>malloc:&lt;span class="w"> &lt;/span>***&lt;span class="w"> &lt;/span>error&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>object&lt;span class="w"> &lt;/span>0x7ffd08c03930:&lt;span class="w"> &lt;/span>pointer&lt;span class="w"> &lt;/span>being&lt;span class="w"> &lt;/span>freed&lt;span class="w"> &lt;/span>was&lt;span class="w"> &lt;/span>not&lt;span class="w"> &lt;/span>allocated ***&lt;span class="w"> &lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="w"> &lt;/span>a&lt;span class="w"> &lt;/span>breakpoint&lt;span class="w"> &lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="w"> &lt;/span>malloc_error_break&lt;span class="w"> &lt;/span>to&lt;span class="w"> &lt;/span>debug abort&lt;span class="w"> &lt;/span>./prog2 &lt;/code>&lt;/pre>&lt;/div> &lt;p>From the error message we now know that some unallocated memory was freed. It also gives a tip on where to start debugging, so let’s do just that:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>gdb&lt;span class="w"> &lt;/span>./prog2 Reading&lt;span class="w"> &lt;/span>symbols&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>shared&lt;span class="w"> &lt;/span>libraries&lt;span class="w"> &lt;/span>...&lt;span class="w"> &lt;/span>&lt;span class="k">done&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>b&lt;span class="w"> &lt;/span>malloc_error_break Function&lt;span class="w"> &lt;/span>&lt;span class="s2">"malloc_error_break"&lt;/span>&lt;span class="w"> &lt;/span>not&lt;span class="w"> &lt;/span>defined. Make&lt;span class="w"> &lt;/span>breakpoint&lt;span class="w"> &lt;/span>pending&lt;span class="w"> &lt;/span>on&lt;span class="w"> &lt;/span>future&lt;span class="w"> &lt;/span>shared&lt;span class="w"> &lt;/span>library&lt;span class="w"> &lt;/span>load?&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>y&lt;span class="w"> &lt;/span>or&lt;span class="w"> &lt;/span>&lt;span class="o">[&lt;/span>n&lt;span class="o">])&lt;/span>&lt;span class="w"> &lt;/span>y Breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>malloc_error_break&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>pending. &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>r Starting&lt;span class="w"> &lt;/span>program:&lt;span class="w"> &lt;/span>/private/tmp/prog2&lt;span class="w"> &lt;/span> Reading&lt;span class="w"> &lt;/span>symbols&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>shared&lt;span class="w"> &lt;/span>libraries&lt;span class="w"> &lt;/span>++.............................&lt;span class="w"> &lt;/span>&lt;span class="k">done&lt;/span> Breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>0x7fff9439b558 Pending&lt;span class="w"> &lt;/span>breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="w"> &lt;/span>-&lt;span class="w"> &lt;/span>&lt;span class="s2">"malloc_error_break"&lt;/span>&lt;span class="w"> &lt;/span>resolved prog2&lt;span class="o">(&lt;/span>&lt;span class="m">12693&lt;/span>&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>malloc:&lt;span class="w"> &lt;/span>***&lt;span class="w"> &lt;/span>error&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>object&lt;span class="w"> &lt;/span>0x100103920:&lt;span class="w"> &lt;/span>pointer&lt;span class="w"> &lt;/span>being&lt;span class="w"> &lt;/span>freed&lt;span class="w"> &lt;/span>was&lt;span class="w"> &lt;/span>not&lt;span class="w"> &lt;/span>allocated ***&lt;span class="w"> &lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="w"> &lt;/span>a&lt;span class="w"> &lt;/span>breakpoint&lt;span class="w"> &lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="w"> &lt;/span>malloc_error_break&lt;span class="w"> &lt;/span>to&lt;span class="w"> &lt;/span>debug Breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>,&lt;span class="w"> &lt;/span>0x00007fff9439b558&lt;span class="w"> &lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="w"> &lt;/span>malloc_error_break&lt;span class="w"> &lt;/span>&lt;span class="o">()&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>bt &lt;span class="c1">#0 0x00007fff9439b558 in malloc_error_break ()&lt;/span> &lt;span class="c1">#1 0x00007fff9439c912 in free ()&lt;/span> &lt;span class="c1">#2 0x0000000100000f03 in main (argc=1, argv=0x7fff5fbffa78) at prog2.cpp:4&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>f&lt;span class="w"> &lt;/span>&lt;span class="m">2&lt;/span> &lt;span class="c1">#2 0x0000000100000f03 in main (argc=1, argv=0x7fff5fbffa78) at prog2.cpp:4&lt;/span> &lt;span class="m">4&lt;/span>&lt;span class="w"> &lt;/span>delete&lt;span class="o">[]&lt;/span>&lt;span class="w"> &lt;/span>txt&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>l &lt;span class="m">1&lt;/span>&lt;span class="w"> &lt;/span>int&lt;span class="w"> &lt;/span>main&lt;span class="o">(&lt;/span>int&lt;span class="w"> &lt;/span>argc,&lt;span class="w"> &lt;/span>char&lt;span class="w"> &lt;/span>**argv&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span> &lt;span class="m">2&lt;/span>&lt;span class="w"> &lt;/span>char&lt;span class="w"> &lt;/span>*txt&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>new&lt;span class="w"> &lt;/span>char&lt;span class="o">[&lt;/span>&lt;span class="m">128&lt;/span>&lt;span class="o">]&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="m">3&lt;/span>&lt;span class="w"> &lt;/span>delete&lt;span class="o">[]&lt;/span>&lt;span class="w"> &lt;/span>txt&lt;span class="p">;&lt;/span> &lt;span class="m">4&lt;/span>&lt;span class="w"> &lt;/span>delete&lt;span class="o">[]&lt;/span>&lt;span class="w"> &lt;/span>txt&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span> &lt;span class="m">5&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="m">6&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">}&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>So we set a pending breakpoint, start the program, find the frame and observe the double &lt;code>delete[]&lt;/code> on line 3 and 4.&lt;/p> &lt;p>A third possibility is a floating point exception:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>./prog3 floating&lt;span class="w"> &lt;/span>point&lt;span class="w"> &lt;/span>exception&lt;span class="w"> &lt;/span>./prog3 &lt;/code>&lt;/pre>&lt;/div> &lt;p>Using &lt;span class="caps">GDB&lt;/span> we immediately see the problem:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>gdb&lt;span class="w"> &lt;/span>./prog3 Reading&lt;span class="w"> &lt;/span>symbols&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>shared&lt;span class="w"> &lt;/span>libraries&lt;span class="w"> &lt;/span>...&lt;span class="w"> &lt;/span>&lt;span class="k">done&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>r Starting&lt;span class="w"> &lt;/span>program:&lt;span class="w"> &lt;/span>/private/tmp/prog3&lt;span class="w"> &lt;/span> Reading&lt;span class="w"> &lt;/span>symbols&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>shared&lt;span class="w"> &lt;/span>libraries&lt;span class="w"> &lt;/span>++.............................&lt;span class="w"> &lt;/span>&lt;span class="k">done&lt;/span> Program&lt;span class="w"> &lt;/span>received&lt;span class="w"> &lt;/span>signal&lt;span class="w"> &lt;/span>EXC_ARITHMETIC,&lt;span class="w"> &lt;/span>Arithmetic&lt;span class="w"> &lt;/span>exception. 0x0000000100000f38&lt;span class="w"> &lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="w"> &lt;/span>main&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="nv">argc&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="m">1&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="nv">argv&lt;/span>&lt;span class="o">=&lt;/span>0x7fff5fbffa78&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>prog3.cpp:3 &lt;span class="m">3&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>a&lt;span class="w"> &lt;/span>/&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Which in this case is a division-by-zero error. Pay attention to the warnings your compiler issues to avoid these things. It might have looked like this: &lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>prog3.cpp:3:&lt;span class="w"> &lt;/span>warning:&lt;span class="w"> &lt;/span>division&lt;span class="w"> &lt;/span>by&lt;span class="w"> &lt;/span>zero&lt;span class="w"> &lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="w"> &lt;/span>‘a&lt;span class="w"> &lt;/span>/&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span>’ &lt;/code>&lt;/pre>&lt;/div> &lt;p>Note that these are just examples of runtime errors. A lot more exist that I have not covered here.&lt;/p> &lt;h4>3. Debugging with no debugging symbols&lt;/h4> &lt;p>Sometimes the program you are debugging has no symbol table and you still have to locate the problem. It might be that you are debugging a third party binary so you don’t have access to the source code. &lt;b>This section will be a bit advanced.&lt;/b>&lt;/p> &lt;p>Let’s start with the first problematic program from last section: &lt;code>prog1&lt;/code>. This is what &lt;span class="caps">GDB&lt;/span> tells us with no debug symbols:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>gdb&lt;span class="w"> &lt;/span>./prog1 Reading&lt;span class="w"> &lt;/span>symbols&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>shared&lt;span class="w"> &lt;/span>libraries&lt;span class="w"> &lt;/span>...&lt;span class="w"> &lt;/span>&lt;span class="k">done&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>r Starting&lt;span class="w"> &lt;/span>program:&lt;span class="w"> &lt;/span>/private/tmp/prog1&lt;span class="w"> &lt;/span> Reading&lt;span class="w"> &lt;/span>symbols&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>shared&lt;span class="w"> &lt;/span>libraries&lt;span class="w"> &lt;/span>++.............................&lt;span class="w"> &lt;/span>&lt;span class="k">done&lt;/span> Program&lt;span class="w"> &lt;/span>received&lt;span class="w"> &lt;/span>signal&lt;span class="w"> &lt;/span>EXC_BAD_ACCESS,&lt;span class="w"> &lt;/span>Could&lt;span class="w"> &lt;/span>not&lt;span class="w"> &lt;/span>access&lt;span class="w"> &lt;/span>memory. Reason:&lt;span class="w"> &lt;/span>KERN_INVALID_ADDRESS&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>address:&lt;span class="w"> &lt;/span>0x0000000000000000 0x0000000100000f27&lt;span class="w"> &lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="w"> &lt;/span>main&lt;span class="w"> &lt;/span>&lt;span class="o">()&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Unfortunately we cannot inspect the source code but instead we can inspect the machine code by disassembling a section of memory into symbolic language:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>disas Dump&lt;span class="w"> &lt;/span>of&lt;span class="w"> &lt;/span>assembler&lt;span class="w"> &lt;/span>code&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">function&lt;/span>&lt;span class="w"> &lt;/span>main: 0x0000000100000f10&lt;span class="w"> &lt;/span>&amp;lt;main+0&amp;gt;:&lt;span class="w"> &lt;/span>push&lt;span class="w"> &lt;/span>%rbp 0x0000000100000f11&lt;span class="w"> &lt;/span>&amp;lt;main+1&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>%rsp,%rbp 0x0000000100000f14&lt;span class="w"> &lt;/span>&amp;lt;main+4&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>%edi,-0x4&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> 0x0000000100000f17&lt;span class="w"> &lt;/span>&amp;lt;main+7&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>%rsi,-0x10&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> 0x0000000100000f1b&lt;span class="w"> &lt;/span>&amp;lt;main+11&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x0,-0x20&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> 0x0000000100000f23&lt;span class="w"> &lt;/span>&amp;lt;main+19&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>-0x20&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>,%rax 0x0000000100000f27&lt;span class="w"> &lt;/span>&amp;lt;main+23&amp;gt;:&lt;span class="w"> &lt;/span>movl&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x1,&lt;span class="o">(&lt;/span>%rax&lt;span class="o">)&lt;/span> 0x0000000100000f2d&lt;span class="w"> &lt;/span>&amp;lt;main+29&amp;gt;:&lt;span class="w"> &lt;/span>movl&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x0,-0x18&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> 0x0000000100000f34&lt;span class="w"> &lt;/span>&amp;lt;main+36&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>-0x18&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>,%eax 0x0000000100000f37&lt;span class="w"> &lt;/span>&amp;lt;main+39&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>%eax,-0x14&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> 0x0000000100000f3a&lt;span class="w"> &lt;/span>&amp;lt;main+42&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>-0x14&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>,%eax 0x0000000100000f3d&lt;span class="w"> &lt;/span>&amp;lt;main+45&amp;gt;:&lt;span class="w"> &lt;/span>pop&lt;span class="w"> &lt;/span>%rbp 0x0000000100000f3e&lt;span class="w"> &lt;/span>&amp;lt;main+46&amp;gt;:&lt;span class="w"> &lt;/span>retq&lt;span class="w"> &lt;/span> End&lt;span class="w"> &lt;/span>of&lt;span class="w"> &lt;/span>assembler&lt;span class="w"> &lt;/span>dump. &lt;/code>&lt;/pre>&lt;/div> &lt;p>Let us focus around the reported address &lt;code>0x0000000100000f27&lt;/code>:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>disas&lt;span class="w"> &lt;/span>0x0000000100000f1b&lt;span class="w"> &lt;/span>0x0000000100000f2d Dump&lt;span class="w"> &lt;/span>of&lt;span class="w"> &lt;/span>assembler&lt;span class="w"> &lt;/span>code&lt;span class="w"> &lt;/span>from&lt;span class="w"> &lt;/span>0x100000f1b&lt;span class="w"> &lt;/span>to&lt;span class="w"> &lt;/span>0x100000f2d: 0x0000000100000f1b&lt;span class="w"> &lt;/span>&amp;lt;main+11&amp;gt;:&lt;span class="w"> &lt;/span>movq&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x0,-0x20&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> 0x0000000100000f23&lt;span class="w"> &lt;/span>&amp;lt;main+19&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>-0x20&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>,%rax 0x0000000100000f27&lt;span class="w"> &lt;/span>&amp;lt;main+23&amp;gt;:&lt;span class="w"> &lt;/span>movl&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x1,&lt;span class="o">(&lt;/span>%rax&lt;span class="o">)&lt;/span> End&lt;span class="w"> &lt;/span>of&lt;span class="w"> &lt;/span>assembler&lt;span class="w"> &lt;/span>dump. &lt;span class="sb">````&lt;/span> On&lt;span class="w"> &lt;/span>the&lt;span class="w"> &lt;/span>third&lt;span class="w"> &lt;/span>line&lt;span class="w"> &lt;/span>the&lt;span class="w"> &lt;/span>pointer&lt;span class="w"> &lt;/span>is&lt;span class="w"> &lt;/span>accessed&lt;span class="w"> &lt;/span>and&lt;span class="w"> &lt;/span>&lt;span class="sb">`&lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="sb">`&lt;/span>&lt;span class="w"> &lt;/span>is&lt;span class="w"> &lt;/span>attempted&lt;span class="w"> &lt;/span>saved&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>the&lt;span class="w"> &lt;/span>location.&lt;span class="w"> &lt;/span>So&lt;span class="w"> &lt;/span>this&lt;span class="w"> &lt;/span>information&lt;span class="w"> &lt;/span>can&lt;span class="w"> &lt;/span>be&lt;span class="w"> &lt;/span>given&lt;span class="w"> &lt;/span>to&lt;span class="w"> &lt;/span>the&lt;span class="w"> &lt;/span>third&lt;span class="w"> &lt;/span>party.&lt;span class="w"> &lt;/span>However,&lt;span class="w"> &lt;/span>we&lt;span class="w"> &lt;/span>actually&lt;span class="w"> &lt;/span>know&lt;span class="w"> &lt;/span>the&lt;span class="w"> &lt;/span>&lt;span class="nb">source&lt;/span>&lt;span class="w"> &lt;/span>code&lt;span class="w"> &lt;/span>so&lt;span class="w"> &lt;/span>I&lt;span class="err">'&lt;/span>ll&lt;span class="w"> &lt;/span>show&lt;span class="w"> &lt;/span>the&lt;span class="w"> &lt;/span>parallels: &lt;span class="sb">```&lt;/span>shell movq&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x0,-0x20&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>int&lt;span class="w"> &lt;/span>*ptr&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span>&lt;span class="p">;&lt;/span> mov&lt;span class="w"> &lt;/span>-0x20&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>,%rax&lt;span class="w"> &lt;/span>//&lt;span class="w"> &lt;/span>Put&lt;span class="w"> &lt;/span>addr&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="w"> &lt;/span>%rax movl&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x1,&lt;span class="o">(&lt;/span>%rax&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>*ptr&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="p">;&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>On the first line &lt;code>0&lt;/code> is saved at &lt;code>-0x20(%rbp)&lt;/code>, line two moves the address (&lt;code>0&lt;/code>) to &lt;code>%rax&lt;/code> and the third line tries to dereference the null-pointer and assign &lt;code>1&lt;/code> to it.&lt;/p> &lt;p>Let us try to do the same thing for &lt;code>prog2&lt;/code>:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>gdb&lt;span class="w"> &lt;/span>./prog2 Reading&lt;span class="w"> &lt;/span>symbols&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>shared&lt;span class="w"> &lt;/span>libraries&lt;span class="w"> &lt;/span>...&lt;span class="w"> &lt;/span>&lt;span class="k">done&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>b&lt;span class="w"> &lt;/span>malloc_error_break Function&lt;span class="w"> &lt;/span>&lt;span class="s2">"malloc_error_break"&lt;/span>&lt;span class="w"> &lt;/span>not&lt;span class="w"> &lt;/span>defined. Make&lt;span class="w"> &lt;/span>breakpoint&lt;span class="w"> &lt;/span>pending&lt;span class="w"> &lt;/span>on&lt;span class="w"> &lt;/span>future&lt;span class="w"> &lt;/span>shared&lt;span class="w"> &lt;/span>library&lt;span class="w"> &lt;/span>load?&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>y&lt;span class="w"> &lt;/span>or&lt;span class="w"> &lt;/span>&lt;span class="o">[&lt;/span>n&lt;span class="o">])&lt;/span>&lt;span class="w"> &lt;/span>y Breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>malloc_error_break&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>pending. &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>r Starting&lt;span class="w"> &lt;/span>program:&lt;span class="w"> &lt;/span>/private/tmp/prog2&lt;span class="w"> &lt;/span> Reading&lt;span class="w"> &lt;/span>symbols&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>shared&lt;span class="w"> &lt;/span>libraries&lt;span class="w"> &lt;/span>++.............................&lt;span class="w"> &lt;/span>&lt;span class="k">done&lt;/span> Breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>0x7fff9439b558 Pending&lt;span class="w"> &lt;/span>breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="w"> &lt;/span>-&lt;span class="w"> &lt;/span>&lt;span class="s2">"malloc_error_break"&lt;/span>&lt;span class="w"> &lt;/span>resolved prog2&lt;span class="o">(&lt;/span>&lt;span class="m">15026&lt;/span>&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>malloc:&lt;span class="w"> &lt;/span>***&lt;span class="w"> &lt;/span>error&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>object&lt;span class="w"> &lt;/span>0x100103920:&lt;span class="w"> &lt;/span>pointer&lt;span class="w"> &lt;/span>being&lt;span class="w"> &lt;/span>freed&lt;span class="w"> &lt;/span>was&lt;span class="w"> &lt;/span>not&lt;span class="w"> &lt;/span>allocated ***&lt;span class="w"> &lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="w"> &lt;/span>a&lt;span class="w"> &lt;/span>breakpoint&lt;span class="w"> &lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="w"> &lt;/span>malloc_error_break&lt;span class="w"> &lt;/span>to&lt;span class="w"> &lt;/span>debug Breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>,&lt;span class="w"> &lt;/span>0x00007fff9439b558&lt;span class="w"> &lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="w"> &lt;/span>malloc_error_break&lt;span class="w"> &lt;/span>&lt;span class="o">()&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>bt &lt;span class="c1">#0 0x00007fff9439b558 in malloc_error_break ()&lt;/span> &lt;span class="c1">#1 0x00007fff9439c912 in free ()&lt;/span> &lt;span class="c1">#2 0x0000000100000f03 in main ()&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>The exception arises on address &lt;code>0x0000000100000f03&lt;/code>, so again we have to disassemble to make sense of it:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>disas Dump&lt;span class="w"> &lt;/span>of&lt;span class="w"> &lt;/span>assembler&lt;span class="w"> &lt;/span>code&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">function&lt;/span>&lt;span class="w"> &lt;/span>main: 0x0000000100000eb0&lt;span class="w"> &lt;/span>&amp;lt;main+0&amp;gt;:&lt;span class="w"> &lt;/span>push&lt;span class="w"> &lt;/span>%rbp 0x0000000100000eb1&lt;span class="w"> &lt;/span>&amp;lt;main+1&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>%rsp,%rbp 0x0000000100000eb4&lt;span class="w"> &lt;/span>&amp;lt;main+4&amp;gt;:&lt;span class="w"> &lt;/span>sub&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x20,%rsp 0x0000000100000eb8&lt;span class="w"> &lt;/span>&amp;lt;main+8&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>%edi,%eax 0x0000000100000eba&lt;span class="w"> &lt;/span>&amp;lt;main+10&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>%eax,-0x4&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> 0x0000000100000ebd&lt;span class="w"> &lt;/span>&amp;lt;main+13&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>%rsi,-0x10&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> 0x0000000100000ec1&lt;span class="w"> &lt;/span>&amp;lt;main+17&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x80,%rax 0x0000000100000ecb&lt;span class="w"> &lt;/span>&amp;lt;main+27&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>%rax,%rdi 0x0000000100000ece&lt;span class="w"> &lt;/span>&amp;lt;main+30&amp;gt;:&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x100000f20&lt;span class="w"> &lt;/span>&amp;lt;dyld_stub__Znam&amp;gt; 0x0000000100000ed3&lt;span class="w"> &lt;/span>&amp;lt;main+35&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>%rax,-0x20&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> 0x0000000100000ed7&lt;span class="w"> &lt;/span>&amp;lt;main+39&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>-0x20&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>,%rax 0x0000000100000edb&lt;span class="w"> &lt;/span>&amp;lt;main+43&amp;gt;:&lt;span class="w"> &lt;/span>cmp&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x0,%rax 0x0000000100000edf&lt;span class="w"> &lt;/span>&amp;lt;main+47&amp;gt;:&lt;span class="w"> &lt;/span>je&lt;span class="w"> &lt;/span>0x100000eed&lt;span class="w"> &lt;/span>&amp;lt;main+61&amp;gt; 0x0000000100000ee1&lt;span class="w"> &lt;/span>&amp;lt;main+49&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>-0x20&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>,%rax 0x0000000100000ee5&lt;span class="w"> &lt;/span>&amp;lt;main+53&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>%rax,%rdi 0x0000000100000ee8&lt;span class="w"> &lt;/span>&amp;lt;main+56&amp;gt;:&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x100000f1a&lt;span class="w"> &lt;/span>&amp;lt;dyld_stub__ZdaPv&amp;gt; 0x0000000100000eed&lt;span class="w"> &lt;/span>&amp;lt;main+61&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>-0x20&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>,%rax 0x0000000100000ef1&lt;span class="w"> &lt;/span>&amp;lt;main+65&amp;gt;:&lt;span class="w"> &lt;/span>cmp&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x0,%rax 0x0000000100000ef5&lt;span class="w"> &lt;/span>&amp;lt;main+69&amp;gt;:&lt;span class="w"> &lt;/span>je&lt;span class="w"> &lt;/span>0x100000f03&lt;span class="w"> &lt;/span>&amp;lt;main+83&amp;gt; 0x0000000100000ef7&lt;span class="w"> &lt;/span>&amp;lt;main+71&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>-0x20&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>,%rax 0x0000000100000efb&lt;span class="w"> &lt;/span>&amp;lt;main+75&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>%rax,%rdi 0x0000000100000efe&lt;span class="w"> &lt;/span>&amp;lt;main+78&amp;gt;:&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x100000f1a&lt;span class="w"> &lt;/span>&amp;lt;dyld_stub__ZdaPv&amp;gt; 0x0000000100000f03&lt;span class="w"> &lt;/span>&amp;lt;main+83&amp;gt;:&lt;span class="w"> &lt;/span>movl&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x0,-0x18&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> 0x0000000100000f0a&lt;span class="w"> &lt;/span>&amp;lt;main+90&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>-0x18&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>,%eax 0x0000000100000f0d&lt;span class="w"> &lt;/span>&amp;lt;main+93&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>%eax,-0x14&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> 0x0000000100000f10&lt;span class="w"> &lt;/span>&amp;lt;main+96&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>-0x14&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>,%eax 0x0000000100000f13&lt;span class="w"> &lt;/span>&amp;lt;main+99&amp;gt;:&lt;span class="w"> &lt;/span>add&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>x20,%rsp 0x0000000100000f17&lt;span class="w"> &lt;/span>&amp;lt;main+103&amp;gt;:&lt;span class="w"> &lt;/span>pop&lt;span class="w"> &lt;/span>%rbp 0x0000000100000f18&lt;span class="w"> &lt;/span>&amp;lt;main+104&amp;gt;:&lt;span class="w"> &lt;/span>retq&lt;span class="w"> &lt;/span> End&lt;span class="w"> &lt;/span>of&lt;span class="w"> &lt;/span>assembler&lt;span class="w"> &lt;/span>dump. &lt;/code>&lt;/pre>&lt;/div> &lt;p>This is a large chunk but I will point out the important little details. The following line calls &lt;code>new[]&lt;/code>:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>0x0000000100000ece&lt;span class="w"> &lt;/span>&amp;lt;main+30&amp;gt;:&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x100000f20&lt;span class="w"> &lt;/span>&amp;lt;dyld_stub__Znam&amp;gt; &lt;/code>&lt;/pre>&lt;/div> &lt;p>The reason is that &lt;code>_Znam&lt;/code> actually means &lt;code>operator new[](unsigned long)&lt;/code>. &lt;em>You can use the tool &lt;code>c++filt&lt;/code> or &lt;a href="http://slush.warosu.org/c++filtjs/" target="_blank">this site&lt;/a> to do demangle symbols.&lt;/em>&lt;/p> &lt;p>And here are the double deletions:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>0x0000000100000ee8&lt;span class="w"> &lt;/span>&amp;lt;main+56&amp;gt;:&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x100000f1a&lt;span class="w"> &lt;/span>&amp;lt;dyld_stub__ZdaPv&amp;gt; 0x0000000100000efe&lt;span class="w"> &lt;/span>&amp;lt;main+78&amp;gt;:&lt;span class="w"> &lt;/span>callq&lt;span class="w"> &lt;/span>0x100000f1a&lt;span class="w"> &lt;/span>&amp;lt;dyld_stub__ZdaPv&amp;gt; &lt;/code>&lt;/pre>&lt;/div> &lt;p>&lt;code>_ZdaPv&lt;/code> means &lt;code>operator delete[](void*)&lt;/code>. In both cases they are passed the same address by the following instructions:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>0x0000000100000ee1&lt;span class="w"> &lt;/span>&amp;lt;main+49&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>-0x20&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>,%rax 0x0000000100000ee5&lt;span class="w"> &lt;/span>&amp;lt;main+53&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>%rax,%rdi &lt;/code>&lt;/pre>&lt;/div> &lt;p>And here as well:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>0x0000000100000ef7&lt;span class="w"> &lt;/span>&amp;lt;main+71&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>-0x20&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>,%rax 0x0000000100000efb&lt;span class="w"> &lt;/span>&amp;lt;main+75&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>%rax,%rdi &lt;/code>&lt;/pre>&lt;/div> &lt;p>The third program with the floating-point exception is debugged in the following way without symbols:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>gdb&lt;span class="w"> &lt;/span>./prog3 Reading&lt;span class="w"> &lt;/span>symbols&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>shared&lt;span class="w"> &lt;/span>libraries&lt;span class="w"> &lt;/span>...&lt;span class="w"> &lt;/span>&lt;span class="k">done&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>r Starting&lt;span class="w"> &lt;/span>program:&lt;span class="w"> &lt;/span>/private/tmp/prog3&lt;span class="w"> &lt;/span> Reading&lt;span class="w"> &lt;/span>symbols&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>shared&lt;span class="w"> &lt;/span>libraries&lt;span class="w"> &lt;/span>++.............................&lt;span class="w"> &lt;/span>&lt;span class="k">done&lt;/span> Program&lt;span class="w"> &lt;/span>received&lt;span class="w"> &lt;/span>signal&lt;span class="w"> &lt;/span>EXC_ARITHMETIC,&lt;span class="w"> &lt;/span>Arithmetic&lt;span class="w"> &lt;/span>exception. 0x0000000100000f38&lt;span class="w"> &lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="w"> &lt;/span>main&lt;span class="w"> &lt;/span>&lt;span class="o">()&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Once again it is necessary to disassemble:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>disas Dump&lt;span class="w"> &lt;/span>of&lt;span class="w"> &lt;/span>assembler&lt;span class="w"> &lt;/span>code&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">function&lt;/span>&lt;span class="w"> &lt;/span>main: 0x0000000100000f20&lt;span class="w"> &lt;/span>&amp;lt;main+0&amp;gt;:&lt;span class="w"> &lt;/span>push&lt;span class="w"> &lt;/span>%rbp 0x0000000100000f21&lt;span class="w"> &lt;/span>&amp;lt;main+1&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>%rsp,%rbp 0x0000000100000f24&lt;span class="w"> &lt;/span>&amp;lt;main+4&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>%edi,-0x4&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> 0x0000000100000f27&lt;span class="w"> &lt;/span>&amp;lt;main+7&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>%rsi,-0x10&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> 0x0000000100000f2b&lt;span class="w"> &lt;/span>&amp;lt;main+11&amp;gt;:&lt;span class="w"> &lt;/span>movl&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>xff,-0x1c&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> 0x0000000100000f32&lt;span class="w"> &lt;/span>&amp;lt;main+18&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>-0x1c&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>,%eax 0x0000000100000f35&lt;span class="w"> &lt;/span>&amp;lt;main+21&amp;gt;:&lt;span class="w"> &lt;/span>xor&lt;span class="w"> &lt;/span>%ecx,%ecx 0x0000000100000f37&lt;span class="w"> &lt;/span>&amp;lt;main+23&amp;gt;:&lt;span class="w"> &lt;/span>cltd&lt;span class="w"> &lt;/span> 0x0000000100000f38&lt;span class="w"> &lt;/span>&amp;lt;main+24&amp;gt;:&lt;span class="w"> &lt;/span>idiv&lt;span class="w"> &lt;/span>%ecx 0x0000000100000f3a&lt;span class="w"> &lt;/span>&amp;lt;main+26&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>%eax,-0x18&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> 0x0000000100000f3d&lt;span class="w"> &lt;/span>&amp;lt;main+29&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>%eax,-0x14&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> 0x0000000100000f40&lt;span class="w"> &lt;/span>&amp;lt;main+32&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>-0x14&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>,%eax 0x0000000100000f43&lt;span class="w"> &lt;/span>&amp;lt;main+35&amp;gt;:&lt;span class="w"> &lt;/span>pop&lt;span class="w"> &lt;/span>%rbp 0x0000000100000f44&lt;span class="w"> &lt;/span>&amp;lt;main+36&amp;gt;:&lt;span class="w"> &lt;/span>retq&lt;span class="w"> &lt;/span> End&lt;span class="w"> &lt;/span>of&lt;span class="w"> &lt;/span>assembler&lt;span class="w"> &lt;/span>dump. &lt;/code>&lt;/pre>&lt;/div> &lt;p>The interesting lines are these with the exception happening on the last line:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>0x0000000100000f2b&lt;span class="w"> &lt;/span>&amp;lt;main+11&amp;gt;:&lt;span class="w"> &lt;/span>movl&lt;span class="w"> &lt;/span>&lt;span class="nv">$0&lt;/span>xff,-0x1c&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span> 0x0000000100000f32&lt;span class="w"> &lt;/span>&amp;lt;main+18&amp;gt;:&lt;span class="w"> &lt;/span>mov&lt;span class="w"> &lt;/span>-0x1c&lt;span class="o">(&lt;/span>%rbp&lt;span class="o">)&lt;/span>,%eax 0x0000000100000f35&lt;span class="w"> &lt;/span>&amp;lt;main+21&amp;gt;:&lt;span class="w"> &lt;/span>xor&lt;span class="w"> &lt;/span>%ecx,%ecx 0x0000000100000f37&lt;span class="w"> &lt;/span>&amp;lt;main+23&amp;gt;:&lt;span class="w"> &lt;/span>cltd&lt;span class="w"> &lt;/span> 0x0000000100000f38&lt;span class="w"> &lt;/span>&amp;lt;main+24&amp;gt;:&lt;span class="w"> &lt;/span>idiv&lt;span class="w"> &lt;/span>%ecx &lt;/code>&lt;/pre>&lt;/div> &lt;p>This basically does the operation &lt;code>0xFF / 0&lt;/code>. &lt;code>0xFF&lt;/code> is saved to &lt;code>-0x1c(%rbp)&lt;/code> and moved to &lt;code>%eax&lt;/code>, then &lt;code>0&lt;/code> is “created” by doing an &lt;span class="caps">XOR&lt;/span> on &lt;code>%ecx&lt;/code> with itself (recall that &lt;span class="caps">XOR&lt;/span> on two equal operands always yields &lt;code>0&lt;/code>) and storing in &lt;code>%ecx&lt;/code>, &lt;code>cltd&lt;/code> converts signed long word &lt;code>%eax&lt;/code> to a double word in &lt;code>%edx:%eax&lt;/code> and finally &lt;code>idiv&lt;/code> does the signed division.&lt;/p> &lt;p>Stay tuned for more.&lt;/p></content><category term="Debugging"/><category term="gdb"/><category term="debugging"/><category term="cpp"/><category term="gcc"/></entry><entry><title>Unleashing the Power of GDB</title><link href="https://www.mortens.dev/blog/unleashing-the-power-of-gdb/" rel="alternate"/><published>2013-02-12T01:33:30+02:00</published><updated>2013-02-12T01:33:30+02:00</updated><author><name>Morten</name></author><id>tag:www.mortens.dev,2013-02-12:/blog/unleashing-the-power-of-gdb/</id><summary type="html">&lt;p>Unleashing the Power of &lt;span class="caps">GDB&lt;/span> to debug&amp;nbsp;programs&lt;/p></summary><content type="html">&lt;p>The &lt;span class="caps">GNU&lt;/span> Debugger&lt;a href="http://sourceware.org/gdb/current/onlinedocs/gdb/index.html#Top" target="_blank">&lt;sup>[1]&lt;/sup>&lt;/a> is my favorite debugging tool and I personally think it’s essential for any *nix developer to know how to use it properly if you’re working with C/C++, D, Go, Obj-C, Fortran, Pascal, Modula-2 or Ada&lt;a href="http://sourceware.org/gdb/current/onlinedocs/gdb/Supported-Languages.html#Supported-Languages">&lt;sup>[2]&lt;/sup>&lt;/a>.&lt;/p> &lt;p>&lt;em>This is the first in hopefully a series of entries about utilising &lt;span class="caps">GDB&lt;/span> to its fullest.&lt;/em> First a little about how to invoke &lt;span class="caps">GDB&lt;/span>, secondly some basic usage of some of the most frequently used commands, how to attach to a running program and modify/redirect its &lt;code>stdout&lt;/code> and &lt;code>stderr&lt;/code>, then how to install and use watchpoints, and finally how to manually call functions and class methods.&lt;/p> &lt;h4>1. Invocation&lt;/h4> &lt;p>Here is how to start debugging a program:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>gdb&lt;span class="w"> &lt;/span>./program &lt;/code>&lt;/pre>&lt;/div> &lt;p>Make sure to compile your programs with debugging symbols to make source code and line numbers available while debugging. If using &lt;span class="caps">GCC&lt;/span> or Clang use the &lt;code>-g&lt;/code> argument to do this.&lt;/p> &lt;p>Sometimes arguments have to be passed to the program to debug:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>gdb&lt;span class="w"> &lt;/span>--args&lt;span class="w"> &lt;/span>./program&lt;span class="w"> &lt;/span>arg1&lt;span class="w"> &lt;/span>arg2&lt;span class="w"> &lt;/span>arg3.. &lt;/code>&lt;/pre>&lt;/div> &lt;h4>2. Basic usage&lt;/h4> &lt;p>The basic commands to use during the debugging phase is &lt;code>run&lt;/code> (&lt;code>r&lt;/code>), &lt;code>step&lt;/code> (&lt;code>s&lt;/code>), &lt;code>next&lt;/code> (&lt;code>n&lt;/code>), &lt;code>continue&lt;/code> (&lt;code>c&lt;/code>), &lt;code>frame&lt;/code> (&lt;code>f&lt;/code>), &lt;code>backtrace&lt;/code> (&lt;code>bt&lt;/code>), &lt;code>print&lt;/code> (&lt;code>p&lt;/code>), &lt;code>info&lt;/code> (&lt;code>i&lt;/code>), &lt;code>break&lt;/code>(&lt;code>b&lt;/code>), &lt;code>lines&lt;/code> (&lt;code>l&lt;/code>), &lt;code>help&lt;/code> (&lt;code>h&lt;/code>) and &lt;code>quit&lt;/code> (&lt;code>q&lt;/code>).&lt;/p> &lt;ul> &lt;li>&lt;strong>run&lt;/strong> will run the program or re-run if already started.&lt;/li> &lt;li>&lt;strong>step&lt;/strong> steps until the program reaches a new source code line and can be used with an integer argument to step that many times.&lt;/li> &lt;li>&lt;strong>next&lt;/strong> works like `step` except it will treat a function call like a single instruction. Can also be given an integer argument.&lt;/li> &lt;li>&lt;strong>continue&lt;/strong> will resume execution after hitting a breakpoint, for instance.&lt;/li> &lt;li>&lt;strong>frame&lt;/strong> can be used to select or print current stack frame. When no argument is given it will print the current stack frame, and otherwise it will select the chosen frame.&lt;/li> &lt;li>&lt;strong>backtrace&lt;/strong> is used to print a backtrace of all stack frames in order. When an argument is given it will print the innermost frames if positive and the outermost if negative.&lt;/li> &lt;li>&lt;strong>print&lt;/strong> prints the value of an expression. It could be variables in the current stack frame, globals or an entire file. As we shall see later on it can also be used to invoke system calls and more.&lt;/li> &lt;li>&lt;strong>info&lt;/strong> is very useful because it can display a lot of information about variables, threads, frame, registers, files, types, symbols, locals, addresses and tons more.&lt;/li> &lt;li>&lt;strong>break&lt;/strong> is used to set breakpoints in the program at a specified line, function or address.&lt;/li> &lt;li>&lt;strong>lines&lt;/strong> with no arguments shows the 10 source code lines centered at the current line. The argument can be a line number, a file with line number (&lt;span class="caps">FILE&lt;/span>:&lt;span class="caps">LINENUM&lt;/span>), a function, a file and function (&lt;span class="caps">FILE&lt;/span>:&lt;span class="caps">FUNCTION&lt;/span>) or an address (*&lt;span class="caps">ADDR&lt;/span>).&lt;/li> &lt;li>&lt;strong>help&lt;/strong> is invaluable because it explains about more or less everything in &lt;span class="caps">GDB&lt;/span>. &lt;em>So use it!&lt;/em>&lt;/li> &lt;li>Lastly &lt;strong>quit&lt;/strong> exits the program and terminates &lt;span class="caps">GDB&lt;/span>.&lt;/li> &lt;/ul> &lt;p>So let’s give them a spin. Save the following code to a file named “test.cpp”:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="cp">#include&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="cpf">&amp;lt;string&amp;gt;&lt;/span> &lt;span class="cp">#include&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span> &lt;span class="k">using&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">namespace&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nn">std&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="kt">void&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">func2&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">string&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">str&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="n">cout&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"func2 says: "&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">str&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="kt">void&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">func1&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="n">string&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">str&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"$"&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="n">func2&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">str&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="kt">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">main&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">argc&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">char&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">**&lt;/span>&lt;span class="n">argv&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="n">func1&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">5&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Then compile it thusly:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>g++&lt;span class="w"> &lt;/span>-g&lt;span class="w"> &lt;/span>-o&lt;span class="w"> &lt;/span>&lt;span class="nb">test&lt;/span>&lt;span class="w"> &lt;/span>test.cpp &lt;/code>&lt;/pre>&lt;/div> &lt;p>And debug it:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>gdb&lt;span class="w"> &lt;/span>./test &lt;/code>&lt;/pre>&lt;/div> &lt;p>First thing we will do is set a breakpoint at &lt;code>main&lt;/code> and run the program:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>b&lt;span class="w"> &lt;/span>main Breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>0x100000c4f:&lt;span class="w"> &lt;/span>file&lt;span class="w"> &lt;/span>test.cpp,&lt;span class="w"> &lt;/span>line&lt;span class="w"> &lt;/span>&lt;span class="m">15&lt;/span>. &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>r Starting&lt;span class="w"> &lt;/span>program:&lt;span class="w"> &lt;/span>/private/tmp/test&lt;span class="w"> &lt;/span> Reading&lt;span class="w"> &lt;/span>symbols&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>shared&lt;span class="w"> &lt;/span>libraries&lt;span class="w"> &lt;/span>++.............................&lt;span class="w"> &lt;/span>&lt;span class="k">done&lt;/span> Breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>,&lt;span class="w"> &lt;/span>main&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="nv">argc&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="m">1&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="nv">argv&lt;/span>&lt;span class="o">=&lt;/span>0x7fff5fbffa80&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>test.cpp:15 &lt;span class="m">15&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>int&lt;span class="w"> &lt;/span>&lt;span class="nv">i&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>i&lt;span class="w"> &lt;/span>&amp;lt;&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">3&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>i++&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Then we inspect the arguments of the current stack:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>f &lt;span class="c1">#0 main (argc=1, argv=0x7fff5fbffa80) at test.cpp:15&lt;/span> &lt;span class="m">15&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>int&lt;span class="w"> &lt;/span>&lt;span class="nv">i&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>i&lt;span class="w"> &lt;/span>&amp;lt;&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">3&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>i++&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>i&lt;span class="w"> &lt;/span>args &lt;span class="nv">argc&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span> &lt;span class="nv">argv&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>char&lt;span class="w"> &lt;/span>**&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>0x7fff5fbffa80 &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>p&lt;span class="w"> &lt;/span>argv &lt;span class="nv">$1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>char&lt;span class="w"> &lt;/span>**&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>0x7fff5fbffa80 &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>p&lt;span class="w"> &lt;/span>*argv &lt;span class="nv">$2&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>0x7fff5fbffbf8&lt;span class="w"> &lt;/span>&lt;span class="s2">"/private/tmp/test"&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>p&lt;span class="w"> &lt;/span>argv&lt;span class="o">[&lt;/span>&lt;span class="m">0&lt;/span>&lt;span class="o">]&lt;/span> &lt;span class="nv">$3&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>0x7fff5fbffbf8&lt;span class="w"> &lt;/span>&lt;span class="s2">"/private/tmp/test"&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>p&lt;span class="w"> &lt;/span>argv&lt;span class="o">[&lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="o">]&lt;/span> &lt;span class="nv">$4&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>0x0 &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Notice that the manipulation of the &lt;code>argv&lt;/code> array is very much like in C/C++ with deference/element access (&lt;code>p *argv&lt;/code> and &lt;code>p argv[1]&lt;/code>).&lt;/p> &lt;p>Now we step one round through the &lt;code>for&lt;/code>-loop:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>s &lt;span class="m">16&lt;/span>&lt;span class="w"> &lt;/span>func1&lt;span class="o">(&lt;/span>i&lt;span class="w"> &lt;/span>*&lt;span class="w"> &lt;/span>&lt;span class="m">5&lt;/span>&lt;span class="o">)&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>s func1&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="nv">i&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="m">5&lt;/span>&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>test.cpp:10 &lt;span class="m">10&lt;/span>&lt;span class="w"> &lt;/span>string&lt;span class="w"> &lt;/span>str&lt;span class="o">(&lt;/span>i,&lt;span class="w"> &lt;/span>&lt;span class="s2">"&lt;/span>$&lt;span class="s2">"&lt;/span>&lt;span class="o">)&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>s &lt;span class="m">11&lt;/span>&lt;span class="w"> &lt;/span>func2&lt;span class="o">(&lt;/span>str&lt;span class="o">)&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>s func2&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="nv">str&lt;/span>&lt;span class="o">=&lt;/span>@0x7fff5fbffa00&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>test.cpp:6 &lt;span class="m">6&lt;/span>&lt;span class="w"> &lt;/span>cout&lt;span class="w"> &lt;/span>&amp;lt;&amp;lt;&lt;span class="w"> &lt;/span>&lt;span class="s2">"func2 says: "&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;lt;&amp;lt; str &amp;lt;&amp;lt; endl;&lt;/span> &lt;span class="s">(gdb) s&lt;/span> &lt;span class="s">func2 says: $$$$$&lt;/span> &lt;span class="s">7 }&lt;/span> &lt;span class="s">(gdb) s&lt;/span> &lt;span class="s">func1 (i=5) at test.cpp:12&lt;/span> &lt;span class="s">12 }&lt;/span> &lt;span class="s">(gdb) s&lt;/span> &lt;span class="s">0x0000000100000bee 11 func2(str&lt;/span>&lt;span class="o">)&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>s main&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="nv">argc&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="m">1&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="nv">argv&lt;/span>&lt;span class="o">=&lt;/span>0x7fff5fbffa80&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>test.cpp:15 &lt;span class="m">15&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>int&lt;span class="w"> &lt;/span>&lt;span class="nv">i&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>i&lt;span class="w"> &lt;/span>&amp;lt;&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">3&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>i++&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>What happens is that we first call &lt;code>func1(5)&lt;/code> which in turn calls &lt;code>func2(str)&lt;/code> and returns to the &lt;code>for&lt;/code>-loop. If we instead used &lt;code>next&lt;/code> the output would be shorter because it would not step into &lt;code>func1&lt;/code>:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>n &lt;span class="m">16&lt;/span>&lt;span class="w"> &lt;/span>func1&lt;span class="o">(&lt;/span>i&lt;span class="w"> &lt;/span>*&lt;span class="w"> &lt;/span>&lt;span class="m">5&lt;/span>&lt;span class="o">)&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>n func2&lt;span class="w"> &lt;/span>says:&lt;span class="w"> &lt;/span>&lt;span class="nv">$$$$$$$$$$&lt;/span> &lt;span class="m">15&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>int&lt;span class="w"> &lt;/span>&lt;span class="nv">i&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>i&lt;span class="w"> &lt;/span>&amp;lt;&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">3&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>i++&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>It’s time to see a backtrace in action:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>b&lt;span class="w"> &lt;/span>func2 Breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">2&lt;/span>&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>0x100000abc:&lt;span class="w"> &lt;/span>file&lt;span class="w"> &lt;/span>test.cpp,&lt;span class="w"> &lt;/span>line&lt;span class="w"> &lt;/span>&lt;span class="m">6&lt;/span>. &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>c Continuing. Breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">2&lt;/span>,&lt;span class="w"> &lt;/span>func2&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="nv">str&lt;/span>&lt;span class="o">=&lt;/span>@0x7fff5fbffa00&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>test.cpp:6 &lt;span class="m">6&lt;/span>&lt;span class="w"> &lt;/span>cout&lt;span class="w"> &lt;/span>&amp;lt;&amp;lt;&lt;span class="w"> &lt;/span>&lt;span class="s2">"func2 says: "&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;lt;&amp;lt; str &amp;lt;&amp;lt; endl;&lt;/span> &lt;span class="s">(gdb) bt&lt;/span> &lt;span class="s">#0 func2 (str&lt;/span>&lt;span class="o">=&lt;/span>@0x7fff5fbffa00&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>test.cpp:6 &lt;span class="c1">#1 0x0000000100000b81 in func1 (i=15) at test.cpp:11&lt;/span> &lt;span class="c1">#2 0x0000000100000c65 in main (argc=1, argv=0x7fff5fbffa80) at test.cpp:16&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>The trace shows the stack frames in a numbered fashion from &lt;code>func2&lt;/code> and backwards. Let’s inspect frame &lt;code>#1&lt;/code>:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>f&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span> &lt;span class="c1">#1 0x0000000100000b81 in func1 (i=15) at test.cpp:11&lt;/span> &lt;span class="m">11&lt;/span>&lt;span class="w"> &lt;/span>func2&lt;span class="o">(&lt;/span>str&lt;span class="o">)&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>l &lt;span class="m">6&lt;/span>&lt;span class="w"> &lt;/span>cout&lt;span class="w"> &lt;/span>&amp;lt;&amp;lt;&lt;span class="w"> &lt;/span>&lt;span class="s2">"func2 says: "&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;lt;&amp;lt; str &amp;lt;&amp;lt; endl;&lt;/span> &lt;span class="s">7 }&lt;/span> &lt;span class="s">8 &lt;/span> &lt;span class="s">9 void func1(int i) {&lt;/span> &lt;span class="s">10 str&lt;/span>ing&lt;span class="w"> &lt;/span>str&lt;span class="o">(&lt;/span>i,&lt;span class="w"> &lt;/span>&lt;span class="s2">"&lt;/span>$&lt;span class="s2">"&lt;/span>&lt;span class="o">)&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="m">11&lt;/span>&lt;span class="w"> &lt;/span>func2&lt;span class="o">(&lt;/span>str&lt;span class="o">)&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="m">12&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">}&lt;/span> &lt;span class="m">13&lt;/span>&lt;span class="w"> &lt;/span> &lt;span class="m">14&lt;/span>&lt;span class="w"> &lt;/span>int&lt;span class="w"> &lt;/span>main&lt;span class="o">(&lt;/span>int&lt;span class="w"> &lt;/span>argc,&lt;span class="w"> &lt;/span>char&lt;span class="w"> &lt;/span>**argv&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span> &lt;span class="m">15&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>int&lt;span class="w"> &lt;/span>&lt;span class="nv">i&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>i&lt;span class="w"> &lt;/span>&amp;lt;&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">3&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>i++&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>That concludes the basics:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>q The&lt;span class="w"> &lt;/span>program&lt;span class="w"> &lt;/span>is&lt;span class="w"> &lt;/span>running.&lt;span class="w"> &lt;/span>Exit&lt;span class="w"> &lt;/span>anyway?&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>y&lt;span class="w"> &lt;/span>or&lt;span class="w"> &lt;/span>n&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>y &lt;/code>&lt;/pre>&lt;/div> &lt;h4>3. Attaching live programs&lt;/h4> &lt;p>&lt;span class="caps">GDB&lt;/span> can attach to running programs by stating its process &lt;span class="caps">ID&lt;/span> (&lt;span class="caps">PID&lt;/span>):&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>gdb&lt;span class="w"> &lt;/span>-p&lt;span class="w"> &lt;/span>PID &lt;/code>&lt;/pre>&lt;/div> &lt;p>Here is a little trick to debug a program started by another program at runtime. It might be crucial to attach and debug “from the top” so what to do? Simply add a little sleep to leave enough time to find the &lt;span class="caps">PID&lt;/span> and attach using &lt;span class="caps">GDB&lt;/span>. After attaching set the needed breakpoints and &lt;code>continue&lt;/code> execution. Another way of achieving the same thing is to use:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>gdb&lt;span class="w"> &lt;/span>--waitfor&lt;span class="o">=&lt;/span>PROCNAME &lt;/code>&lt;/pre>&lt;/div> &lt;p>Where &lt;span class="caps">PROCNAME&lt;/span> is the process name to continuously poll for until it has been launched. Note that some instructions &lt;em>will&lt;/em> have been executed before &lt;span class="caps">GDB&lt;/span> attaches this way because polling is not exactly instant however close it might seem to be.&lt;/p> &lt;p>A very useful technique is to know how to redirect &lt;code>stdout&lt;/code> (file descriptor 1) and/or &lt;code>stderr&lt;/code> (&lt;span class="caps">FD&lt;/span> 2) after a program has started. We are going to exploit the fact that &lt;code>print&lt;/code> can invoke system calls like &lt;code>dup2&lt;/code> and &lt;code>open&lt;/code> in our case. After attaching to the process do the following:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>p&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>void&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>dup2&lt;span class="o">((&lt;/span>int&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>open&lt;span class="o">(&lt;/span>&lt;span class="s2">"/tmp/out.txt"&lt;/span>,&lt;span class="w"> &lt;/span>0x201,&lt;span class="w"> &lt;/span>&lt;span class="m">0640&lt;/span>&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="o">)&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>p&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>void&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>dup2&lt;span class="o">((&lt;/span>int&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>open&lt;span class="o">(&lt;/span>&lt;span class="s2">"/tmp/err.txt"&lt;/span>,&lt;span class="w"> &lt;/span>0x201,&lt;span class="w"> &lt;/span>&lt;span class="m">0640&lt;/span>&lt;span class="o">)&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="m">2&lt;/span>&lt;span class="o">)&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>detach &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>q &lt;/code>&lt;/pre>&lt;/div> &lt;p>In short it will redirect &lt;code>stdout&lt;/code> to “/tmp/stdout.txt” and &lt;code>stderr&lt;/code> to “/tmp/stderr.txt”. The system call &lt;code>open&lt;/code> is used to open a file for writing in our case. The mode “0x201” actually means “write only and create file if nonexistent” since &lt;code>O_CREAT | O_WRONLY&lt;/code> = 0x200 | 0x1 = 0x201 (see the &lt;code>fcntl.h&lt;/code> header file for details). “0640” is the umask (user has &lt;span class="caps">RW&lt;/span> and group has R). After opening a file and retrieving its &lt;span class="caps">FD&lt;/span> we need to redirect the device in question to it (&lt;code>stdout&lt;/code> and &lt;code>stderr&lt;/code> in this case). This is achieved using &lt;code>dup2&lt;/code> that creates an alias to the &lt;span class="caps">FD&lt;/span>, does redirection and closes the old &lt;span class="caps">FD&lt;/span>.&lt;/p> &lt;p>Additionally, it’s important to cast types to enforce &lt;span class="caps">GDB&lt;/span> to behave correctly. If this is not the case it could argue giving the following error message: &lt;/p> &lt;p>&lt;blockquote class="blockquote">Unable to call function “open” at 0x7fff906e3fe4: no return type information available. To call this function anyway, you can cast the return type explicitly (e.g. ”print (float) fabs (3.0)”)&lt;/blockquote>&lt;/p> &lt;p>Another scenario would be to completely turn off output to &lt;code>stdout&lt;/code>/&lt;code>stderr&lt;/code>:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>p&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>void&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>close&lt;span class="o">(&lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="o">)&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>p&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>void&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>close&lt;span class="o">(&lt;/span>&lt;span class="m">2&lt;/span>&lt;span class="o">)&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>det &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>q &lt;/code>&lt;/pre>&lt;/div> &lt;p>Here is some code for the testing the above instructions and to observe that the output is redirected or stopped:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="cp">#include&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="cpf">&amp;lt;unistd.h&amp;gt;&lt;/span> &lt;span class="cp">#include&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span> &lt;span class="k">using&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">namespace&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nn">std&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="kt">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">main&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">argc&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">char&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">**&lt;/span>&lt;span class="n">argv&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">120&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="n">cout&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"hello stdout"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="n">cerr&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"hello stderr"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="n">sleep&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;h4>4. Watchpoints&lt;/h4> &lt;p>Watchpoints are useful when certain variables need to be watched using the command &lt;code>watch&lt;/code>. Whenever a watched variable is changed &lt;span class="caps">GDB&lt;/span> will show the old and new value along with the stack frame. Try debugging the program from before:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>b&lt;span class="w"> &lt;/span>main Breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>0x100000c4f:&lt;span class="w"> &lt;/span>file&lt;span class="w"> &lt;/span>test.cpp,&lt;span class="w"> &lt;/span>line&lt;span class="w"> &lt;/span>&lt;span class="m">15&lt;/span>. &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>r&lt;span class="w"> &lt;/span> Starting&lt;span class="w"> &lt;/span>program:&lt;span class="w"> &lt;/span>/private/tmp/test&lt;span class="w"> &lt;/span> Reading&lt;span class="w"> &lt;/span>symbols&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>shared&lt;span class="w"> &lt;/span>libraries&lt;span class="w"> &lt;/span>++.............................&lt;span class="w"> &lt;/span>&lt;span class="k">done&lt;/span> Breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>,&lt;span class="w"> &lt;/span>main&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="nv">argc&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="m">1&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="nv">argv&lt;/span>&lt;span class="o">=&lt;/span>0x7fff5fbffa80&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>test.cpp:15 &lt;span class="m">15&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>int&lt;span class="w"> &lt;/span>&lt;span class="nv">i&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>i&lt;span class="w"> &lt;/span>&amp;lt;&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">3&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>i++&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>watch&lt;span class="w"> &lt;/span>i Hardware&lt;span class="w"> &lt;/span>watchpoint&lt;span class="w"> &lt;/span>&lt;span class="m">2&lt;/span>:&lt;span class="w"> &lt;/span>i &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>d&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>c Continuing. Hardware&lt;span class="w"> &lt;/span>watchpoint&lt;span class="w"> &lt;/span>&lt;span class="m">2&lt;/span>:&lt;span class="w"> &lt;/span>i Old&lt;span class="w"> &lt;/span>&lt;span class="nv">value&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span> New&lt;span class="w"> &lt;/span>&lt;span class="nv">value&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span> 0x0000000100000c56&lt;span class="w"> &lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="w"> &lt;/span>main&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="nv">argc&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="m">1&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="nv">argv&lt;/span>&lt;span class="o">=&lt;/span>0x7fff5fbffa80&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>test.cpp:15 &lt;span class="m">15&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>int&lt;span class="w"> &lt;/span>&lt;span class="nv">i&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>i&lt;span class="w"> &lt;/span>&amp;lt;&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">3&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>i++&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>c Continuing. &lt;span class="nv">$$$$&lt;/span>$ Hardware&lt;span class="w"> &lt;/span>watchpoint&lt;span class="w"> &lt;/span>&lt;span class="m">2&lt;/span>:&lt;span class="w"> &lt;/span>i Old&lt;span class="w"> &lt;/span>&lt;span class="nv">value&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span> New&lt;span class="w"> &lt;/span>&lt;span class="nv">value&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">2&lt;/span> 0x0000000100000c6e&lt;span class="w"> &lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="w"> &lt;/span>main&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="nv">argc&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="m">1&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="nv">argv&lt;/span>&lt;span class="o">=&lt;/span>0x7fff5fbffa80&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>test.cpp:15 &lt;span class="m">15&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>int&lt;span class="w"> &lt;/span>&lt;span class="nv">i&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>i&lt;span class="w"> &lt;/span>&amp;lt;&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">3&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>i++&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>c Continuing. &lt;span class="nv">$$$$$$$$$$&lt;/span> Hardware&lt;span class="w"> &lt;/span>watchpoint&lt;span class="w"> &lt;/span>&lt;span class="m">2&lt;/span>:&lt;span class="w"> &lt;/span>i Old&lt;span class="w"> &lt;/span>&lt;span class="nv">value&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">2&lt;/span> New&lt;span class="w"> &lt;/span>&lt;span class="nv">value&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">3&lt;/span> 0x0000000100000c6e&lt;span class="w"> &lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="w"> &lt;/span>main&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="nv">argc&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="m">1&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="nv">argv&lt;/span>&lt;span class="o">=&lt;/span>0x7fff5fbffa80&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>test.cpp:15 &lt;span class="m">15&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>int&lt;span class="w"> &lt;/span>&lt;span class="nv">i&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>i&lt;span class="w"> &lt;/span>&amp;lt;&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">3&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>i++&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>c Continuing. &lt;span class="nv">$$$$$$$$$$$$$$&lt;/span>$ Hardware&lt;span class="w"> &lt;/span>watchpoint&lt;span class="w"> &lt;/span>&lt;span class="m">2&lt;/span>:&lt;span class="w"> &lt;/span>i Old&lt;span class="w"> &lt;/span>&lt;span class="nv">value&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">3&lt;/span> New&lt;span class="w"> &lt;/span>&lt;span class="nv">value&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">4&lt;/span> 0x0000000100000c6e&lt;span class="w"> &lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="w"> &lt;/span>main&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="nv">argc&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="m">1&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="nv">argv&lt;/span>&lt;span class="o">=&lt;/span>0x7fff5fbffa80&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>test.cpp:15 &lt;span class="m">15&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>int&lt;span class="w"> &lt;/span>&lt;span class="nv">i&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>i&lt;span class="w"> &lt;/span>&amp;lt;&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">3&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>i++&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>c Continuing. Watchpoint&lt;span class="w"> &lt;/span>&lt;span class="m">2&lt;/span>&lt;span class="w"> &lt;/span>deleted&lt;span class="w"> &lt;/span>because&lt;span class="w"> &lt;/span>the&lt;span class="w"> &lt;/span>program&lt;span class="w"> &lt;/span>has&lt;span class="w"> &lt;/span>left&lt;span class="w"> &lt;/span>the&lt;span class="w"> &lt;/span>block&lt;span class="w"> &lt;/span>&lt;span class="k">in&lt;/span> which&lt;span class="w"> &lt;/span>its&lt;span class="w"> &lt;/span>expression&lt;span class="w"> &lt;/span>is&lt;span class="w"> &lt;/span>valid. &lt;/code>&lt;/pre>&lt;/div> &lt;p>Notice I did &lt;code>d 1&lt;/code> which means to delete the breakpoint with number “1”. &lt;/p> &lt;h4>5. Calling functions&lt;/h4> &lt;p>While debugging it is possible to call functions of the program - even pass them arguments - and have the result saved in value history if non-void. Load the first test program from above in &lt;span class="caps">GDB&lt;/span>:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>b&lt;span class="w"> &lt;/span>&lt;span class="m">11&lt;/span> Breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>0x100000b45:&lt;span class="w"> &lt;/span>file&lt;span class="w"> &lt;/span>test.cpp,&lt;span class="w"> &lt;/span>line&lt;span class="w"> &lt;/span>&lt;span class="m">11&lt;/span>. &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>r Starting&lt;span class="w"> &lt;/span>program:&lt;span class="w"> &lt;/span>/private/tmp/test&lt;span class="w"> &lt;/span> Reading&lt;span class="w"> &lt;/span>symbols&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>shared&lt;span class="w"> &lt;/span>libraries&lt;span class="w"> &lt;/span>++.............................&lt;span class="w"> &lt;/span>&lt;span class="k">done&lt;/span> Breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>,&lt;span class="w"> &lt;/span>func1&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="nv">i&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="m">5&lt;/span>&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>test.cpp:11 &lt;span class="m">11&lt;/span>&lt;span class="w"> &lt;/span>func2&lt;span class="o">(&lt;/span>str&lt;span class="o">)&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>i&lt;span class="w"> &lt;/span>loc&lt;span class="w"> &lt;/span> &lt;span class="nv">str&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nv">_M_dataplus&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span> &lt;span class="w"> &lt;/span>&amp;lt;std::allocator&amp;lt;char&amp;gt;&amp;gt;&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span> &lt;span class="w"> &lt;/span>&amp;lt;__gnu_cxx::new_allocator&amp;lt;char&amp;gt;&amp;gt;&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span>&amp;lt;No&lt;span class="w"> &lt;/span>data&lt;span class="w"> &lt;/span>fields&amp;gt;&lt;span class="o">}&lt;/span>,&lt;span class="w"> &lt;/span>&amp;lt;No&lt;span class="w"> &lt;/span>data&lt;span class="w"> &lt;/span>fields&amp;gt;&lt;span class="o">}&lt;/span>,&lt;span class="w"> &lt;/span> &lt;span class="w"> &lt;/span>members&lt;span class="w"> &lt;/span>of&lt;span class="w"> &lt;/span>std::string::_Alloc_hider:&lt;span class="w"> &lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nv">_M_p&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>0x100103938&lt;span class="w"> &lt;/span>&lt;span class="s2">"&lt;/span>&lt;span class="nv">$$$$&lt;/span>$&lt;span class="s2">"&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="o">}&lt;/span> &lt;span class="o">}&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>call&lt;span class="w"> &lt;/span>func2&lt;span class="o">(&lt;/span>str&lt;span class="o">)&lt;/span> func2&lt;span class="w"> &lt;/span>says:&lt;span class="w"> &lt;/span>&lt;span class="nv">$$$$&lt;/span>$ &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>q The&lt;span class="w"> &lt;/span>program&lt;span class="w"> &lt;/span>is&lt;span class="w"> &lt;/span>running.&lt;span class="w"> &lt;/span>Exit&lt;span class="w"> &lt;/span>anyway?&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>y&lt;span class="w"> &lt;/span>or&lt;span class="w"> &lt;/span>n&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>y &lt;/code>&lt;/pre>&lt;/div> &lt;p>Since we already have a &lt;code>std::string&lt;/code> object we can call &lt;code>func2(str)&lt;/code> manually.&lt;/p> &lt;p>This functionality opens up for a variety of different uses. One is to use predefined debugging functions to display custom data structures that &lt;span class="caps">GDB&lt;/span> doesn’t know about. Take the &lt;code>std::string&lt;/code> structure above for &lt;code>str&lt;/code> - it’s not very descriptive except for the fact that its content is visible (&lt;code>_M_p = 0x100103938 "$$$$$"&lt;/code>). &lt;/p> &lt;p>Compile and load up the following program in &lt;span class="caps">GDB&lt;/span>:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="cp">#include&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="cpf">&amp;lt;string&amp;gt;&lt;/span> &lt;span class="cp">#include&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span> &lt;span class="k">using&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">namespace&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nn">std&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="k">class&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nc">Test&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="n">Test&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">),&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">b&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">),&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">c&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">),&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">str&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">"Hello, World!"&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">b&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">c&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="n">string&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">str&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">};&lt;/span> &lt;span class="kt">void&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">dbg&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Test&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">test&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="n">cout&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"a = "&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">test&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">endl&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"b = "&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">test&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">b&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">endl&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"c = "&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">test&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">c&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">endl&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"str = "&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">test&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">str&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="kt">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">main&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">argc&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">char&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">**&lt;/span>&lt;span class="n">argv&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="n">Test&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">test&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Then it’s high time to compare the two approaches:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>b&lt;span class="w"> &lt;/span>main Breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>0x100000b31:&lt;span class="w"> &lt;/span>file&lt;span class="w"> &lt;/span>custom.cpp,&lt;span class="w"> &lt;/span>line&lt;span class="w"> &lt;/span>&lt;span class="m">21&lt;/span>. &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>r Starting&lt;span class="w"> &lt;/span>program:&lt;span class="w"> &lt;/span>/private/tmp/custom&lt;span class="w"> &lt;/span> Reading&lt;span class="w"> &lt;/span>symbols&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>shared&lt;span class="w"> &lt;/span>libraries&lt;span class="w"> &lt;/span>++.............................&lt;span class="w"> &lt;/span>&lt;span class="k">done&lt;/span> Breakpoint&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>,&lt;span class="w"> &lt;/span>main&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="nv">argc&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="m">1&lt;/span>,&lt;span class="w"> &lt;/span>&lt;span class="nv">argv&lt;/span>&lt;span class="o">=&lt;/span>0x7fff5fbffa78&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>custom.cpp:21 &lt;span class="m">21&lt;/span>&lt;span class="w"> &lt;/span>Test&lt;span class="w"> &lt;/span>test&lt;span class="p">;&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>n &lt;span class="m">22&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>call&lt;span class="w"> &lt;/span>dbg&lt;span class="o">(&lt;/span>&lt;span class="nb">test&lt;/span>&lt;span class="o">)&lt;/span> &lt;span class="nv">a&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span> &lt;span class="nv">b&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">2&lt;/span> &lt;span class="nv">c&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">3&lt;/span> &lt;span class="nv">str&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>Hello,&lt;span class="w"> &lt;/span>World! &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>p&lt;span class="w"> &lt;/span>&lt;span class="nb">test&lt;/span> &lt;span class="nv">$1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nv">a&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>,&lt;span class="w"> &lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nv">b&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">2&lt;/span>,&lt;span class="w"> &lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nv">c&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">3&lt;/span>,&lt;span class="w"> &lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nv">str&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nv">_M_dataplus&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span> &lt;span class="w"> &lt;/span>&amp;lt;std::allocator&amp;lt;char&amp;gt;&amp;gt;&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span> &lt;span class="w"> &lt;/span>&amp;lt;__gnu_cxx::new_allocator&amp;lt;char&amp;gt;&amp;gt;&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">{&lt;/span>&amp;lt;No&lt;span class="w"> &lt;/span>data&lt;span class="w"> &lt;/span>fields&amp;gt;&lt;span class="o">}&lt;/span>,&lt;span class="w"> &lt;/span>&amp;lt;No&lt;span class="w"> &lt;/span>data&lt;span class="w"> &lt;/span>fields&amp;gt;&lt;span class="o">}&lt;/span>,&lt;span class="w"> &lt;/span> &lt;span class="w"> &lt;/span>members&lt;span class="w"> &lt;/span>of&lt;span class="w"> &lt;/span>std::string::_Alloc_hider:&lt;span class="w"> &lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="nv">_M_p&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>0x100103938&lt;span class="w"> &lt;/span>&lt;span class="s2">"Hello, World!"&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="o">}&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="o">}&lt;/span> &lt;span class="o">}&lt;/span> &lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Keep in mind that this is just a simple test. The great thing about this is that you can fine-tune the debugging function to show only what you need to see and leave out the unnecessary parts. &lt;em>And make sure the variables you’re accessing are actually live and initialised when doing so!&lt;/em> If we skip the &lt;code>next&lt;/code> command above this is the result:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>call&lt;span class="w"> &lt;/span>dbg&lt;span class="o">(&lt;/span>&lt;span class="nb">test&lt;/span>&lt;span class="o">)&lt;/span> &lt;span class="nv">a&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span> &lt;span class="nv">b&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span> &lt;span class="nv">c&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span> Program&lt;span class="w"> &lt;/span>received&lt;span class="w"> &lt;/span>signal&lt;span class="w"> &lt;/span>EXC_BAD_ACCESS,&lt;span class="w"> &lt;/span>Could&lt;span class="w"> &lt;/span>not&lt;span class="w"> &lt;/span>access&lt;span class="w"> &lt;/span>memory. Reason:&lt;span class="w"> &lt;/span>KERN_INVALID_ADDRESS&lt;span class="w"> &lt;/span>at&lt;span class="w"> &lt;/span>address:&lt;span class="w"> &lt;/span>0xffffffffffffffe8 0x00007fff8fa68c85&lt;span class="w"> &lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="w"> &lt;/span>std::operator&amp;lt;&amp;lt;&lt;span class="w"> &lt;/span>&amp;lt;char,&lt;span class="w"> &lt;/span>std::char_traits&amp;lt;char&amp;gt;,&lt;span class="w"> &lt;/span>std::allocator&amp;lt;char&amp;gt;&lt;span class="w"> &lt;/span>&amp;gt;&lt;span class="w"> &lt;/span>&lt;span class="o">()&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>It is also possible to call class methods. Add the following snippet after the constructor on line 7 in the previous code:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="kt">void&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">__attribute__&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">((&lt;/span>&lt;span class="n">used&lt;/span>&lt;span class="p">))&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">dump&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="n">cout&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">"str = "&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">str&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Notice the use of the “used” attribute - this is because if the method is not called in the source code, which is the case here, the compiler will optimise the whole thing away in most cases.&lt;/p> &lt;p>Invoking the method on our &lt;code>test&lt;/code> object is easy:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="o">(&lt;/span>gdb&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>call&lt;span class="w"> &lt;/span>test.dump&lt;span class="o">()&lt;/span> &lt;span class="nv">str&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>Hello,&lt;span class="w"> &lt;/span>World! &lt;/code>&lt;/pre>&lt;/div> &lt;p>That concludes the basic knowledge needed to start debugging using &lt;span class="caps">GDB&lt;/span>. Stay tuned for more!&lt;/p></content><category term="Debugging"/><category term="gdb"/><category term="debugging"/><category term="cpp"/><category term="gcc"/></entry><entry><title>sed tricks</title><link href="https://www.mortens.dev/blog/sed-tricks/" rel="alternate"/><published>2013-02-09T16:05:04+02:00</published><updated>2013-02-09T16:05:04+02:00</updated><author><name>Morten</name></author><id>tag:www.mortens.dev,2013-02-09:/blog/sed-tricks/</id><summary type="html">&lt;p>sed tricks for modifying data from files and&amp;nbsp;stdin&lt;/p></summary><content type="html">&lt;p>The &lt;strong>s&lt;/strong>tream &lt;strong>ed&lt;/strong>itor, most commonly know as &lt;b>sed&lt;/b>, is a wonderful tool for modifying data from files and stdin. &lt;em>In this article I will be using the &lt;span class="caps">BSD&lt;/span> variant of sed which is a little bit different from the &lt;span class="caps">GNU&lt;/span> variant of sed but I will try to point out where the differences are in my examples.&lt;/em> &lt;/p> &lt;h4>1. Usage&lt;/h4> &lt;p>One of the most common ways of using sed is:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>cat&lt;span class="w"> &lt;/span>file.txt&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="w"> &lt;/span>sed&lt;span class="w"> &lt;/span>COMMAND &lt;/code>&lt;/pre>&lt;/div> &lt;p>And the other&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>sed&lt;span class="w"> &lt;/span>COMMAND&lt;span class="w"> &lt;/span>FILE &lt;/code>&lt;/pre>&lt;/div> &lt;p>It is possible to have multiple commands using the &lt;code>-e&lt;/code> argument:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>sed&lt;span class="w"> &lt;/span>-e&lt;span class="w"> &lt;/span>COMMAND&lt;span class="w"> &lt;/span>-e&lt;span class="w"> &lt;/span>COMMAND&lt;span class="w"> &lt;/span>.. &lt;/code>&lt;/pre>&lt;/div> &lt;p>Or even like this:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>sed&lt;span class="w"> &lt;/span>&lt;span class="s1">'COMMAND;COMMAND;..'&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>The &lt;em>&lt;span class="caps">COMMAND&lt;/span>&lt;/em> can be a lot of different things but usually it will be the substitution pattern: &lt;code>s/regular expression/replacement/flags&lt;/code>&lt;/p> &lt;p>Here is an example:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="nb">echo&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">"aabb"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="w"> &lt;/span>sed&lt;span class="w"> &lt;/span>-e&lt;span class="w"> &lt;/span>&lt;span class="s1">'s/a/A/'&lt;/span>&lt;span class="w"> &lt;/span>-e&lt;span class="w"> &lt;/span>&lt;span class="s1">'s/b/B/g'&lt;/span> AaBB &lt;/code>&lt;/pre>&lt;/div> &lt;p>Notice that the first command is only run on the first occurrence and the second is run on all using the &lt;code>g&lt;/code> flag. Keep in mind that it works on a &lt;em>line-by-line&lt;/em> basis. &lt;/p> &lt;p>Another important aspect is &lt;em>in-place&lt;/em> alteration of files:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>sed&lt;span class="w"> &lt;/span>-i&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>EXT&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>COMMAND&lt;span class="w"> &lt;/span>FILE &lt;/code>&lt;/pre>&lt;/div> &lt;p>This command will edit &lt;span class="caps">FILE&lt;/span> using &lt;span class="caps">COMMAND&lt;/span> and if the extension &lt;span class="caps">EXT&lt;/span> is given then a backup is saved to the &lt;span class="caps">FILE&lt;/span> with &lt;span class="caps">EXT&lt;/span> appended to the filename. It is generally recommended to produce backup files so nothing is lost unintentionally.&lt;/p> &lt;h4>2. Group matching&lt;/h4> &lt;p>Often it is necessary to match some block of data and substitute some portions without removing other parts, or to alter the order of blocks. A group is matched using parentheses in the command and referenced with &lt;code>\\1&lt;/code>,&lt;code>\\2&lt;/code>.. etc., for instance:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="nb">echo&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">"foobar"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="w"> &lt;/span>sed&lt;span class="w"> &lt;/span>&lt;span class="s1">'s/\\(foo\\)\\(bar\\)/\\2\\1/'&lt;/span> barfoo &lt;/code>&lt;/pre>&lt;/div> &lt;p>Two groups are matched (“foo” and “bar”) and their order is reversed. Notice that the parentheses have to be escaped in order to prevent matching the actual characters “(” and “)”.&lt;/p> &lt;h4>3. Extended regular expressions&lt;/h4> &lt;p>The expressions I have used up until now were basic regular expressions but a more powerful variant exists, namely the extended regular expressions. In this mode, along with a lot of stuff, it’s not necessary to escape parentheses and the &lt;span class="caps">POSIX&lt;/span> character sets are available. Example:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="nb">echo&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">"foo \\t bar"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="w"> &lt;/span>sed&lt;span class="w"> &lt;/span>-E&lt;span class="w"> &lt;/span>&lt;span class="s1">'s/(foo)[[:space:]]*(bar)/\\2 \\1/'&lt;/span> bar&lt;span class="w"> &lt;/span>foo &lt;/code>&lt;/pre>&lt;/div> &lt;p>The character set &lt;code>[:space:]&lt;/code> matches any whitespace character. &lt;b>&lt;em>&lt;code>-E&lt;/code> is replaced with &lt;code>-r&lt;/code> in &lt;span class="caps">GNU&lt;/span> sed.&lt;/em>&lt;/b>&lt;/p> &lt;p>&lt;a href="http://www.grymoire.com/Unix/Regular.html" target="_blank">Here&lt;/a> is a great reference of the different regular expressions, both basic and extended ones.&lt;/p> &lt;h4>4. Case sensitivity&lt;/h4> &lt;p>In &lt;span class="caps">GNU&lt;/span> sed there is a flag to turn off case sensitivity, namely the “i” flag. Sadly this flag is not available in &lt;span class="caps">BSD&lt;/span> sed so one has to turn to other possibilities. One is to decapitalize all letters before piping to sed, but that doesn’t work for files and in-place modifications. However, case can be ignored when using character sets and similar constructs so keep that in mind, i.e. &lt;code>[:alpha:]&lt;/code> will match “A” as well as “a”. Selective parts of a regular expression can sometimes require specific characters so if one wants to match both cases it can be done using ranges, like &lt;code>[a-cA-C]&lt;/code> for instance.&lt;/p> &lt;p>Different approaches exist for decapitalizing using pipes. Here is one using &lt;code>tr&lt;/code>:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="nb">echo&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">"Hello, World"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="w"> &lt;/span>tr&lt;span class="w"> &lt;/span>&lt;span class="s1">'[:upper:]'&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">'[:lower:]'&lt;/span> hello,&lt;span class="w"> &lt;/span>world &lt;/code>&lt;/pre>&lt;/div> &lt;p>And here is one using &lt;code>awk&lt;/code>:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="nb">echo&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">"Hello, World"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="w"> &lt;/span>awk&lt;span class="w"> &lt;/span>&lt;span class="s1">'{print tolower($0)}'&lt;/span> hello,&lt;span class="w"> &lt;/span>world &lt;/code>&lt;/pre>&lt;/div> &lt;p>If all else fails Perl has a sed-like substitution syntax that accepts the “i” flag:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="nb">echo&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">"HeLlo"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="w"> &lt;/span>perl&lt;span class="w"> &lt;/span>-pe&lt;span class="w"> &lt;/span>&lt;span class="s1">'s/l/./ig'&lt;/span> He..o &lt;/code>&lt;/pre>&lt;/div> &lt;h4>5. Greedy vs non-greedy matching&lt;/h4> &lt;p>sed is greedy by default, meaning it will try to match as much as possible when using &lt;code>+&lt;/code> or &lt;code>*&lt;/code>. Here’s a greedy example:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="nb">echo&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">"aaa(bbb)aaa(bbb)aaa"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="w"> &lt;/span>sed&lt;span class="w"> &lt;/span>-E&lt;span class="w"> &lt;/span>&lt;span class="s1">'s/\\(.*\\)/./'&lt;/span> aaa.aaa &lt;/code>&lt;/pre>&lt;/div> &lt;p>The above matches a “(” then anything greedily until next “)”. Suppose we wanted to only match the first “(bbb)” and not “(bbb)aaa(bbb)”, then we could do the following:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="nb">echo&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">"aaa(bbb)aaa(bbb)aaa"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="w"> &lt;/span>sed&lt;span class="w"> &lt;/span>-E&lt;span class="w"> &lt;/span>&lt;span class="s1">'s/\\([^\\(]*\\)/./'&lt;/span> aaa.aaa&lt;span class="o">(&lt;/span>bbb&lt;span class="o">)&lt;/span>aaa &lt;/code>&lt;/pre>&lt;/div> &lt;p>As before it matches a “(” then matching non-greedily for “(” (meaning &lt;em>not&lt;/em> matching a “(“) until we match the closing “)”.&lt;/p> &lt;h4>6. Examples&lt;/h4> &lt;p>A friend of mine recently asked me how to replace entries of the form “&amp;lt;email address&amp;gt;” with “&amp;lt;—removed—&amp;gt;” using sed. The following was the solution:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>cat&lt;span class="w"> &lt;/span>file.txt&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="w"> &lt;/span>sed&lt;span class="w"> &lt;/span>-E&lt;span class="w"> &lt;/span>&lt;span class="s1">'s/(&amp;lt;).*@.*(&amp;gt;)/\\1--removed--\\2/g'&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>It’s not a correct regexp for matching email addresses but given the knowledge of the presence of &amp;lt;, &amp;gt; and @ it was fitting in his scenario.&lt;/p> &lt;p>The proper way of doing it would be the following:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>cat&lt;span class="w"> &lt;/span>file.txt&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="w"> &lt;/span>sed&lt;span class="w"> &lt;/span>-E&lt;span class="w"> &lt;/span>&lt;span class="s1">'s/(&amp;lt;)[[:alpha:][:digit:]\\._%\\+-]+@[[:alpha:][:digit:]\\.-]+\\.[[:alpha:]]{2,4}(&amp;gt;)/\\1--removed--\\2/g'&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Another useful thing is to escape spaces in filenames and use them with commands:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="ch">#!/bin/sh&lt;/span> &lt;span class="nv">DIR&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="sb">`&lt;/span>&lt;span class="nb">echo&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">$1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="w"> &lt;/span>sed&lt;span class="w"> &lt;/span>&lt;span class="s1">'s/ /\\\\\\\\ /g'&lt;/span>&lt;span class="sb">`&lt;/span> &lt;span class="nb">eval&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">echo&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">"Listing &lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="nv">DIR&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">:"&lt;/span> &lt;span class="nb">eval&lt;/span>&lt;span class="w"> &lt;/span>ls&lt;span class="w"> &lt;/span>-l&lt;span class="w"> &lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="nv">DIR&lt;/span>&lt;span class="si">}&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>I used &lt;em>double-escaped backslashes&lt;/em> because the final output should be, for instance, “/test\ one\ seven/foobar.txt” and not “/test one seven/foobar.txt” so that the commands can interpret the paths correctly (using the &lt;code>eval&lt;/code> command). The effect is that the script can be called with both an escaped or non-escaped path, i.e. &lt;code>"/test one seven"&lt;/code> or &lt;code>/test\\ one\\ seven&lt;/code>.&lt;/p> &lt;p>When creating a Linux distribution of a program or similar that is required to run off-the-bat, and where the source code might not be available, it is often needed to get all the shared library dependencies of certain binary files. The following script will copy these to the destination directory: &lt;b>(Linux only!)&lt;/b>&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="ch">#!/bin/sh&lt;/span> &lt;span class="c1"># Usage: getshared.sh &amp;lt;binary&amp;gt; &amp;lt;dest directory&amp;gt;&lt;/span> &lt;span class="nv">BIN&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="sb">`&lt;/span>&lt;span class="nb">echo&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">$1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="w"> &lt;/span>sed&lt;span class="w"> &lt;/span>&lt;span class="s1">'s/ /\\\\\\\\ /g'&lt;/span>&lt;span class="sb">`&lt;/span> &lt;span class="nv">DST&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="sb">`&lt;/span>&lt;span class="nb">echo&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nv">$2&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="w"> &lt;/span>sed&lt;span class="w"> &lt;/span>&lt;span class="s1">'s/ /\\\\\\\\ /g'&lt;/span>&lt;span class="sb">`&lt;/span> &lt;span class="nb">eval&lt;/span>&lt;span class="w"> &lt;/span>mkdir&lt;span class="w"> &lt;/span>-p&lt;span class="w"> &lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="nv">DST&lt;/span>&lt;span class="si">}&lt;/span> &lt;span class="nb">eval&lt;/span>&lt;span class="w"> &lt;/span>ldd&lt;span class="w"> &lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="nv">BIN&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="w"> &lt;/span>grep&lt;span class="w"> &lt;/span>&lt;span class="s2">"=&amp;gt;"&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="w"> &lt;/span>sed&lt;span class="w"> &lt;/span>&lt;span class="s1">'s/.*\\s*=&amp;gt;\\s*\\(.*\\)(.*)/\\1/'&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="w"> &lt;/span>awk&lt;span class="w"> &lt;/span>&lt;span class="s1">'{print $1};'&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">eval&lt;/span>&lt;span class="w"> &lt;/span>xargs&lt;span class="w"> &lt;/span>-I&lt;span class="o">{}&lt;/span>&lt;span class="w"> &lt;/span>cp&lt;span class="w"> &lt;/span>-vuL&lt;span class="w"> &lt;/span>&lt;span class="o">{}&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="nv">DST&lt;/span>&lt;span class="si">}&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Here the sed command retrieves the dependency library from the output using the &lt;code>\\1&lt;/code> group. A sample line from &lt;code>ldd&lt;/code> could be&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>libc.so.6&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&amp;gt;&lt;span class="w"> &lt;/span>/usr/x86_64-linux-gnu/libc.so.6&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>0x00007f6eb8c000&lt;span class="o">)&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Assume we have a file we want to modify in-place, like an &lt;span class="caps">INI&lt;/span> configuration file like this:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="k">[Section]&lt;/span> &lt;span class="na">enableStuff&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">false&lt;/span>&lt;span class="w"> &lt;/span> &lt;span class="na">someVar&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">1337&lt;/span> &lt;span class="na">enableOther&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">false&lt;/span> &lt;span class="na">dontTouchThis&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">"wicked"&lt;/span> &lt;span class="na">oldSchool&lt;/span>&lt;span class="o">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">false&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>And let’s say we wanted to replace all instances of “false” with “true”:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>sed&lt;span class="w"> &lt;/span>-i&lt;span class="w"> &lt;/span>.bck&lt;span class="w"> &lt;/span>-E&lt;span class="w"> &lt;/span>&lt;span class="s1">'s/([[:alnum:]]+)[^\\s]*([=:])[^\\s]*false/\\1\\2true/'&lt;/span>&lt;span class="w"> &lt;/span>conf.ini &lt;/code>&lt;/pre>&lt;/div> &lt;p>You will get the following result in &lt;code>conf.ini&lt;/code> (along with the backup in &lt;code>conf.ini.bck&lt;/code>):&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="k">[Section]&lt;/span> &lt;span class="na">enableStuff&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">true&lt;/span>&lt;span class="w"> &lt;/span> &lt;span class="na">someVar&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">1337&lt;/span> &lt;span class="na">enableOther&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">true&lt;/span> &lt;span class="na">dontTouchThis&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">"wicked"&lt;/span> &lt;span class="na">oldSchool&lt;/span>&lt;span class="o">:&lt;/span>&lt;span class="s">true&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Notice that I remove all whitespace and that I allow both “=” and “:” as the delimiter because some implementations use “:” however uncommon it may be.&lt;/p> &lt;p>That concludes my tips and tricks using sed.&lt;/p></content><category term="Shell"/><category term="sed"/><category term="bsd"/><category term="gnu"/></entry><entry><title>Upgrading to Xcode 4.4 or later</title><link href="https://www.mortens.dev/blog/upgrading-to-xcode-4-4-or-later/" rel="alternate"/><published>2013-02-03T22:13:56+02:00</published><updated>2013-02-03T22:13:56+02:00</updated><author><name>Morten</name></author><id>tag:www.mortens.dev,2013-02-03:/blog/upgrading-to-xcode-4-4-or-later/</id><summary type="html">&lt;p>Upgrading to Xcode 4.4 or&amp;nbsp;later&lt;/p></summary><content type="html">&lt;p>Xcode moved to the App Store as of version 4.4 and it had certain consequences to the common programmer. First of all, the SDKs are no longer located at “/Developer/SDKs” like they were before. The app is located at “/Applications/Xcode.app” on a default install and it contains the SDKs in the directory:&lt;/p> &lt;p>&lt;blockquote class="blockquote">/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs&lt;/blockquote>&lt;/p> &lt;p>All command-line tools are no longer installed per default either so in order to install them open Xcode, go to “Preferences”, select the “Downloads”, choose “Components” and install “Command Line Tools”.&lt;/p> &lt;p>In order to configure the &lt;span class="caps">BSD&lt;/span> tools correctly it is needed to instruct where Xcode is installed. It is done like this:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>xcode-select&lt;span class="w"> &lt;/span>--switch&lt;span class="w"> &lt;/span>/Applications/Xcode.app/Contents/Developer &lt;/code>&lt;/pre>&lt;/div> &lt;p>Another important change of Xcode 4.4+ is the discontinuation of the 10.6 &lt;span class="caps">SDK&lt;/span>. When installing, or updating, 4.4+ it will only have SDKs 10.7 and 10.8. If 10.6 is installed it will be &lt;em>removed&lt;/em>. So if you have 4.3 or earlier installed I recommend that you backup 10.6 if you need it for development. The &lt;span class="caps">SDK&lt;/span> contains a lot of symbolic links so it’s important to &lt;i>not&lt;/i> follow them:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>zip&lt;span class="w"> &lt;/span>-r9&lt;span class="w"> &lt;/span>--symlink&lt;span class="w"> &lt;/span>/path/to/store/sdk-10.6.zip&lt;span class="w"> &lt;/span>/Developer/SDKs/MacOSX10.6.sdk &lt;/code>&lt;/pre>&lt;/div> &lt;p>If you don’t have &lt;span class="caps">SDK&lt;/span> 10.6 and want it you can follow these steps:&lt;/p> &lt;ol> &lt;li>Go to &lt;a href="https://developer.apple.com/downloads/index.action" target="_blank" title="https://developer.apple.com/downloads/index.action">https://developer.apple.com/downloads/index.action&lt;/a>&lt;/li> &lt;li>You have to login which thus requires an Apple Developer account.&lt;/li> &lt;li>Filter the search with “Xcode 4 and iOS &lt;span class="caps">SDK&lt;/span> 4.3”.&lt;/li> &lt;li>Download “Xcode 4 and iOS &lt;span class="caps">SDK&lt;/span> 4.3 - Final” &lt;span class="caps">DMG&lt;/span> (4.28 &lt;span class="caps">GB&lt;/span>).&lt;/li> &lt;li>Open the &lt;span class="caps">DMG&lt;/span> to mount it and go to “/Volumes/Xcode and iOS &lt;span class="caps">SDK&lt;/span>/Packages”.&lt;/li> &lt;li>You will find the file “MacOSX10.6.pkg” there which contains the &lt;span class="caps">SDK&lt;/span>.&lt;/li> &lt;/ol> &lt;p>I personally use &lt;span class="caps">SDK&lt;/span> 10.6 on a daily basis for work so I have to have it installed at all times. And since Xcode will remove it if put into its &lt;span class="caps">SDK&lt;/span> directory on update I have instead created the old directory “/Developer/SDKs” and put the &lt;span class="caps">SDK&lt;/span> there. Then I put symbolic links to the new SDKs 10.7 and 10.8.&lt;/p></content><category term="IDE"/><category term="xcode"/></entry><entry><title>Profiling with Instruments.app</title><link href="https://www.mortens.dev/blog/profiling-with-instruments-app/" rel="alternate"/><published>2013-02-02T23:23:13+02:00</published><updated>2013-02-02T23:23:13+02:00</updated><author><name>Morten</name></author><id>tag:www.mortens.dev,2013-02-02:/blog/profiling-with-instruments-app/</id><summary type="html">&lt;p>Profiling with Instruments.app to detect memory leaks and inspect call&amp;nbsp;trees&lt;/p></summary><content type="html">&lt;p>Profiling binaries is essential in any serious development process. Unfortunately not very many good profilers exist out there. I usually employ &lt;a href="http://valgrind.org">Valgrind&lt;/a> to detect memory leaks and the front-end &lt;a href="http://kcachegrind.sourceforge.net">KCachegrind&lt;/a> to inspect call stacks. But KCachegrind requires both X11 and &lt;span class="caps">KDE3&lt;/span> libs which I want to avoid. However, last week I discovered &lt;span style="text-decoration: underline;">Instruments.app&lt;/span> that comes with Xcode. It’s a great profiler with lots of different modes, like detecting memory leaks, tracking heap allocations, detection of “zombie” objects, time-based profiling, performance monitor counter (&lt;span class="caps">PMC&lt;/span>) based sampling, event-based sampling, file activity, sudden termination analysis and much more. &lt;em>But Instruments.app is not good at finding uninitialized variables like Valgrind is among other things - so this is not a direct substitution!&lt;/em>&lt;/p> &lt;p>The app is located here:&lt;/p> &lt;p>&lt;blockquote class="blockquote">/Applications/Xcode.app/Contents/Applications/Instruments.app&lt;/blockquote>&lt;/p> &lt;p>Let’s write a little program with a memory leak that we want the program to detect for us.&lt;/p> &lt;p>Save the following code to a file named “memleak.cpp”:&lt;/p> &lt;div class="highlight">&lt;pre>&lt;span>&lt;/span>&lt;code>&lt;span class="cp">#include&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="cpf">&amp;lt;unistd.h&amp;gt;&lt;/span> &lt;span class="kt">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">main&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">argc&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">char&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">**&lt;/span>&lt;span class="n">argv&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">10&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="kt">char&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="n">test&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">char&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">1024&lt;/span>&lt;span class="p">];&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="n">sleep&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span> &lt;span class="w"> &lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span> &lt;/code>&lt;/pre>&lt;/div> &lt;p>Compile the program and run Instruments.app. When it starts select the “Leaks” template in the “Mac &lt;span class="caps">OS&lt;/span> X” section and click “Choose”. A new window opens up showing two instruments; one for allocations and one for explicit memory leaks. Before one can record anything the program to profile has to be chosen in the “Choose Target” drop-down menu. Click “Record” and wait for the program to terminate (after 10 seconds) and you’ll have the following results:&lt;/p> &lt;p>&lt;a href="https://www.mortens.dev/images/instruments-app-1.png">&lt;img alt="Instruments.app showing memory leaks in memleak.cpp" class="img-fluid" src="https://www.mortens.dev/images/instruments-app-1.png" width="800"/>&lt;/a>&lt;/p> &lt;p>Clicking the “Leaks” instrument you will see:&lt;/p> &lt;p>&lt;a href="https://www.mortens.dev/images/instruments-app-2.png">&lt;img alt="Instruments.app showing memory leaks in memleak.cpp" class="img-fluid" src="https://www.mortens.dev/images/instruments-app-2.png" width="800"/>&lt;/a>&lt;/p> &lt;p>Just to show the difference try inserting &lt;code>delete[] test;&lt;/code> after line 5 in the code, recompile and re-record the analysis. You’ll see the following:&lt;/p> &lt;p>&lt;a href="https://www.mortens.dev/images/instruments-app-3.png">&lt;img alt="Instruments.app showing no memory leaks in memleak.cpp" class="img-fluid" src="https://www.mortens.dev/images/instruments-app-3.png" width="800"/>&lt;/a>&lt;/p> &lt;p>Sometimes it’s necessary and insightful to gaze upon the call stacks:&lt;/p> &lt;p>&lt;a href="https://www.mortens.dev/images/instruments-app-4.png">&lt;img alt="Instruments.app showing call stack in memleak.cpp" class="img-fluid" src="https://www.mortens.dev/images/instruments-app-4.png" width="800"/>&lt;/a>Furthermore, any system libraries and missing symbols can be hidden in the “Call Tree” sidebar for convenience. If the program was compiled with debugging symbols (use &lt;code>-g&lt;/code> with &lt;span class="caps">GCC&lt;/span> or Clang, for instance) the source code along with the machine code can be shown by double-clicking an entry:&lt;/p> &lt;p>&lt;a href="https://www.mortens.dev/images/instruments-app-5.png">&lt;img alt="Instruments.app showing machine code for memleak.cpp" class="img-fluid" src="https://www.mortens.dev/images/instruments-app-5.png" width="800"/>&lt;/a>&lt;/p> &lt;p>In any case, I will try using this profiler more at work and see if I find more interesting features to share.&lt;/p></content><category term="Profiling"/><category term="profiling"/><category term="cpp"/><category term="xcode"/></entry></feed>