Using gdb

Written by

in

Using gdb

I figured I’ll write a mini-tutorial on how to use gdb, because there’s not that many places where they teach you how to use gdb effectively.

Let’s say you have a program and it crashes, what do you do?

Example code:

“`


void func() { char *p = 0; *p = 0x69; }


int main() { func(); }


“`

Next:

“`


gdb a.out

“`

Followed by the `run` command:

“`


(gdb) run

Starting program: /home/d/a.out

[Thread debugging using libthread_db enabled]

Using host libthread_db library “/lib/x86_64-linux-gnu/libthread_db.so.1”.


Program received signal SIGSEGV, Segmentation fault.

0x000055555555513d in func () at test.c:1

1 void func() { char *p = 0; *p = 0x69; }

(gdb)

“`

You can see where it crashes, but you’d like a stacktrace…

“`


gdb) bt

#0 0x000055555555513d in func () at test.c:1

#1 0x0000555555555155 in main () at test.c:3

(gdb)

“`

(NB: `bt` stands for backtrace)

You can go up a frame and check local variables:

“`


(gdb) up

#1 0x0000555555555155 in main () at test.c:3

3 int main() { func(); }

(gdb) info local

No locals.

“`

Or down a frame and check local variables:

“`


(gdb) down

#0 0x000055555555513d in func () at test.c:1

1 void func() { char *p = 0; *p = 0x69; }

(gdb) info local

p = 0x0

“`

You can continue after the segfault:

“`

(gdb) cont

Continuing.


Program terminated with signal SIGSEGV, Segmentation fault.

The program no longer exists.

(gdb)

“`

Now we can re-run it, but before we do, we can set a breakpoint:

“`

(gdb) break func

Breakpoint 1 at 0x555555555131: file test.c, line 1.

(gdb)


“`

Now we run it again, it will stop at the breakpoint:

“`


(gdb) run

Starting program: /home/d/a.out

[Thread debugging using libthread_db enabled]

Using host libthread_db library “/lib/x86_64-linux-gnu/libthread_db.so.1”.


Breakpoint 1, func () at test.c:1

1 void func() { char *p = 0; *p = 0x69; }

(gdb)

“`

We can single step through it:

“`


(gdb) step


Program received signal SIGSEGV, Segmentation fault.

0x000055555555513d in func () at test.c:1

1 void func() { char *p = 0; *p = 0x69; }

(gdb)

“`

We can also try the command `next`, which is similar to `step` but skips over subroutines.

We can get help from gdb at any time using `help`.

Another useful `info` command is `info reg`, which shows CPU registers.

Also useful is `disas` command, which disassembles the code.

 

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *