Difference between revisions of "GDB"

From eLinux.org
Jump to: navigation, search
(Startup)
(add preamble to the gdb debugging in order to avoid common error)
Line 10: Line 10:
  
 
=== Startup ===
 
=== Startup ===
 +
A common error while using gdb,is using the wrong gdb. In order to debug a program that runs on a target you need a cross gdb,that is to say a GDB that runs on your computer but can debug the target architecture.
 +
Such version is normally included in your toolchain/SDK or buildable if you use a build system
 +
==== Code sourcey Linux ====
 +
Let's say that you downloaded arm-2009q3-67-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2
  
 +
You will need to unpack it,and to run the following command instead of gdb:
 +
cd  arm-2009q3/bin
 +
./arm-none-linux-gnueabi-gdb
 +
==== Openembedded ====
 +
If your build system is also your debug workstation do:
 +
bitbake gdb-cross gdbserver
 +
And it will build a cross gdb for your host and gdbserver for your target
 +
The resulting binaries will be found in your TMPDIR here:
 +
/home/embedded/tmpdir/cross/armv6/bin/
 +
replace "/home/embedded/tmpdir" by your tmpdir and armv6 by your target architecture
 +
The binary name changes according to your distro settings,for me it was:
 +
arm-angstrom-linux-gnueabi-gdb
 +
==== Howto ====
 
To start a new application for debug, use:
 
To start a new application for debug, use:
  

Revision as of 15:11, 5 May 2010

The GNU Debugger GDB is the most common debug tool for Linux. It features most used features one can think of, including server-client debug architecture (so you run the heavy debug part on your host/pc machine), but lack some bits as checkpoint-restart during execution.

Documentation

GDB ships with extensive documentation at http://www.gnu.org/software/gdb/documentation/, but there are some good quick reference cards as well.

Basic Usage

Documentation is so large that sometimes its hard to get started, so most simple tasks can be done with the following commands, but please read GDB docs as soon as possible!

Startup

A common error while using gdb,is using the wrong gdb. In order to debug a program that runs on a target you need a cross gdb,that is to say a GDB that runs on your computer but can debug the target architecture. Such version is normally included in your toolchain/SDK or buildable if you use a build system

Code sourcey Linux

Let's say that you downloaded arm-2009q3-67-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2

You will need to unpack it,and to run the following command instead of gdb:

cd  arm-2009q3/bin
./arm-none-linux-gnueabi-gdb 

Openembedded

If your build system is also your debug workstation do:

bitbake gdb-cross gdbserver

And it will build a cross gdb for your host and gdbserver for your target The resulting binaries will be found in your TMPDIR here:

/home/embedded/tmpdir/cross/armv6/bin/

replace "/home/embedded/tmpdir" by your tmpdir and armv6 by your target architecture The binary name changes according to your distro settings,for me it was:

arm-angstrom-linux-gnueabi-gdb

Howto

To start a new application for debug, use:

 $ gdb ./binary
 $ gdb ./binary core.dump
 $ gdb --args ./binary arg1 arg2
 $ gdb --command=my-gdb-commands.txt --args ./binary arg1 arg2

and then run it with (args just required if no --args were used):

 (gdb) run arg1 arg2

if you need to execute a series of commands every time, consider writing them on a file and use --command=file (or -x file).

It's usually a pain to run the full gdb on your device, so use gdbserver on the target and gdb on host:

target/device$ gdbserver :2345 ./binary arg1 arg2
target/device$ gdbserver /dev/ttyS1 ./binary arg1 arg2
target/device$ gdbserver /dev/ttyS1 --attach PID
host/pc$ gdb
(gdb) target remote /dev/ttyS1
(gdb) target remote 192.168.0.123:2345

If you are using the serial method you need to make sure you have setup the serial speed correctly, On the host:

 (gdb) set remotebaud 115200

On the target(before you issue the gdbserver command):

 stty speed 115200 < /dev/ttyS1

If application is already running, find out its pid (ps, top, pidof, ...) and:

$ gdb --pid $PID

Breakpoints

If you control-C (^C), it will break at that point, but you can also schedule a breakpoint with:

(gdb) break function
(gdb) break line
(gdb) break file:function
(gdb) break file:line

conditional breaks are in the form:

(gdb) break where if condition

where condition is some C expression that evaluates to 1 or 0, like *ptr == NULL

One can disable or remove breakpoints with:

(gdb) enable breakpoint-number
(gdb) disable breakpoint-number
(gdb) delete breakpoint-number
(gdb) clear       # removes all breakpoints

Examining

To list source code nearby position or specific places:

(gdb) list
(gdb) list line
(gdb) list function
(gdb) list file:line
(gdb) list file:function
(gdb) list *address

To list execution backtrace (or bt for short):

(gdb) backtrace

To change frame to operate on:

(gdb) frame frame-number

To change thread to operate on:

(gdb) thread thread-number

To print some value or expression:

(gdb) print $register
(gdb) print variable
(gdb) print *address
(gdb) print *(int *)address
(gdb) print *(char **)address
(gdb) print myfunc(p1, p2) # will actually execute it and return result!
(gdb) print *a = 123 # will actually change *a value and return 123!
(gdb) print file::variable
(gdb) print function::variable

To disassembly:

(gdb) disassembly
(gdb) disassembly file:line

Print function arguments:

(gdb) info args

Print locals:

(gdb) info locals

Print breakpoints:

(gdb) info breakpoints

Print threads:

(gdb) info threads

Stepping

To go to next instruction, possible entering a function (or s for short):

(gdb) step

To go to next instruction, but avoid entering new functions (or n for short):

(gdb) next

To continue until the function returns:

(gdb) finish

To continue execution (or c for short):

(gdb) continue

Manipulating Program

To set variable to some value:

(gdb) set var name=value

To force function to return:

(gdb) return value
(gdb) return expression

Changing Signal Handlers

(gdb) handle signal action

debugging applications with old libC, those pre-nptl, can be really annoying due SIG32 and SIG33, one can ignore those with:

(gdb) handle SIG32 nostop
(gdb) handle SIG32 noprint
(gdb) handle SIG33 nostop
(gdb) handle SIG33 noprint

Shared Object Paths

Often your cross compile root is not /, so you might have to add new paths to the search list.

Unset absolute prefix:

 (gdb) set solib-absolute-prefix null

Add paths to search paths:

 (gdb) set solib-search-path /path1:/path2

Alternatively you can choose to set the prefix to the root of your target file system. Specially if you are doing embedded development and already exporting your root file system from you host machine to your target machine it can be very rewarding so simply use that as root:

 (gdb) set solib-absolute-prefix /rootfs