Intro to gdb - Virginia Tech

Intro to gdb

Note: This documentation is written in regards to CentOS 7 systems with an x86-64 architecture.

1 Starting gdb

We start gdb by one of the following Linux commands:

[user@localhost ~]$ gdb

#start without file

[user@localhost ~]$ gdb executableFile #start with file

and simply for aesthetics, we can also quiet the output of starting gdb with --quiet or -q:

[user@localhost ~]$ gdb -q executableFile Reading symbols from /home/user/executableFile...done. (gdb)

2 Running and Stopping ? Basic gdb Controls

This section refers to commands for opening, running, and stopping programs in gdb, as well as exiting the debugger. (gdb) file executableFile #open/switch program

(gdb) run

#run an opened program

(gdb) run 1 2 3

#run program with arguments: 1, 2, 3

Note: It is necessary to run the program to debug it. Starting gdb does not start the debugging process by itself. Also note that it is recommended to set a breakpoint before running, to avoid automatically passing over unintended lines of code.

(gdb) kill

#stop the running program

(gdb) quit

#exit gdb; also: q or Ctrl+D

Note: Ctrl+C halts the current gdb command and does not quit from the debugger.

3 Breakpoints

gdb numbers the breakpoints you set, which allows you to refer to these breakpoints if you wish to change or modify them while debugging. The number is outputted when setting the breakpoint.

(gdb) break func

#set breakpoint at entry to function `func '

(gdb) b *0x80483c3

#set breakpoint at memory address 0x80483c3

(gdb) b file.c:34

#set breakpoint at line 34 from `file.c'

1

Note: Setting a breakpoint does not prevent you from executing a line of code. Step through code wisely, as you cannot back up to a previous instruction or line without rerunning the program.

(gdb) delete 1

#delete breakpoint 1; also: d

(gdb) delete

#delete all breakpoints

(gdb) disable 1

#disable breakpoint 1

(gdb) enable 1

#enable breakpoint 1

(gdb) clear func

#clear any breakpoints set at function `func '

4 Execution and Stepping

The line of code or instruction that appears before you when debugging is the line or instruction yet to be run. It is executed when you step over it, into it, etc. Therefore, to see and test the results of an instruction that is presented from the last gdb stepping command, you must step to the next instruction.

(gdb) stepi

#execute one instruction; also: si

(gdb) si 4

#execute four instructions

(gdb) nexti

#like si; steps over function calls; also: ni

Note: For practical purposes and comparison, si is like "Step Into" and ni is like "Step Over" from other debuggers. For stepping by lines of source code, use step (or s) and next (or n), respectively.

(gdb) continue

#execute up until next breakpoint; also: c

(gdb) until 3

#execute until breakpoint 3; also: u

(gdb) finish

#finish execution until current function returns

(gdb) call func(4, x)

#calls `func ' with the # 4 and the variable `x'

5 Disassembly ? Examining Code

(gdb) disassemble

#disassemble current function; also: disas

(gdb) disas func

#disassemble function `func '

(gdb) disas 0x80483b7

#disassemble function around 0x80483b7

(gdb) disas func , +10

#disassemble from `func ' to just `func + 10'

The program counter is the current address of memory that is yet to be executed, i.e. the address of the current instruction. Upon disassembly of a current function, we'd see an arrow pointing to this address as well, verifying and displaying the current instruction (assuming that the debugger is running).

(gdb) print /x $rip

#print program counter in hexidecimal

Use /d to print in decimal, and /t to print in binary. The formatters are described in more detail below.

2

6 Printing ? The Basics

Sometimes you want to know a variable or register's value at a certain instance of the program. Sometimes you'd like to know a number's value represented in a certain base. gdb can do that, and more.

(gdb) print var1

#print the value of var1; also: p

Without specifying any exact format, gdb will try to print it out the way it thinks is correct. This can be a good first go-to if you're unsure of the variable's type.

(gdb) p /x 555

#print 555 in hexidecimal -- 0x22b

There are many formatter types you can specify in gdb to alter the way an expression or value is printed out. Use /x for hexidecimal, /d for signed integers, /u for unsigned integers, /t for binary, /c for characters, /f for floating point numbers, /a for hex addresses, and so on. Refer to the documentation at `h x' for more.

(gdb) p 0x100

#print 0x100 in decimal -- 256

(gdb) p /d $rax

#print out value in %rax in decimal

7 Printing ? Casting, Expressions, and Data

gdb allows you to use expressions as arguments, i.e. code that looks similar to C code, whether it's pointer dereferencing, type casts, or in-line arithmetic expressions. There's a number of creative things you can do to examine data.

(gdb) p /d (int) $rax

#print %rax after casting to 32 bits

Something like this might be useful when %rax is actually holding a 32 bit number in a 64 bit register and there's an implicitly negative value in the lower 32 bits.

(gdb) p /x ($rsp + 8)

#print (%rsp + 8), an address + 8, in hex

(gdb) p *(int *) 0x4004d0 #print an integer at 0x4004d0

(gdb) p *(int *) ($rsp+8) #print an integer at address (%rsp + 8)

(gdb) p (char *) 0x4004d0 #print a string at address 0x4004d0

(gdb) p /x (0xf ^ 0x1) #print the XOR of 15 and 1 -- 14

(gdb) p /d *$rax

#dereference $rax and print out the target

The x command has a lot of really great formatters as well, including the /s formatter for strings. x also supports formatters for specific size numbers: b for byte (8 bits), h for halfword (16 bits), w for word (32 bits), and g for giant (64 bits). Again, see `h x' for more.

The general usage syntax for x is : x /[NUM][SIZE][FORMAT] where (Note that if one of NUM, SIZE, or FORMAT are not given, x will pick a default, or the last one you chose with a previous command.)

(gdb) x /w 0xbffff890

#examine word starting at address 0xbffff890

(gdb) x /w $rsp

#examine word starting at %rsp

(gdb) x /wd $rsp

#same as above , print in decimal

(gdb) x /2w $rsp

#examine 2 words starting at %rsp

(gdb) x /2wd $rsp

#same as above , print in decimal

3

(gdb) x /g $rsp

#examine giant starting at %rsp

(gdb) x /s 0xbffff890

#examine string starting at 0xbffff890

(gdb) x /a $rsp

#address in %rsp , as offset from global symbol

(gdb) x /20b func

#examine first 20 opcode bytes from `func '

(gdb) x /10i func

#examine first 10 instructions from `func '

Note: These last two are both alternatives to disassemble, the last being a more explicit way of specifying the length of a disassembly output. x asks for a specific amount of data to examine, while disassemble asks for a range of memory addresses.

(gdb) x /10i $rip

#examine the next 10 instructions

8 Other Useful Things in gdb

(gdb) backtrace

#print backtrace of all stack frames; also bt

bt is mostly commonly used for tracing where a program crashed, or for following a chain of method calls while debugging.

(gdb) info program

#print status of the program; also i

(gdb) i functions

#print the functions in the program

(gdb) i frame

#info about the current frame; also `i f'

(gdb) i registers

#info about the registers; also `i r'

(gdb) i breakpoints

#info about user -set breakpoints; also `i b'

gdb allows for tracking of expressions, registers, or variables as you step through the debugger. display will print one of these things automatically after executing code or instruction(s), which makes it easier to track certain values. Usage: display [/FORMAT] EXPRESSION

(gdb) display /x $rax

#automatically print %rax in hex; also disp

(gdb) disp /c *$rcx

#auto. print a char that a string %rcx points to

(gdb) undisplay

#turn off all tracking

(gdb) undisplay 2

#turn off just the second tracker

(gdb) help CMD

#print documentation on a command `CMD '; also h

4

9 Other Useful Things in the Terminal

[user@localhost ~]$ objdump -t executableFile #whole program symbol table

[user@localhost ~]$ objdump -d executableFile #whole program disassembly

[user@localhost ~]$ objdump -d executableFile > dump.out Redirecting the dump's output into a file, like above, could be practical for having multiple windows open while debugging.

10 Niceties

(gdb) [Ctrl+L]

#Ctrl+L clears the screen , pushing up output

(gdb) set logging on log.txt

Copying output to log.txt.

(gdb) disas func

#disassemble `func ' to a file `log.txt '

(gdb) set logging off

Done logging to log.txt.

(gdb)

(gdb) ls

Undefined command: "ls". Try "help".

(gdb) shell ls

#use shell commands inside of gdb

dump.out executableFile log.txt

(gdb)

Suppose you want a bunch of breakpoints each time you start gdb but don't want to enter them every time starting it up. Besides using a project specific .gdbinit file (which has great control over gdb settings on startup), you could offload gdb commands to a file like this (a file called `b_pts.txt' for the example):

b func b main.c:34 b func2

...

[user@localhost ~]$ gdb -x b_pts.txt executableFile #autoset breakpoints

5

................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download