diff options
author | johannst <johannst@users.noreply.github.com> | 2020-03-17 22:48:49 +0000 |
---|---|---|
committer | johannst <johannst@users.noreply.github.com> | 2020-03-17 22:48:49 +0000 |
commit | 2a064a9d1bbb8de6ce489b685cce026eee167cd2 (patch) | |
tree | 123cdb825636f0bfe98ef152ace16eb8b3ae2647 /print.html | |
parent | 21e8db012f8c46f75e43a40da3f3e2676363c291 (diff) | |
download | notes-2a064a9d1bbb8de6ce489b685cce026eee167cd2.tar.gz notes-2a064a9d1bbb8de6ce489b685cce026eee167cd2.zip |
deploy: fb719f52b73920fb18c7f3080ebb1fc73300be49
Diffstat (limited to 'print.html')
-rw-r--r-- | print.html | 424 |
1 files changed, 258 insertions, 166 deletions
@@ -83,7 +83,7 @@ <nav id="sidebar" class="sidebar" aria-label="Table of contents"> <div id="sidebar-scrollbox" class="sidebar-scrollbox"> - <ol class="chapter"><li class="expanded "><a href="ld.so.html"><strong aria-hidden="true">1.</strong> ld.so</a></li><li class="expanded "><a href="git.html"><strong aria-hidden="true">2.</strong> git</a></li><li class="expanded "><a href="gdb.html"><strong aria-hidden="true">3.</strong> gdb</a></li><li class="expanded "><a href="radare2.html"><strong aria-hidden="true">4.</strong> radare2</a></li><li class="expanded "><a href="emacs.html"><strong aria-hidden="true">5.</strong> emacs</a></li><li class="expanded "><a href="fish.html"><strong aria-hidden="true">6.</strong> fish</a></li><li class="expanded "><a href="strace.html"><strong aria-hidden="true">7.</strong> strace</a></li><li class="expanded "><a href="lsof.html"><strong aria-hidden="true">8.</strong> lsof</a></li><li class="expanded "><a href="pidstat.html"><strong aria-hidden="true">9.</strong> pidstat</a></li><li class="expanded "><a href="time.html"><strong aria-hidden="true">10.</strong> time</a></li><li class="expanded "><a href="pmap.html"><strong aria-hidden="true">11.</strong> pmap</a></li><li class="expanded "><a href="pstack.html"><strong aria-hidden="true">12.</strong> pstack</a></li><li class="expanded "><a href="perf.html"><strong aria-hidden="true">13.</strong> perf</a></li><li class="expanded "><a href="oprofile.html"><strong aria-hidden="true">14.</strong> OProfile</a></li><li class="expanded "><a href="od.html"><strong aria-hidden="true">15.</strong> od</a></li><li class="expanded "><a href="xxd.html"><strong aria-hidden="true">16.</strong> xxd</a></li><li class="expanded "><a href="readelf.html"><strong aria-hidden="true">17.</strong> readelf</a></li><li class="expanded "><a href="objdump.html"><strong aria-hidden="true">18.</strong> objdump</a></li><li class="expanded "><a href="nm.html"><strong aria-hidden="true">19.</strong> nm</a></li><li class="expanded "><a href="c++filt.html"><strong aria-hidden="true">20.</strong> c++filt</a></li></ol> + <ol class="chapter"><li class="expanded "><a href="ld.so.html"><strong aria-hidden="true">1.</strong> ld.so</a></li><li class="expanded "><a href="git.html"><strong aria-hidden="true">2.</strong> git</a></li><li class="expanded "><a href="awk.html"><strong aria-hidden="true">3.</strong> awk</a></li><li class="expanded "><a href="gdb.html"><strong aria-hidden="true">4.</strong> gdb</a></li><li class="expanded "><a href="radare2.html"><strong aria-hidden="true">5.</strong> radare2</a></li><li class="expanded "><a href="emacs.html"><strong aria-hidden="true">6.</strong> emacs</a></li><li class="expanded "><a href="fish.html"><strong aria-hidden="true">7.</strong> fish</a></li><li class="expanded "><a href="strace.html"><strong aria-hidden="true">8.</strong> strace</a></li><li class="expanded "><a href="lsof.html"><strong aria-hidden="true">9.</strong> lsof</a></li><li class="expanded "><a href="pidstat.html"><strong aria-hidden="true">10.</strong> pidstat</a></li><li class="expanded "><a href="time.html"><strong aria-hidden="true">11.</strong> time</a></li><li class="expanded "><a href="pgrep.html"><strong aria-hidden="true">12.</strong> pgrep</a></li><li class="expanded "><a href="pstack.html"><strong aria-hidden="true">13.</strong> pstack</a></li><li class="expanded "><a href="pstack.html"><strong aria-hidden="true">14.</strong> pstack</a></li><li class="expanded "><a href="perf.html"><strong aria-hidden="true">15.</strong> perf</a></li><li class="expanded "><a href="oprofile.html"><strong aria-hidden="true">16.</strong> OProfile</a></li><li class="expanded "><a href="od.html"><strong aria-hidden="true">17.</strong> od</a></li><li class="expanded "><a href="xxd.html"><strong aria-hidden="true">18.</strong> xxd</a></li><li class="expanded "><a href="readelf.html"><strong aria-hidden="true">19.</strong> readelf</a></li><li class="expanded "><a href="objdump.html"><strong aria-hidden="true">20.</strong> objdump</a></li><li class="expanded "><a href="nm.html"><strong aria-hidden="true">21.</strong> nm</a></li><li class="expanded "><a href="c++filt.html"><strong aria-hidden="true">22.</strong> c++filt</a></li></ol> </div> <div id="sidebar-resize-handle" class="sidebar-resize-handle"></div> </nav> @@ -151,16 +151,18 @@ <div id="content" class="content"> <main> <h1><a class="header" href="#ldso8" id="ldso8">ld.so(8)</a></h1> -<h2><a class="header" href="#environment-variables" id="environment-variables">Environment variables</a></h2> +<h2><a class="header" href="#environment-variables" id="environment-variables">Environment Variables</a></h2> <pre><code class="language-console"> LD_PRELOAD=<l_so> colon separated list of libso's to be pre loaded - LD_DEBUG=<opts> comman separated list of debug options + LD_DEBUG=<opts> comma separated list of debug options =help list available options =libs show library search path =files processing of input files =symbols show search path for symbol lookup =bindings show against which definition a symbol is bound </code></pre> -<h2><a class="header" href="#ld_preload-load--init-order" id="ld_preload-load--init-order">LD_PRELOAD load & init order</a></h2> +<h2><a class="header" href="#ld_preload-initialization-order-and-link-map" id="ld_preload-initialization-order-and-link-map">LD_PRELOAD: Initialization Order and Link Map</a></h2> +<p>Libraries specified in <code>LD_PRELOAD</code> are loaded from <code>left-to-right</code> but +initialized from <code>right-to-left</code>.</p> <pre><code class="language-markdown"> > ldd ./main >> libc.so.6 => /usr/lib/libc.so.6 @@ -169,97 +171,106 @@ preloaded in this order <-- initialized in this order - - - preload order determines the order libs are inserted into the link map - - - resulting link map: - +------+ +------+ +------+ +------+ - | main | -> | liba | -> | libb | -> | libc | - +------+ +------+ +------+ +------+ - - - see preload and init order in action - > LD_DEBUG=files LD_PRELOAD=liba.so:libb.so ./main - # load order (-> determines link map) - >> file=liba.so [0]; generating link map - >> file=libb.so [0]; generating link map - >> file=libc.so.6 [0]; generating link map - - # init order - >> calling init: /usr/lib/libc.so.6 - >> calling init: <path>/libb.so - >> calling init: <path>/liba.so - >> initialize program: ./main - - - see the symbol lookup in action and therefore the link map order - > LD_DEBUG=symbols,bindings LD_PRELOAD=liba.so:libb.so ./main - >> symbol=memcpy; lookup in file=./main [0] - >> symbol=memcpy; lookup in file=<path>/liba.so [0] - >> symbol=memcpy; lookup in file=<path>/libb.so [0] - >> symbol=memcpy; lookup in file=/usr/lib/libc.so.6 [0] - >> binding file ./main [0] to /usr/lib/libc.so.6 [0]: normal symbol - `memcpy' [GLIBC_2.14] -</code></pre> -<h2><a class="header" href="#dynamic-linking-x86_64" id="dynamic-linking-x86_64">dynamic linking (x86_64)</a></h2> -<pre><code class="language-makrdown"> - dynamic linking basically works via one indirect jump. It uses a - combination of function trampolines (.plt) and a function pointer table - (.got.plt). On the first call the trampoline sets up some metadata and - then jumps to the ld.so runtime resolve function, which in turn patches - the table with the correct function pointer. - .plt ....... contains function trampolines, usually located in code - segment (rx permission) - .got.plt ... hold the function pointer table - - - following r2 dump shows this - - [0x00401030] indirect jump for 'puts' using function pointer in - _GLOBAL_OFFSET_TABLE_[3] - - initially points to instruction behind 'puts' trampoline [0x00401036] - - this pushes relocation index and then jumps to the first trampoline - [0x00401020] - - the first trampoline jumps to _GLOBAL_OFFSET_TABLE_[2] which will be - filled at program startup by the ld.so with its resolve function - - the resolve function fixes the relocation referenced by the - relocation index pushed by the 'puts' trampoline - - the relocation entry tells the resolve function which symbol to - search for and where to put the function pointer - > readelf -r <main> - >> Relocation section '.rela.plt' at offset 0x4b8 contains 1 entry: - >> Offset Info Type Sym. Value Sym. Name + Addend - >> 000000404018 000200000007 R_X86_64_JUMP_SLO 0000000000000000 puts@GLIBC_2.2.5 + 0 - - offset points to _GLOBAL_OFFSET_TABLE_[3] - - [0x00401040]> pd 4 @ section..got.plt - ;-- section..got.plt: - ;-- .got.plt: ; [22] -rw- section size 32 named .got.plt - ;-- _GLOBAL_OFFSET_TABLE_: - 0x00404000 .qword 0x0000000000403e10 ; section..dynamic ; obj._DYNAMIC - 0x00404008 .qword 0x0000000000000000 - ; CODE XREF from section..plt @ +0x6 - 0x00404010 .qword 0x0000000000000000 - ;-- reloc.puts: - ; CODE XREF from sym.imp.puts @ 0x401030 - 0x00404018 .qword 0x0000000000401036 ; RELOC 64 puts - - [0x00401040]> pd 6 @ section..plt - ;-- section..plt: - ;-- .plt: ; [12] -r-x section size 32 named .plt - ┌─> 0x00401020 ff35e22f0000 push qword [0x00404008] - ╎ 0x00401026 ff25e42f0000 jmp qword [0x00404010] - ╎ 0x0040102c 0f1f4000 nop dword [rax] - ┌ 6: int sym.imp.puts (const char *s); - └ ╎ 0x00401030 ff25e22f0000 jmp qword [reloc.puts] - ╎ 0x00401036 6800000000 push 0 - └─< 0x0040103b e9e0ffffff jmp sym..plt </code></pre> +<p>The preload order determines:</p> +<ul> +<li>the order libraries are inserted into the <code>link map</code></li> +<li>the initialization order for libraries</li> +</ul> +<p>For the example listed above the resulting <code>link map</code> will look like the +following:</p> +<pre><code class="language-makrdown"> +------+ +------+ +------+ +------+ + | main | -> | liba | -> | libb | -> | libc | + +------+ +------+ +------+ +------+ +</code></pre> +<p>This can be seen when running with <code>LD_DEBUG=files</code>:</p> +<pre><code class="language-makrdown"> > LD_DEBUG=files LD_PRELOAD=liba.so:libb.so ./main + # load order (-> determines link map) + >> file=liba.so [0]; generating link map + >> file=libb.so [0]; generating link map + >> file=libc.so.6 [0]; generating link map + + # init order + >> calling init: /usr/lib/libc.so.6 + >> calling init: <path>/libb.so + >> calling init: <path>/liba.so + >> initialize program: ./main +</code></pre> +<p>To verify the <code>link map</code> order we let <code>ld.so</code> resolve the <code>memcpy(3)</code> libc +symbol (used in <em>main</em>) dynamically, while enabling <code>LD_DEBUG=symbols,bindings</code> +to see the resolving in action.</p> +<pre><code class="language-makrdown"> > LD_DEBUG=symbols,bindings LD_PRELOAD=liba.so:libb.so ./main + >> symbol=memcpy; lookup in file=./main [0] + >> symbol=memcpy; lookup in file=<path>/liba.so [0] + >> symbol=memcpy; lookup in file=<path>/libb.so [0] + >> symbol=memcpy; lookup in file=/usr/lib/libc.so.6 [0] + >> binding file ./main [0] to /usr/lib/libc.so.6 [0]: normal symbol `memcpy' [GLIBC_2.14] +</code></pre> +<h2><a class="header" href="#dynamic-linking-x86_64" id="dynamic-linking-x86_64">Dynamic Linking (x86_64)</a></h2> +<p>Dynamic linking basically works via one indirect jump. It uses a combination of +function trampolines (<code>.plt</code> section) and a function pointer table (<code>.got.plt</code> +section). +On the first call the trampoline sets up some metadata and then jumps to the +<code>ld.so</code> runtime resolve function, which in turn patches the table with the +correct function pointer.</p> +<pre><code class="language-makrdown"> .plt ....... procedure linkage table, contains function trampolines, usually + located in code segment (rx permission) + .got.plt ... global offset table for .plt, holds the function pointer table +</code></pre> +<p>Using <code>radare2</code> we can analyze this in more detail:</p> +<pre><code class="language-makrdown"> [0x00401040]> pd 4 @ section..got.plt + ;-- section..got.plt: + ;-- .got.plt: ; [22] -rw- section size 32 named .got.plt + ;-- _GLOBAL_OFFSET_TABLE_: + [0] 0x00404000 .qword 0x0000000000403e10 ; section..dynamic + [1] 0x00404008 .qword 0x0000000000000000 + ; CODE XREF from section..plt @ +0x6 + [2] 0x00404010 .qword 0x0000000000000000 + ;-- reloc.puts: + ; CODE XREF from sym.imp.puts @ 0x401030 + [3] 0x00404018 .qword 0x0000000000401036 ; RELOC 64 puts + + [0x00401040]> pd 6 @ section..plt + ;-- section..plt: + ;-- .plt: ; [12] -r-x section size 32 named .plt + ┌─> 0x00401020 ff35e22f0000 push qword [0x00404008] + ╎ 0x00401026 ff25e42f0000 jmp qword [0x00404010] + ╎ 0x0040102c 0f1f4000 nop dword [rax] + ┌ 6: int sym.imp.puts (const char *s); + └ ╎ 0x00401030 ff25e22f0000 jmp qword [reloc.puts] + ╎ 0x00401036 6800000000 push 0 + └─< 0x0040103b e9e0ffffff jmp sym..plt +</code></pre> +<ul> +<li>At address <code>0x00401030</code> in the <code>.plt</code> section we see the indirect jump for +<code>puts</code> using the function pointer in <code>_GLOBAL_OFFSET_TABLE_[3] (GOT)</code>.</li> +<li><code>GOT[3]</code> initially points to instruction after the <code>puts</code> trampoline +<code>0x00401036</code>.</li> +<li>This pushes the relocation index <code>0</code> and then jumps to the first trampoline +<code>0x00401020</code>.</li> +<li>The first trampoline jumps to <code>GOT[2]</code> which will be filled at program +startup by the <code>ld.so</code> with its resolve function.</li> +<li>The <code>ld.so</code> resolve function fixes the relocation referenced by the +relocation index pushed by the <code>puts</code> trampoline.</li> +<li>The relocation entry at index <code>0</code> tells the resolve function which symbol to +search for and where to put the function pointer: +<pre><code class="language-makrdown"> > readelf -r <main> + >> Relocation section '.rela.plt' at offset 0x4b8 contains 1 entry: + >> Offset Info Type Sym. Value Sym. Name + Addend + >> 000000404018 000200000007 R_X86_64_JUMP_SLO 0000000000000000 puts@GLIBC_2.2.5 + 0 +</code></pre> +As we can see the offset from relocation at index <code>0</code> points to <code>GOT[3]</code>.</li> +</ul> <h1><a class="header" href="#git1" id="git1">git(1)</a></h1> -<h2><a class="header" href="#misc" id="misc">Misc</a></h2> +<h2><a class="header" href="#staging" id="staging">staging</a></h2> <pre><code class="language-markdown"> git add -p [<file>] ............ partial staging (interactive) </code></pre> -<h2><a class="header" href="#remote" id="remote">remote</a></h2> +<h2><a class="header" href="#remote" id="remote">Remote</a></h2> <pre><code class="language-markdown"> git remote -v .................. list remotes verbose (with URLs) git remote show [-n] <remote> .. list info for <remote> (like remote HEAD, remote branches, tracking mapping) </code></pre> -<h2><a class="header" href="#branching" id="branching">branching</a></h2> +<h2><a class="header" href="#branching" id="branching">Branching</a></h2> <pre><code class="language-markdown"> git branch [-a] ................ list available branches; -a to include remote branches git branch -vv ................. list branch & annotate with head sha1 & @@ -269,7 +280,7 @@ git push -u origin <rbname> .... push branch to origin (or other remote), and setup <rbname> as tracking branch </code></pre> -<h2><a class="header" href="#resetting" id="resetting">resetting</a></h2> +<h2><a class="header" href="#resetting" id="resetting">Resetting</a></h2> <pre><code class="language-markdown"> git reset [opt] <ref|commit> opt: --mixed .................... resets index, but not working tree @@ -281,25 +292,26 @@ git reset --soft HEAD~1 ........ delete most recent commit but keep work git reset --hard HEAD~1 ........ delete most recent commit and delete work </code></pre> -<h2><a class="header" href="#tags" id="tags">tags</a></h2> +<h2><a class="header" href="#tags" id="tags">Tags</a></h2> <pre><code class="language-markdown"> git tag -a <tname> -m "descr" ........ creates an annotated tag (full object containing tagger, date, ...) git tag -l ........................... list available tags git checkout tag/<tname> ............. checkout specific tag git checkout tag/<tname> -b <bname> .. checkout specific tag in a new branch </code></pre> -<h2><a class="header" href="#diff" id="diff">diff</a></h2> +<h2><a class="header" href="#diff" id="diff">Diff</a></h2> <pre><code class="language-markdown"> git diff HEAD:<fname> origin/HEAD:<fname> ... diff files for different refs git diff -U$(wc -l <fname>) <fname> ......... shows complete file with diffs instead of usual diff snippets </code></pre> -<h2><a class="header" href="#log" id="log">log</a></h2> +<h2><a class="header" href="#log" id="log">Log</a></h2> <pre><code class="language-markdown"> git log --oneline .... shows log in single line per commit -> alias for '--pretty=oneline --abbrev-commit' git log --graph ...... text based graph of commit history git log --decorate ... decorate log with REFs + git log -p <file> .... show commit history + diffs for <file> </code></pre> -<h2><a class="header" href="#patching" id="patching">patching</a></h2> +<h2><a class="header" href="#patching" id="patching">Patching</a></h2> <pre><code class="language-markdown"> git format-patch <opt> <since>/<revision range> opt: -N ................... use [PATCH] instead [PATCH n/m] in subject when @@ -323,7 +335,7 @@ # generate single patch file from a certain commit/ref git format-patch <COMMIT/REF> --stdout > my-patch.patch </code></pre> -<h2><a class="header" href="#submodules" id="submodules">submodules</a></h2> +<h2><a class="header" href="#submodules" id="submodules">Submodules</a></h2> <pre><code class="language-markdown"> git submodule add <url> [<path>] .......... add new submodule to current project git clone --recursive <url> ............... clone project and recursively all submodules (same as using @@ -337,18 +349,56 @@ origin/HEAD or a branch specified for the submodule </code></pre> -<h2><a class="header" href="#inspection" id="inspection">inspection</a></h2> +<h2><a class="header" href="#inspection" id="inspection">Inspection</a></h2> <pre><code class="language-markdown"> git ls-tree [-r] <ref> .... show git tree for <ref>, -r to recursively ls sub-trees git show <obj> ............ show <obj> git cat-file -p <obj> ..... print content of <obj> </code></pre> -<h2><a class="header" href="#revision_range" id="revision_range">revision_range</a></h2> +<h2><a class="header" href="#revision-specifier" id="revision-specifier">Revision Specifier</a></h2> <pre><code class="language-markdown"> HEAD ........ last commit HEAD~1 ...... last commit-1 HEAD~N ...... last commit-N (linear backwards when in tree structure, check difference between HEAD^ and HEAD~) git rev-list --max-parents=0 HEAD ........... first commit </code></pre> +<h1><a class="header" href="#awk1" id="awk1">awk(1)</a></h1> +<pre><code class="language-markdown">awk [opt] program [input] + -F <sepstr> field separator string (can be regex) + program awk program + input file or stdin if not file given +</code></pre> +<h2><a class="header" href="#input-processing" id="input-processing">Input processing</a></h2> +<p>Input is processed in two stages:</p> +<ol> +<li>Splitting input into a sequence of <code>records</code>. +By default split at <code>newline</code> character, but can be changed via the +builtin <code>RS</code> variable.</li> +<li>Splitting a <code>record</code> into <code>fields</code>. By default strings without <code>whitespace</code>, +but can be changed via the builtin variable <code>FS</code> or command line option +<code>-F</code>.</li> +</ol> +<p>Field are accessed as follows:</p> +<ul> +<li><code>$0</code> whole <code>record</code></li> +<li><code>$1</code> field one</li> +<li><code>$2</code> field two</li> +<li>...</li> +</ul> +<h2><a class="header" href="#program" id="program">Program</a></h2> +<p>An <code>awk</code> program is composed of pairs of the form:</p> +<pre><code class="language-markdown">pattern { action } +</code></pre> +<p>The program is run against each <code>record</code> in the input stream. If a <code>pattern</code> +matches a <code>record</code> the corresponding <code>action</code> is executed and can access the +<code>fields</code>.</p> +<pre><code class="language-markdown">INPUT + | + v +record ----> ∀ pattern matched + | | + v v +fields ----> run associated action +</code></pre> <h1><a class="header" href="#gdb1" id="gdb1">gdb(1)</a></h1> <h1><a class="header" href="#cli" id="cli">CLI</a></h1> <pre><code class="language-markdown"> gdb [opts] [prg [-c coredump | -p pid]] @@ -415,6 +465,7 @@ Create a catchpoint for <signal>. </code></pre> <h1><a class="header" href="#user-commands-macros" id="user-commands-macros">User commands (macros)</a></h1> +<p>Gdb allows to create & document user commands as follows:</p> <pre><code class="language-markdown"> define <cmd> # cmds end @@ -422,23 +473,29 @@ document <cmd> # docu end - - help user-defined List user defined commands. - help <cmd> List documentation for command <cmd>. +</code></pre> +<p>To get all user commands or documentations one can use:</p> +<pre><code class="language-markdown"> help user-defined + help <cmd> </code></pre> <h1><a class="header" href="#hooks" id="hooks">Hooks</a></h1> -<p>Gdb allows to create two types of command <code>hooks</code> which will be either executed -before or after a certain command.</p> -<pre><code class="language-markdown"> define hook-<cmd> Run commands defined in hook before - # cmds executing <cmd>. +<p>Gdb allows to create two types of command <code>hooks</code></p> +<ul> +<li><code>hook-</code> will be run before <code><cmd></code></li> +<li><code>hookpost-</code> will be run after <code><cmd></code></li> +</ul> +<pre><code class="language-markdown"> define hook-<cmd> + # cmds end - define hookpost-<cmd> Run commands defined in hookpost after - # cmds executing <cmd>. + define hookpost-<cmd> + # cmds end </code></pre> -<h1><a class="header" href="#flows" id="flows">Flows</a></h1> -<h2><a class="header" href="#catch-sigsegv-and-execute-commands-on-occurrence" id="catch-sigsegv-and-execute-commands-on-occurrence">Catch SIGSEGV and execute commands on occurrence</a></h2> +<h1><a class="header" href="#examples" id="examples">Examples</a></h1> +<h2><a class="header" href="#catch-sigsegv-and-execute-commands" id="catch-sigsegv-and-execute-commands">Catch SIGSEGV and execute commands</a></h2> +<p>This creates a <code>catchpoint</code> for the <code>SIGSEGV</code> signal and attached the <code>command</code> +to it.</p> <pre><code class="language-markdown"> catch signal SIGSEGV command bt @@ -449,8 +506,9 @@ before or after a certain command.</p> <pre><code class="language-markdown"> gdb --batch -ex 'thread 1' -ex 'bt' -p <pid> </code></pre> <h2><a class="header" href="#script-gdb-for-automating-debugging-sessions" id="script-gdb-for-automating-debugging-sessions">Script gdb for automating debugging sessions</a></h2> -<pre><code class="language-markdown"># run.gdb - set pagination off +<p>To script gdb add commands into a file and pass it to gdb via <code>-x</code>. +For example create <code>run.gdb</code>:</p> +<pre><code class="language-markdown"> set pagination off break mmap command @@ -463,20 +521,21 @@ before or after a certain command.</p> c </code></pre> <p>This script can be used as:</p> -<pre><code class="language-markdown"> gdb -p <pid> -x ./run.gdb --batch &> run.log +<pre><code class="language-markdown"> gdb --batch -x ./run.gdb -p <pid> </code></pre> +<h1><a class="header" href="#know-bugs" id="know-bugs">Know Bugs</a></h1> <h2><a class="header" href="#workaround-command--finish-bug" id="workaround-command--finish-bug">Workaround <code>command + finish</code> bug</a></h2> -<p>When using <code>finish</code> action inside a <code>command</code> block, actions after <code>finish</code> are -not executed anymore. To workaround that bug one can create a wrapper function -which calls <code>finish</code>.</p> +<p>When using <code>finish</code> inside a <code>command</code> block, commands after <code>finish</code> are not +executed. To workaround that bug one can create a wrapper function which calls +<code>finish</code>.</p> <pre><code class="language-markdown"> define handler - bt - finish - info reg rax + bt + finish + info reg rax end command - handler + handler end </code></pre> <h1><a class="header" href="#radare21" id="radare21">radare2(1)</a></h1> @@ -563,7 +622,7 @@ which calls <code>finish</code>.</p> <pre><code class="language-markdown">strace [opts] [prg] -f .......... follow child processes on fork(2) -p <pid> .... attach to running process - -s <size> ... max string size (default: 32) + -s <size> ... max string size, truncate of longer (default: 32) -e <expr> ... expression for trace filtering -o <file> ... log output into <file> -c .......... dump syscall statitics at the end @@ -575,20 +634,20 @@ which calls <code>finish</code>.</p> trace=signal ............... trace signal related syscalls signal ..................... trace signals delivered to the process </code></pre> -<h1><a class="header" href="#examples" id="examples">Examples</a></h1> -<p>Trace <code>'open & socket</code> syscalls for a running process + childs.</p> -<pre><code class="language-markdown">strace -f -p <pid> -e trace=open,socket +<h1><a class="header" href="#examples-1" id="examples-1">Examples</a></h1> +<p>Trace <code>open(2)</code> & <code>socket(2)</code> syscalls for a running process + child processes:</p> +<pre><code class="language-markdown">strace -f -e trace=open,socket -p <pid> </code></pre> -<p>Trace signals delivered to a running process.</p> -<pre><code class="language-markdown">strace -f -p <pid> -e signal +<p>Trace signals delivered to a running process:</p> +<pre><code class="language-markdown">strace -f -e signal -p <pid> </code></pre> <h1><a class="header" href="#lsof8" id="lsof8">lsof(8)</a></h1> <pre><code class="language-markdown">lsof -a ......... AND slection filters instead ORing (OR: default) - -p <pid> ... list open file descriptors for process + -p <pid> ... filter by <pid> +fg ........ show file flags for file descripros -n ......... don't convert network addr to hostnames - -P ......... don't convert network port to know service names + -P ......... don't convert network port to service names -i <@h[:p]>. show connections to h (hostname|ip addr) with optional port p </code></pre> <pre><code class="language-markdown">file flags: @@ -597,43 +656,69 @@ which calls <code>finish</code>.</p> AP ......... append TR ......... truncate </code></pre> -<h1><a class="header" href="#examples-1" id="examples-1">Examples</a></h1> -<p>Show open files with file flags:</p> +<h1><a class="header" href="#examples-2" id="examples-2">Examples</a></h1> +<h2><a class="header" href="#file-flags" id="file-flags">File flags</a></h2> +<p>Show open files with file flags for process:</p> <pre><code class="language-markdown">lsof +fg -p <pid> </code></pre> -<p>Show open tcp connections from user:</p> +<h2><a class="header" href="#open-tcp-connections" id="open-tcp-connections">Open TCP connections</a></h2> +<p>Show open tcp connections for <code>$USER</code>:</p> <pre><code class="language-markdown">lsof -a -u $USER -i tcp </code></pre> -<p>Show open connections to 'localhost' for user:</p> +<p><strong>Note</strong>: <code>-a</code> <em>ands</em> the results. If <code>-a</code> is not given all open files matching +<code>$USER</code> and all tcp connections are listed (<em>ored</em>).</p> +<h2><a class="header" href="#open-connection-to-specific-host" id="open-connection-to-specific-host">Open connection to specific host</a></h2> +<p>Show open connections to <code>localhost</code> for <code>$USER</code>:</p> <pre><code class="language-markdown">lsof -a -u $USER -i @localhost </code></pre> <h1><a class="header" href="#pidstat1" id="pidstat1">pidstat(1)</a></h1> -<p>Trace minor/major page faults.</p> -<pre><code class="language-markdown">pidstat -r -p <pid> [interval] - minor_pagefault: happens when the page needed is already in memory but not - allocated to the faulting process, in that case the kernel - only has to create a new page-table entry pointing to the - shared physical page - major_pagefault: happends when the page needed is NOT in memory, the kernel - has to create a new page-table entry and populate the - physical page +<pre><code class="language-markdown">pidstat [opt] [interval] [cont] + -U [user] show username instead UID, optionally only show for user + -r memory statistics + -d I/O statistics + -h single line per process and no lines with average +</code></pre> +<h1><a class="header" href="#page-fault-and-memory-utilization" id="page-fault-and-memory-utilization">Page fault and memory utilization</a></h1> +<pre><code class="language-markdown">pidstat -r -p <pid> [interval] [count] +</code></pre> +<pre><code class="language-markdown">minor_pagefault: Happens when the page needed is already in memory but not + allocated to the faulting process, in that case the kernel + only has to create a new page-table entry pointing to the + shared physical page (not required to load a memory page from + disk). + +major_pagefault: Happens when the page needed is NOT in memory, the kernel + has to create a new page-table entry and populate the + physical page (required to load a memory page from disk). +</code></pre> +<h1><a class="header" href="#io-statistics" id="io-statistics">I/O statistics</a></h1> +<pre><code class="language-markdown">pidstat -d -p <pid> [interval] [count] </code></pre> <h1><a class="header" href="#usrbintime1" id="usrbintime1">/usr/bin/time(1)</a></h1> <pre><code class="language-markdown"># statistics of process run /usr/bin/time -v <cmd> </code></pre> -<h1><a class="header" href="#pmap1" id="pmap1">pmap(1)</a></h1> -<pre><code class="language-markdown">pmap <pid> - ............. dump virtual memory map of process. - compared to /proc/<pid>/maps it shows the size of the mappings +<h1><a class="header" href="#pgrep1" id="pgrep1">pgrep(1)</a></h1> +<pre><code class="language-markdown">pgrep [opts] <pattern> + -n only list newest matching process + -u <usr> only show matching for user <usr> + -l additionally list command + -a additionally list command + arguments +</code></pre> +<h2><a class="header" href="#debug-newest-process" id="debug-newest-process">Debug newest process</a></h2> +<p>For example attach gdb to newest zsh process from <code>$USER</code>.</p> +<pre><code class="language-markdown">gdb -p $(pgrep -n -u $USER zsh) </code></pre> <h1><a class="header" href="#pstack1" id="pstack1">pstack(1)</a></h1> <pre><code class="language-markdown">pstack <pid> - ............. dump current stack of process + threads + Dump stack for all threads of process. +</code></pre> +<h1><a class="header" href="#pstack1-1" id="pstack1-1">pstack(1)</a></h1> +<pre><code class="language-markdown">pstack <pid> + Dump stack for all threads of process. </code></pre> <h1><a class="header" href="#perf1" id="perf1">perf(1)</a></h1> -<pre><code class="language-markdown">perf list - ......... show supported hw/sw events +<pre><code class="language-markdown">perf list show supported hw/sw events perf stat -p <pid> .. show stats for running process @@ -649,7 +734,8 @@ perf record -p <pid> ............... record stats for running process -F <hz> ................ sampling frequency --call-graph <method> .. [fp, dwarf, lbr] method how to caputre backtrace - fp : use frame-pointer, need -fno-omit-frame-pointer + fp : use frame-pointer, need to compile with + -fno-omit-frame-pointer dwarf: use .cfi debug information lbr : use hardware last branch record facility -g ..................... short-hand for --call-graph fp @@ -660,8 +746,7 @@ perf report --stdio ............... report to stdio, if not presen tui mode -g graph,0.5,caller ... show caller based call chains with value >0.5 </code></pre> -<h2><a class="header" href="#useful-perf-events" id="useful-perf-events">Useful <code>perf</code> events</a></h2> -<pre><code class="language-markdown">useful <ev>: +<pre><code class="language-markdown">Useful <ev>: page-faults minor-faults major-faults @@ -669,27 +754,26 @@ perf report task-clock </code></pre> <h2><a class="header" href="#a-hrefhttpsgithubcombrendangreggflamegraphflamegrapha" id="a-hrefhttpsgithubcombrendangreggflamegraphflamegrapha"><a href="https://github.com/brendangregg/FlameGraph"><code>Flamegraph</code></a></a></h2> -<pre><code class="language-markdown"># flamegraph for single event trace -perf record -g -p <pid> -e cpu-cycles +<h3><a class="header" href="#flamegraph-with-single-event-trace" id="flamegraph-with-single-event-trace">Flamegraph with single event trace</a></h3> +<pre><code class="language-markdown">perf record -g -e cpu-cycles -p <pid> perf script | FlameGraph/stackcollapse-perf.pl | FlameGraph/flamegraph.pl > cycles-flamegraph.svg - -# flamegraphs for multiple events trace -perf record -g -p <pid> -e cpu-cycles,page-faults +</code></pre> +<h3><a class="header" href="#flamegraph-with-multiple-event-traces" id="flamegraph-with-multiple-event-traces">Flamegraph with multiple event traces</a></h3> +<pre><code class="language-markdown">perf record -g -e cpu-cycles,page-faults -p <pid> perf script --per-event-dump # fold & generate as above </code></pre> -<h1><a class="header" href="#oprofile" id="oprofile">OProfile</a></h1> +<h1><a class="header" href="#a-hrefhttpsoprofilesourceforgeiooprofilea" id="a-hrefhttpsoprofilesourceforgeiooprofilea"><a href="https://oprofile.sourceforge.io/">OProfile</a></a></h1> <pre><code class="language-markdown">operf -g -p <pid> -g ...... caputre call-graph information opreport [opt] FILE - ...... show time spent per binary image + show time spent per binary image -l ...... show time spent per symbol -c ...... show callgraph information (see below) -a ...... add column with time spent accumulated over child nodes -ophelp - ...... show supported hw/sw events +ophelp show supported hw/sw events </code></pre> <h1><a class="header" href="#od1" id="od1">od(1)</a></h1> <pre><code class="language-markdown"> od [opts] <file> @@ -701,7 +785,7 @@ ophelp -j <n> skip <n> bytes from <file> (hex if start with 0x) -N <n> dump <n> bytes (hex of start with 0x) </code></pre> -<h2><a class="header" href="#ascii-chars-to-hex-string" id="ascii-chars-to-hex-string">ascii chars to hex string</a></h2> +<h2><a class="header" href="#ascii-to-hex-string" id="ascii-to-hex-string">ASCII to hex string</a></h2> <pre><code class="language-markdown"> echo -n AAAABBBB | od -An -w4 -tx4 >> 41414141 >> 42424242 @@ -711,13 +795,18 @@ ophelp >> del E L F nl # ta >> 177 E L F \n # tc </code></pre> -<h2><a class="header" href="#extract-part-of-file-eg-rodata-section-form-elf" id="extract-part-of-file-eg-rodata-section-form-elf">extract part of file (eg .rodata section form ELF)</a></h2> +<h2><a class="header" href="#extract-parts-of-file" id="extract-parts-of-file">Extract parts of file</a></h2> +<p>For example <code>.rodata</code> section from an elf file. We can use <code>readelf</code> to get the +offset into the file where the <code>.rodata</code> section starts.</p> <pre><code class="language-markdown"> readelf -W -S foo >> Section Headers: >> [Nr] Name Type Address Off Size ES Flg Lk Inf Al >> ... >> [15] .rodata PROGBITS 00000000004009c0 0009c0 000030 00 A 0 0 16 - od -j 0x0009c0 -N 0x30 -tx4 -w4 foo +</code></pre> +<p>With the offset of <code>-j 0x0009c0</code> we can dump <code>-N 0x30</code> bytes from the beginning of +the <code>.rodata</code> section as follows:</p> +<pre><code class="language-markdown"> od -j 0x0009c0 -N 0x30 -tx4 -w4 foo >> 0004700 00020001 >> 0004704 00000000 >> * @@ -726,6 +815,7 @@ ophelp >> 0004750 00000003 >> 0004754 00000004 </code></pre> +<p><strong>Note</strong>: Numbers starting with <code>0x</code> will be interpreted as hex by <code>od</code>.</p> <h1><a class="header" href="#xxd1" id="xxd1">xxd(1)</a></h1> <pre><code class="language-markdown"> xxd [opts] -p dump continuous hexdump @@ -733,19 +823,19 @@ ophelp -e dump as little endian mode -i output as C array </code></pre> -<h2><a class="header" href="#from-ascii-to-hex-stream" id="from-ascii-to-hex-stream">from ascii to hex stream</a></h2> +<h2><a class="header" href="#ascii-to-hex-stream" id="ascii-to-hex-stream">ASCII to hex stream</a></h2> <pre><code class="language-markdown"> echo -n 'aabb' | xxd -p >> 61616262 </code></pre> -<h2><a class="header" href="#from-hex-stream-to-binary-stream" id="from-hex-stream-to-binary-stream">from hex stream to binary stream</a></h2> +<h2><a class="header" href="#hex-to-binary-stream" id="hex-to-binary-stream">Hex to binary stream</a></h2> <pre><code class="language-markdown"> echo -n '61616262' | xxd -p -r >> aabb </code></pre> -<h2><a class="header" href="#ascii-to-binary" id="ascii-to-binary">ascii to binary</a></h2> +<h2><a class="header" href="#ascii-to-binary" id="ascii-to-binary">ASCII to binary</a></h2> <pre><code class="language-markdown"> echo -n '\x7fELF' | xxd -p | xxd -p -r | file -p - >> ELF </code></pre> -<h2><a class="header" href="#ascii-to-c-array-hex-encoded" id="ascii-to-c-array-hex-encoded">ascii to C array (hex encoded)</a></h2> +<h2><a class="header" href="#ascii-to-c-array-hex-encoded" id="ascii-to-c-array-hex-encoded">ASCII to <code>C</code> array (hex encoded)</a></h2> <pre><code class="language-markdown"> xxd -i <(echo -n '\x7fELF') >> unsigned char _proc_self_fd_11[] = { >> 0x7f, 0x45, 0x4c, 0x46 @@ -773,7 +863,8 @@ ophelp -j <section> display info for section --[no-]show-raw-insn [dont] show object code next to disassembly </code></pre> -<h2><a class="header" href="#disassemble-plt-section" id="disassemble-plt-section">Disassemble .plt section</a></h2> +<h2><a class="header" href="#disassemble-section" id="disassemble-section">Disassemble section</a></h2> +<p>For example <code>.plt</code> section:</p> <pre><code class="language-markdown"> objdump -j .plt -d <elf> </code></pre> <h1><a class="header" href="#nm1" id="nm1">nm(1)</a></h1> @@ -782,10 +873,11 @@ ophelp -u undefined only </code></pre> <h1><a class="header" href="#cfilt1" id="cfilt1">c++filt(1)</a></h1> -<h2><a class="header" href="#demangle-symbol" id="demangle-symbol">demangle symbol</a></h2> +<h2><a class="header" href="#demangle-symbol" id="demangle-symbol">Demangle symbol</a></h2> <pre><code class="language-markdown"> c++-filt <symbol_str> </code></pre> -<h2><a class="header" href="#demangle-stream-eg-dynamic-symbol-table" id="demangle-stream-eg-dynamic-symbol-table">demangle stream (eg dynamic symbol table)</a></h2> +<h2><a class="header" href="#demangle-stream" id="demangle-stream">Demangle stream</a></h2> +<p>For example dynamic symbol table:</p> <pre><code class="language-markdown"> readelf -W --dyn-syms <elf> | c++filt </code></pre> |