aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/_notes/gdb.md
blob: d6348798233f92a98f94b9d641ecf40ea41eb353 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
---
title: GDB
subtitle: cheat sheet
links:
  - {rel: stylesheet, href: 'assets/css/gdb.css'}
---
Core dumps
----------

* Where are my core dumps?

      cat /proc/sys/kernel/core_pattern

* Put core dumps in a directory:

      mkdir /coredumps
      chmod 0777 /coredumps
      echo '/coredumps/core.%e.%p' | tee /proc/sys/kernel/core_pattern

* Still no dumps :-(

      ulimit -c unlimited

* If dumps are piped to systemd-coredump, you can examine them using
`coredumpctl`.

  <div markdown="1" class="table-responsive">
  | List dumps            | `coredumpctl`
  | Debug the last dump   | `coredumpctl gdb`
  | Extract the last dump | `coredumpctl dump -o core`
  {: .table .table-bordered }
  </div>

.gdbinit
--------

    # Without these, gdb is hardly usable:
    set pagination off
    set confirm off
    set print pretty on

    # Save history:
    set history save on
    set history filename ~/.gdb-history
    set history size 10000

Basics
------

<div markdown="1" class="table-responsive">

| Run                     | `r`
| Continue                | `c`
| Breakpoint at function  | `b FUNC`
| Breakpoint at address   | `b *0xdeadbeef`
| List breakpoints        | `i b`
| Disable breakpoint      | `dis N`
| Enable breakpoint       | `en N`
| Delete breakpoint       | `d N`
| Call stack              | `bt`
| Call stack: all threads | `thread apply all bt`
| Go to frame             | `f N`
| Switch to thread        | `t N`
| Disassemble             | `disas FUNC`
| Step over line          | `n`
| Step over instruction   | `si`
| Step out of frame       | `fin`
{: .table .table-bordered }

</div>

Hint: put this in your ~/.gdbinit and use `bta` as a shortcut:

    define bta
        thread apply all backtrace
    end

Data inspection
---------------

<div markdown="1" class="table-responsive">

| Disassemble 5 instructions    | `x/5i 0xdeadbeef`
| Print a 64-bit address        | `x/1xg 0xdeadbeef`
| Print a 32-bit address        | `x/1xw 0xdeadbeef`
| Print anything                | `p sa->__sigaction_handler.sa_handler`
| Describe a type               | `ptype struct sigaction`
| Describe a type with offsets  | `ptype /o struct sigaction`
| Disassemble all code sections | `objdump -d /proc/self/exe`
| Disassemble a single section  | `objdump -d -j .init /proc/self/exe`
| Display the section contents  | `objdump -s -j .data /proc/self/exe`
{: .table .table-bordered }

</div>

Hint: put this in your ~/.gdbinit:

    define xxd
        dump binary memory /tmp/dump.bin $arg0 ((char *)$arg0)+$arg1
        shell xxd -groupsize 1 /tmp/dump.bin
        shell rm -f /tmp/dump.bin
    end

You can then use `xxd ADDR LEN` to display, in my opinion, the best formatting
for memory dumps:

    (gdb) xxd main 24
    00000000: f3 0f 1e fa 41 57 41 89 ff bf 05 00 00 00 41 56  ....AWA.......AV
    00000010: 49 89 f6 41 55 41 54 55                          I..AUATU

Debuginfod
----------

If your distribution provides a Debuginfod server, use it!
For example, see [Arch], [Debian], [Fedora].
In ~/.gdbinit, add

    set debuginfod enabled on

[Arch]: https://wiki.archlinux.org/title/Debuginfod
[Debian]: https://wiki.debian.org/Debuginfod
[Fedora]: https://fedoraproject.org/wiki/Debuginfod


Intel syntax
------------

This is just me being a baby duck.
In ~/.gdbinit:

    set disassembly-flavor intel

With `objdump`:

    objdump -Mintel -d /proc/self/exe