Go to the first, previous, next, last section, table of contents.


You Provide the Top Level for the Libgdb Command Interpreter

When you use libgdb, your code is providing a top level for the command language interpreter. The top level is significant because it provides commands for the the interpreter to execute. In addition, the top level is responsible for handling some kinds of errors, and performing certain cleanup operations on behalf of the interpreter.

Initialization

Before calling any other libgdb functions, call this:

Function: void gdb_init (void)
Perform one-time initialization for libgdb.

An application may wish to evaluate specific gdb commands as part of its own initialization. The details of how this can be accomplished are explained below.

The Top-Level Loop

There is a strong presumption in libgdb that the application has the form of a loop. Here is what such a loop might look like:

while (gdb_still_going ())
  {
    if (!GDB_TOP_LEVEL ())
      {
        char * command;
        gdb_start_top_loop ();
        command = process_events ();
        gdb_execute_command (command);
        gdb_finish_top_loop ();
      }
    }

The function gdb_still_going returns 1 until the gdb command `quit' is run.

The macro GDB_TOP_LEVEL invokes setjmp to set the top level error handler. When a command results in an error, the interpreter exits with a longjmp. There is nothing special libgdb requires of the top level error handler other than it be present and that it restart the top level loop. Errors are explained in detail in a later chapter.

Each time through the top level loop two important things happen: a debugger command is constructed on the basis of user input, and the interpreter is invoked to execute that command. In the sample code, the call to the imaginary function process_events represents the point at which a graphical interface should read input events until ready to execute a debugger command. The call to gdb_execute_command invokes the command interpreter (what happens to the output from the command will be explained later).

Libgdb manages some resources using the top-level loop. The primary reason for this is error-handling: even if a command terminates with an error, it may already have allocated resources which need to be freed. The freeing of such resources takes place at the top-level, regardless of how the the command exits. The calls to gdb_start_top_loop and gdb_finish_top_loop let libgdb know when it is safe to perform operations associated with these resources.

Breakpoint Commands

Breakpoint commands are scripts of GDB operations associated with particular breakpoints. When a breakpoint is reached, its associated commands are executed.

Breakpoint commands are invoked by the libgdb function gdb_finish_top_loop.

Notice that if control returns to the top-level error handler, the execution of breakpoint commands is bypassed. This can happen as a result of errors during either gdb_execute_command or gdb_finish_top_loop.

Application Initialization

Sometimes it is inconvenient to execute commands via a command loop for example, the commands an application uses to initialize itself. An alternative to execute_command is execute_catching_errors. When execute_catching_errors is used, no top level error handler need be in effect, and it is not necessary to call gdb_start_top_loop or gdb_finish_top_loop.

Cleanup

The debugger command "quit" performs all necessary cleanup for libgdb. After it has done so, it changes the return value of gdb_still_going to 0 and returns to the top level error handler.


Go to the first, previous, next, last section, table of contents.