Optimization Caveat: It is possible to use GDB with optimized code (I do it all the time) but this may change the flow of execution, subroutine calls (inlining) and may cause variables to `disappear' etc.
ddd --debugger <cross_arch>-rtems-gdb
Note: you need to set PATH prior to starting ddd/gdb, see below.
Upon connection to the target, the host computer obtains a list of currently loaded object files from the target. In order for the host GDB being able to locate the necessary object files, the PATH environment variable must point to the directories containing these objects. Note that GDB doesn't define a dedicated path variable for `cross-architecture objects' but requires the user to set the ordinary PATH that is also searched for host executables! Note that PATH is an environment variable and cannot be changed from within a GDB session (GDB's environ and path commands only affect the PATH as seen by a native debuggee and don't have any effect in a cross-gdb session).
GDB also features a load command to instruct the target computer to load/link object modules. Since the target computer usually sees a directory tree that is different from the host, any path information is discarded from the load argument - instead, the target's PATH environment variable must contain the directory where the target can locate the object that is to be loaded.
rtems_gdb_start(int agent_priority, char *serial_name)
Passing a priority of 0 lets the daemon pick its default scheduling priority. The second argument defines the connection method to be used. A NULL pointer lets the daemon listen on TCP port 2159 (registered port number for the gdb remote protocol) for an incoming connection, if a string is passed, it must be the path to a serial device, e.g., /dev/ttyS1.
The agent can be stopped (
rtems_gdb_stop()) and restarted
with a different priority and/or communication method.
Note: rtems 4.6.2 requires a patch for this to work safely since the operation involves one task closing a socket on which another task is blocking.
The syntax for connecting to a target is (TCP)
(gdb) target rtems-remote <target>:2159or
(gdb) target rtems-remote <com_port_on_host>(serial) - note that the agent's serial port runs at 115200 8N1 - use GDB's remote baud command.
Note that rtems-remote is an extension of the standard GDB `remote' target - it adds support for Cexp modules (names, section addresses etc.).
Once connected to the target, the debugger is attached to a dummy thread context. All user and system threads are executing normally at this point.
Use the detach command to close the connection to the target at any time. All stopped threads will be resumed.
rtems_gdb_start()the agent is executed in the context of the the caller, i.e., no separate task is created. Thus, the agent may be run from a shell (e.g., ``Cexp'') and take over the console line for the duration of the session, i.e., until the detach command is issued from GDB. In this ``foreground'' mode of operation, the agent terminates after a the session is ended returning control to the caller of
A sample session example:
Cexp>rtems_gdb_start(-1,0) GDB Daemon starting < scrambled output since terminal mode changed > .y < exit from terminal program and start gdb > (gdb) target rtems-remote < /dev/ttySxx > (gdb) < session commands > (gdb) detach (gdb) quit < restart terminal program and resume Cexp session > Cexp>
Once stopped, a thread remains suspended until you issue the continue command or detach (terminate the session). Either of those operations lets all stopped threads resume.
You can hit <Ctrl>-C to interrupt the target; this only interrupts the `dummy'/`helper' thread and attaches GDB to it. I.e.,
target rtems-remote xx:2159 //connect, attach to 'helper'At this point, the helper is stopped - you can inspect its registers etc. everyone else continues normally
info threads t 14 //switch to thread ID 14Thread 14 is stopped. The helper remains stopped. Inspect T14's registers + stack
t 12 //switch to thread ID 12helper, T14 and T12 are stopped; inspect T12's registers + stack
t 14 //switch back to thread ID 14helper, T14 and T12 remain stopped; inspect T14's registers + stack
cont //resume everythinghelper, T14 and T12 are resumed
<Ctrl>-C //interruptinterrupt, stop helper and attach to it - same state as after connection was established.
(gdb) print printf("Hello\n")invokes the printf routine on the target, retrieves the return value and prints it to the gdb console.
This is actually a pretty complex operation involving creating a dummy stack frame and appropriate arguments etc. on the target. Some targets' exception handlers may not expect modifications of the stack and might crash as a result of an attempt to call a routine on the target.
Also, it should be noted that the routine is always executed in the context of the ``current task''. Hence, the ``current task''
<Ctrl>-<Shift>-L(default) to refresh the display.