Guide for gdbserver remote debugging with Magic C++
Last update 06/24/2005
Table of Contents
1. Glossary
There are two common tools used for symbolic debugging software used in Linux based target hardware. The GDB debugger is typically used to debug applications. A JTAG emulator is typically used to debug the Linux kernel and kernel device drivers. Debugging using a JTAG emulator is dependent on the emulator used, and thus is not discussed in this manual.
GDB Debugger. The purpose of a debugger is to allow the developer to see what is going on inside the program while it executes. Use of that debugger is not the topic of this section. For detailed information regarding usage of the GDB debugger, please refer to one of the following:
The standard gdb man pages.
The info pages included on your Linux workstation.
The online manual provided by the Free Software Foundation at http://www.gnu.org/software/gdb/documentation. Cross GDB Debuggers. The corss GDB debugger use slightly different versions of the GDB debugger. The cross GDB debugger has special modifications to work with the embedded target.
gdbserver. The cross debugger executes on the user's Linux workstation. In order to communicate with a program running on the target hardware, an additional program must run on the target hardware. This program is gdbserver. It is included with the target platform toolchain and is installed in the target file system.
gdbserver Communications. There are two methods for communication between the target hardware's gdbserver and the Linux workstation GDB client. One method uses an available serial port while the other uses the Ethernet port.
Some target hardware have multiple serial connectors with one of them dedicated to the system console (typically /dev/ttyS0) and another (/dev/ttyS1) is available for GDB communication with the Linux workstation. In the case where the target hardware has only one serial port, it is probably not available for GDB debugging. In this case, the Ethernet port should be used for GDB communication with the Linux workstation.
If you are going to use the serial port for debugging, see the Serial Port section for additional information about the use and configuration of the board's serial port. Use the connection that is appropriate for your target hardware, specifying it at the time you start the debug session.
Graphical Front-Ends. Magic C++ is a MS VC++ like graphical front end with GDB debugger.
Debug-able Files. You can use Magic C++(with the gdbserver) to debug Linux programs on the target hardware. You can use Magic C++(with the kgdb) to debug Linux kernel on the target hardware.You can use any program invoked from the Linux command line with this debugger, provided that the program was built to be compatible with GDB.
2. Using remote gdb
The easiest way to use gdb for debugging user applications, is to run it directly on the target. However this requires that the gdb on the target has access to the host file system for source code, and requires quite a large amount of memory on the target.
To avoid these problems, it is possible to run gdb on the host, controlling a program running on the target. To do this a small server process is run on the target, specifying a socket or serial port which it should wait on for commands:
target% gdbserver magicuni.ipowermysql.com:6789 application
|
| |
|
|
On the host, simply run gdb, and the connect to the target:
host% sh4-linux-gdb application
GNU gdb 5.1
Copyright 2001 Free Software Foundation, Inc.
This GDB was configured as "--host=i686-pc-linux-gnu --target=sh4-linux"...
(gdb) target remote targetip:6789
Remote debugging using targetip:6789
0x29558080 in ??()
|
|
|
In the target remote command, targetip specifies the target name or IP address, and 6789 is the port number used when gdbserver was started.
Initial the program will be stopped at its entry point, in the C runtime. So the first thing to do is advance to main:
(gdb) break main
Breakpoint 1 at 0x400656: file main.c, line 20.
(gdb) continue
Continuing.
Breakpoint 1, main() at main.c:20
20 printf("Welcome to the application\n");
(gdb)
|
|
|
From here onwards you can debug the target in the same way as you would debug a program on the host.
To avoid typing all these command every time, it may be useful to create a gdb script file. gdb will always run .gdbinit from the users home directory, and the current directory, alternatively it can be started with the command line option -command=script.
3. Using Magic C++
3.1 System Requirements Listed below are the minimum requirements for installing and using the Magic C++ :
- A windows computer with Magic C++ client IDE installed, work as IDE environment
- A cross-development host computer, it can be
- A Unix/Linux/BSD server with Magic C++ server installed
- The same windows computer with Cygwin/MinGW installed
- An embedded target board with remote debugging stub( gdbserver, kgdb or other stubs ) installed, work as the target environment
3.2 Preparing the Debug Program
The effect of this step is to compile the sources including debug information and disabling optimizations.
The corss GDB compiler and debugger are named different from the standard GDB compiler and debugger, so you must configure them in Magic C++ client IDE.

configure cross development tools
Be sure to place the debuggable version of your program into the target file system before attempting to debug it. You may do this by either:
Building a new file system that you can download to the target
Building a new file system that the target hardware then either mounts via NFS
or
Using FTP from the Linux workstation to "put" your program onto the mounted ramdisk file system of the Ethernet connected target hardware If you have loaded the program into ramdisk via FTP, verify that the file permissions are set to grant execute privileges. If not, you can make the file executable using: chmod +x <file>.
3.3 Debugging the program
Once you have placed your executable program in the target hardware's file system, it is ready for debugging using the following steps. On the Linux workstation, you will need the debugging version of your program in the same directory where you will invoke cross debugger.
Start gdbserver. On the target hardware, invoke the gdbserver in the directory where you have the file you are debugging. To start the target hardware-side of the GDB session, do one of the following:
If you are using a network GDB connection, enter the command below:
# cd <development directory>/examples
# gdbserver :5472 hello
The port number 5472 was selected randomly as a high port number. Any high port number that doesn't conflict with existing active ports will work. The command line also indicates the name of the program you intend to debug, hello in this example. This program is the binary Linux program format intended to run on the target hardware.
If using a serial GDB connection, enter the commands below. See the Serial Port section for instructions on building the stty command into busybox.
# stty -F /dev/ttyS1 -iexten -echoctl 115200
# gdbserver /dev/ttyS1 hello
Example: In either case, gdbserver will respond with something like the following example:
# cd <development directory>/examples
# /usr/bin/gdbserver :5472 hello
Process hello created; pid = 26
...
Program load address = 0x109e5ed0
...
Other useful debug information may be reported between the "Process hello created..." line and the "Program load address..." line.
Connect gdbserver. Start the Linux workstation-side of the GDB session by invoking the cross debugger. This establishes a connection to the GDB server previously started on the target hardware. We invoke cross debugger while in the directory containing the debugging version of our program file. Then issue commands at the GDB command line prompt to establish the connection and load the program's debug symbols.
If using a network GDB connection, choose TCP or UDP

configure remote debugging options
Where:
The string x.x.x.x is replaced with the actual IP address of the target hardware. (If you are not sure what the IP is, type "ifconfig" on the target hardware command line to generate a network configuration report).
The port 8888 was selected randomly as a high port number. It must match the port number that was provided on the preceding target hardware gdbserver command.
If using a serial connection to the gdbserver, choose Serial.

configure remote debugging options
Where:
By default, most Linux workstation's serial ports start up at 9600 baud. On the target hardware /dev/ttyS1 starts up at 9600 baud. See the Serial Port section for instructions on building the stty command into target which will allow you to change the baud rate on /dev/ttyS1.
Example: The following messages show a typical session when the cross debugger is connected to the gdbserver: [gnutt@SpudKayak dsc25]$ cd fs/examples/hello
[gnutt@SpudKayak hello]$ arm-uclinux-gdb
GNU gdb 4.18
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "--host=i686-linux --target=arm-elf".
(gdb) set endian little
(gdb) target remote 15.2.200.99:5471
Remote debugging using 15.2.200.99:5471
0x10967390 in ?? ()
(gdb) add-symbol-file hello.debug 0x109e5ed0
add symbol table from file "hello.debug" at text_addr = 0x109e5ed0?
(y or n) y
Reading symbols from hello.debug...done.
(gdb) b main
Breakpoint 1 at 0x109e5eec: file hello.c, line 39.
(gdb) cont
Continuing.
Breakpoint 1, main (argc=276705864, argv=0x0, envp=0x0) at hello.c:39
39 printf("Hello, world!\n");
(gdb)
4. Serial Port
Serial Devices. In this section we discuss the serial port and the two linux devices listed below.
/dev/ttyS0
/dev/ttyS1
/dev/console Program Access to /dev/ttyS0
With serial port support enabled you can use the /dev/ttyS0 Linux device to programmaticly send and receive characters over the serial port. For reference, the make xconfig setting has the effect of enabling the CONFIG_<TARGET PROCESSOR>_SERIAL definition used during the build of the kernel. If you hardware supports /dev/ttyS1, this will enable the second serial port as well.
System Console
Default Console. The /dev/console is the device underlying system's stdin, stdout, and stderr file descriptors. The kernel first tries to open /dev/console when it boots to serve as the console. Failing that, it will try to open /dev/ttyS0.
Login via the Serial Port. If you attach a terminal or a computer running terminal emulation software to the target hardware's serial port, then you can login to the target hardware via the serial port.
Standard IO. Once logged in over the serial port, the system console is automatically mapped to the /dev/ttyS0 device. This means that normal printf() statements in a program will route out the serial port. Or put generically, any reference to the system's stdin, stdout, and stderr device descriptors will map to the /dev/ttyS0, and therefore the serial port.
Restrictions. Because /dev/ttyS0 is the default console, applications should NOT use it for other purposes. In cases where the board has a second serial port, applications can instead use /dev/ttyS1.
Serial Settings
Default Baud Rate. By default, the target hardware /dev/ttyS0 serial port starts up at 115200 baud and /dev/ttyS1 serial port, if available, starts up at 9600 baud (most Linux workstation's start up at 9600 baud). The /dev/ttyS0 baud rate value of 115200 was chosen to be compatible with the target hardware bootloader, which uses 115200 to maximize serial download speeds. A single terminal session (such as minicom) can communicate with the bootloader and then with the booted kernel without changing any settings. Applications that use a different baud rate can use the standard stty utility or ioctl() calls on /dev/ttyS0 or /dev/ttyS1, as appropriate, for changing serial port speed at runtime.
The default /dev/ttyS0 settings are:
115200 baud
8 data bits
no parity
1 stop bit The default /dev/ttyS1 settings are:
9600 baud
8 data bits
no parity
1 stop bit Changing Serial Port Settings
stty. busybox supports the stty program for changing serial port settings. However, by default stty is not enabled when busybox is built. To build stty into busybox, follow these instructions:
$ cd <development directory>/fs/userland/busybox
$ mv Config.h Config.h.orig
$ sed -e 's-//#define BB_STTY-#define BB_STTY-' < Config.h.orig > Config.h
$ make clean
$ cd <development directory>
$ make fs Once you have built stty into busybox, you can set change the baud rate using the following:
# stty -F /dev/ttyS1 -iexten -echoctl 115200 Kernel printk() over Serial
Default Configuration. In the make xconfig, you will encounter the option "kernel printks on serial port." This feature is enabled by default. This is what allows the internal kernel messages to appear over the serial line and therefore on your remote connected terminal session (such as minicom). Recall that printk() is NOT the same as printf():
printk() is only performed within the kernel itself for various diagnostics and OS warning messages.
printf() is used by applications in user space for general console output. The setting we use here only applies to the kernel printk() messages. For reference, this setting has the effect of enabling the CONFIG_SERIAL_CADENUX_CONSOLE definition used during the build of the kernel.
Back to top |