Getting Started with gdbserver
Introduction
This documentation shows how to get started with gdbserver with a basic application. When using gdb binaries need to be compiled with debug symbols.
Application and target should have networking. For more information about SDK please check
developer.ridgerun.com/wiki/index.php/RidgeRun_Turrialba_SDK_User_Guide
Compilation process
In order to add debug symbols, autotools parameters need to specify cflags as CFLAGS="-g -O0". This flag can be also added at libraries and other utilities, for example gstreamer plugins.
AUTOTOOLS_PARAMS = LDFLAGS="-Wl,--rpath-link -Wl,$(FSDEVROOT)/usr/lib:$(FSDEVROOT)/lib" --sysconfdir=$(FSDEVROOT)/etc CFLAGS="-g -O0"
This flag can also be added at Toolchain Configuration, but this will compile the whole SDK with debug symbols which is not recommended
Selecting gdb server on target file system
Select gdb server on File System Configuration:
[*] Install GDB server on target file system
Compile SDK and install on target.
Executing gdb
Running application with gdbserver on target
Execute application with gdbserver:
gdbserver <HOST_IP>:<PORT> <APPLICATION_BINARY>
This will leave the application waiting for the host, current output:
/ # gdbserver 10.251.101.11:2345 hello_gdb Process hello_gdb created; pid = 1179 Listening on port 2345
Running gdb on Host
gdb needs to be for arm compiler, codesourcery distributes their toolchain with the binary, usually located at: codesourcery/arm-2009q1/bin/arm-none-linux-gnueabi-gdbtui.
Execute gdbtui binary:
arm-none-linux-gnueabi-gdbtui
At debugger command line some commands needs to be executed in order to start the application remotely:
Specify path to system root:
set solib-absolute-prefix $(DEVDIR)/fs/fs
Specify binary to work with (usually the binary is inside of root file system specified before)
file <PATH_TO_BIARY>
This will load the binary and will display debug information (Current output of gdbtui):
┌──hello_gdb.c─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │38 { │ │39 int i; │ │40 │ │41 /* Mandatory "Hello, world!" */ │ │42 │ │43 deb_puts("Getting ready to say \"Hello, world\"\n"); │ │44 printf("Hello, world!\n"); │ │45 deb_puts("It has been said.\n"); │ │46 │ │47 /* Print arguments */ │ │48 │ │49 printf("argc\t= %d\n", argc); │ │50 printf("argv\t= 0x%p\n", argv); │ │51 │ │52 for (i = 0; i < argc; i++) │ │53 { │ │54 printf("argv[%d]\t= ", i); │ │55 if (argv[i]) │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ exec No process In: Line: ?? PC: 0x0 (gdb) cd Argument required (new working directory). (gdb) cd /home/USER/devdirs/DEVDIR/fs/fs Working directory /home/USER/devdirs/DEVDIR/fs/fs. (gdb) set Argument required (expression to compute). (gdb) set solib-absolute-prefix . (gdb) file usr/bin/hello_gdb Reading symbols from /home/USER/devdirs/DEVDIR/fs/fs/usr/bin/hello_gdb...done. (gdb)
Set breakpoints:
Use the following command:
break <LINE_NUMBER>
This will specify an integer number at the breakpoint.Also the C file name may be specified if using various C files:
break <C_FILE.c>:<LINE_NUMBER>
Example of breakpoint being applied at line 45:
┌──hello_gdb.c─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │38 { │ │39 int i; │ │40 │ │41 /* Mandatory "Hello, world!" */ │ │42 │ │43 deb_puts("Getting ready to say \"Hello, world\"\n"); │ │44 printf("Hello, world!\n"); │ b+ │45 deb_puts("It has been said.\n"); │ │46 │ │47 /* Print arguments */ │ │48 │ │49 printf("argc\t= %d\n", argc); │ │50 printf("argv\t= 0x%p\n", argv); │ │51 │ │52 for (i = 0; i < argc; i++) │ │53 { │ │54 printf("argv[%d]\t= ", i); │ │55 if (argv[i]) │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ exec No process In: Line: ?? PC: 0x0 Undefined command: "ls". Try "help". (gdb) pwd Working directory /home/USER/devdirs/DEVDIR. (gdb) file myapps/hello-gdb/src/src/hello_gdb Reading symbols from /home/USER/devdirs/DEVDIR/myapps/hello-gdb/src/src/hello_gdb...done. (gdb) berak 45 Undefined command: "berak". Try "help". (gdb) break 45 Breakpoint 1 at 0x8478: file hello_gdb.c, line 45. (gdb)
Delete break point
Use the delete command and breakpoint number
delete 2
Specify remote application
Specify target remote application:
target remote <BOARD _IP_ADDRESS>:<PORT>
Run binary
To run the binary use the continue, application will stop at breakpoints
continue
Output when gdb encounters a breakpoint
Breakpoint 1, main (argc=1, argv=0xbeae2ea4, envp=0xbeae2eac) at hello_gdb.c:49 (gdb)
Using ddd with gdb
In order to use ddd with arm gdb run ddd and specify the arm gdb:
ddd --debugger /opt/codesourcery/arm-2009q1/bin/arm-none-linux-gnueabi-gdb
ddd has a command line at the GUI, use the same commands as when using gdbtui. In order to run the binary use the exact same command: "continue"
breakpoints can be added and removed manually at the GUI, the break command also works for this.