| Red Hat Documentation |
|
The GDB remote serial protocol The following documentation discusses the remote serial protocol for hosts and targets.
GDB already understands how to use this protocol; when everything else is set up, you can simply use the ‘target remote’ command (see Specifying a debugging target). You must link with your program a few special-purpose subroutines that implement the GDB remote serial protocol. The file containing these subroutines is called a debugging stub. On certain remote targets, you can use an auxiliary program gdbserver instead of linking a stub into your program. See Using the gdbserver program for details.
m68k-stub.c
i386-stub.c
The debugging stub for your architecture supplies the following three subroutines.
handle_exception
handle_exception takes control when your program stops during execution (for example, on a breakpoint), and mediates communications with GDB on the host machine. This is where the communications protocol is implemented; handle_ exception acts as the GDB representative on the target machine; it begins by sending summary information on the state of your program, then continues to execute, retrieving and transmitting any information GDB needs, until you execute a GDB command that makes your program resume; at that point, handle_exception returns control to your own code on the target machine. breakpoint
Call breakpoint if none of these is true, or if you simply want to make certain your program stops at a predetermined point for the start of your debugging session. The debugging stubs that come with GDB are set up for a particular chip architecture, but they have no information about the rest of your debugging target machine. First of all, you need to tell the stub how to communicate with the serial port.
Write this subroutine to read a single character from the serial port. It may be identical to getchar for your target system; a different name is used to allow you to distinguish the two if you wish. Write this subroutine to write a single character to the serial port. It may be identical to putchar for your target system; a different name is used to allow you to distinguish the two if you wish. Getting the debugging target to return the proper status to GDB probably requires changes to the standard stub; one quick and dirty way is to just execute a breakpoint instruction (the “dirty” part is that GDB reports a SIGTRAP instead of a SIGINT). Other routines you need to supply are the following.
You need to do this because the stub does not have any way of knowing what the exception handling tables on your target system are like (for example, the processor’s table might be in ROM, containing entries which point to a table in RAM). exception_number is the exception number which should be changed; its meaning is architecture-dependent (for example, different numbers might represent divide by zero, misaligned access, etc). When this exception occurs, control should be transferred directly to exception_address, and the processor state (stack, registers, and so on) should be just as it is when a processor exception occurs. So if you want to use a jump instruction to reach exception_address, it should be a simple jump, not a jump to subroutine. For the 386, exception_address should be installed as an interrupt gate so that interrupts are masked while the handler runs. The gate should be at privilege level 0 (the most privileged level). The SPARC and 68k stubs are able to mask interrup themselves without help from exceptionHandler. void flush_i_cache()
On target machines that have instruction caches, GDB requires this function to make certain that the state of your program is stable.
In summary, when your program is ready to debug, you must use the following steps.
Make sure you have the supporting low-level routines (see What you must do for the stub): getDebugChar, putDebugChar, flush_i_cache, memset, exceptionHandler. 2.
breakpoint(); For the 680x0 stub only, you need to provide a variable called exceptionHook. Normally you just use void (*exceptionHook)() = 0;, but if before calling set_debug_traps, you set it to point to a function in your program, that function is called when GDB continues after stopping on a trap (for example, bus error). The function indicated by exceptionHook is called with one parameter: an int which is the exception number. 4.
5.
6.
7.
Now you can use all the usual commands to examine and change data and to step and continue the remote program. To resume the remote program and stop debugging it, use the detach command. Whenever GDB is waiting for the remote program, if you type the interrupt character (often, Ctrl-C), GDB attempts to stop the program. This may or may not succeed, depending in part on the hardware and the serial drivers the remote system uses. If you type the interrupt character once again, GDB displays the following prompt:
Give up (and stop debugging it)? (y or n) The stub files provided with GDB implement the target side of the communication protocol, and the GDB side is implemented in the GDB source file ‘remote.c’. Normally, you can simply allow these subroutines to communicate, and ignore the details. (If you’re implementing your own stub file, you can still ignore the details: start with one of the existing stub files. ‘sparc-stub.c’ is the best organized, and therefore the easiest to read.) However, there may be occasions when you need to know something about the protocol—for example, if there is only one serial port to your target machine, you might want your program to do something special if it recognizes a packet meant for GDB. All GDB commands and responses (other than acknowledgements, which are single characters) are sent as a packet which includes a check-sum. A packet is introduced with the character, ‘$’, and ends with the character, ‘#’, followed by a two-digit checksum: $packet info#checksum. checksum is computed as the modulo 256 sum of the packet info characters. When either the host or the target machine receives a packet, the first response expected is an acknowledgement: a single character, either ‘+’ (to indicate the package was received correctly) or ‘-’ (to request retransmission). The host (GDB) sends commands, and the target (the debugging stub incorporated in your program) sends data in response. The target also sends data when your program stops. Command packets are distinguished by their first character, which identifies the kind of command. The following are some of
the commands currently supported (for a complete list of commands, look
in ‘gdb/remote.c.’):
G
maddr, count
Maddr, count:...
c c addr
s s addr
k
?
T
If you have trouble with the serial connection, you can use the command, set remotedebug. This makes GDB report on all packets sent back and forth across the serial line to the remote machine. The packet-debugging information is printed on the GDB standard output stream. set remotedebug off turns it off, and show remotedebug shows you its current state. gdbserver is a control program for Unix-like systems, which allows you to connect your program with a remote GDB via target remote—but without linking in the usual debugging stub. gdbserver is not a complete replacement for the debugging stubs, because it requires essentially the same operating-system facilities that GDB itself does. In fact, a system that can run gdbserver to connect to a remote GDB could also run GDB locally! gdbserver is sometimes useful nevertheless, because it is a much smaller program than GDB itself. It is also easier to port than all of GDB, so you may be able to get started more quickly on a new system by using gdbserver. Finally, if you develop code for real-time systems, you may find that the tradeoffs involved in real-time operation make it more convenient to do as much development work as possible on another system, for example by cross-compiling. You can use gdbserver to make a similar choice for debugging. GDB and gdbserver
communicate via either a serial line or a TCP connection, using the standard
GDB remote serial protocol.
You need to have a copy of the program you want to debug. gdbserver does not need your program’s symbol table, so you can strip the program if necessary to save space. GDB on the host system does all the symbol handling. To use the server, you must tell it how to communicate with GDB; the name of your program; and the arguments for your program. The syntax has the following example's format.
You must use the same port number with the host GDB target remote command. You need an unstripped copy of your program, since GDB needs symbols and debugging information. Start up GDB as usual, using the name of the local copy of your program as the first argument. (You may also need the ‘--baud’ option if the serial line is running at anything other than 9600 bps.) After that, use target remote to establish communications with gdbserver. Its argument is either a device name (usually a serial device like /dev/ttyb) or a TCP port descriptor in the form, host:PORT. For example, (gdb) target remote /dev/ttyb communicates with the server via serial line, /dev/ttyb. target remote the-target:2345 communicates via a TCP connection to port 2345 on host, the-target. For TCP connections, you must start up gdbserver prior to using the target remote command. Otherwise you may get an error whose text depends on the host system, but which usually looks something like ‘Connection refused’. Using the gdbserve.nlm program gdbserve.nlm is a control program for NetWare systems, which allows you to connect your program with a remote GDB via target remote. GDB and gdbserve.nlm communicate via a serial line, using the standard GDB remote serial protocol.
You need to have a copy of the program you want to debug. gdbserve.nlm does not need your program’s symbol table, so you can strip the program if necessary to save space. GDB on the host system does all the symbol handling. To use the server, you must tell it: how to communicate with GDB, the name of your program, and the arguments for your program. The syntax is the following.
[ BAUD=baud ] program [ args ... ]
You need an unstripped copy of your program, since GDB needs symbols and debugging information. Start up GDB as usual, using the name of the local copy of your program as the first argument. (You may also need the ‘--baud’ option if the serial line is running at anything other than 9600 bps. After that, use target remote to establish communications with gdbserve.nlm. Its argument is a device name (usually a serial device, like /dev/ttyb). For example, (gdb) target remote /dev/ttyb communicates with the server via serial line, /dev/ttyb. GDB with a remote i960 (Nindy) Nindy is a ROM Monitor program for Intel 960 target systems. When GDB is configured to control a remote Intel 960 using Nindy, you can tell GDB how to connect to the 960 in the following ways:
If you simply start gdb without using any command-line options, you are prompted for what serial port to use, before you reach the ordinary GDB prompt:
The following are the startup
options for beginning your GDB session with a Nindy-960 board attached.
-O
If you specify ‘-O’, but are actually trying to connect to a target system that expects the newer protocol, the connection fails, appearing to be a speed mismatch. GDB repeatedly attempts to reconnect at several different line speeds. You can abort this process with an interrupt. -brk
Many target systems do not have the hardware that this requires; it only works with a few boards.
|
|
© 2001 Red Hat, Inc. All rights reserved. About Red Hat : Legal statement : Privacy statement : Y2K statement : Contact Red Hat |