10.5. Debugging a program

The use of an interpreter engine enables some unique approaches to the process of debugging and testing software. This section describes some of the tools and techniques for debugging an application.

10.5.1. Interacting with an Active Program

Gamma can provide an active view-port into the running application. Another task (or shell) can, at any time, interact with a running Gamma program, without halting it or otherwise disturbing its real-time response. This provides an approach to debugging that is much more powerful than adding debug print statements.

For example, suppose that we started a process with the name "my_task" interactively:

Gamma> init_ipc ("my_task");
t
		  

The gsend (for Gamma) or lsend (for Lisp) utility is used to interact with a running application from a shell:

[sh]$ gsend my_task
my_task>
		

The lsend utility accepts Lisp input as the default and gsend accepts Gamma input as its default.

Once connected to a running Gamma program using gsend/lsend, the developer can:

  • query/set variables/objects/instance_vars in the global scope

  • call functions/methods

  • re-define function definitions

  • run any Gamma command interactively

The syntax for starting the gsend utility is as follows:

gsend [-l] [-g] [program] [pid]

-l

Accept Lisp input from the keyboard.

-g

Accept Gamma input from the keyboard.

program

a Gamma program name, attached by name_attach, init_ipc, or qnx_name_attach

pid

(QNX 4 only) a task ID

gsend and lsend attach to a running Gamma program and allow the user to send commands without exiting the event loop of the attached process. Any statement may be issued, including changing the definitions of existing functions. In our simple example we can call the princ function for my_task to execute:

[sh]$ gsend my_task
my_task> princ ("Hello!\n");
t
		  

Notice that event processing stops for the duration of the command. Now let's look at my_task. In order to respond to requests from gsend/lsend, my_task must be executing an event loop. We can start one using the next_event function in a while statement:

Gamma> init_ipc ("my_task");
t
Gamma> while(t) next_event();
Hello!
		

The my_task program continues to run as normal during this operation.

This presents an excellent opportunity for rapid development by programmers. Typically developers are used to the "code, compile, link, run, debug, code..." iterative approach to programming. Once a Gamma developer makes a program with a well written event loop, such as the one shown in the section below on trapping errors, programming and testing can become operations that happen in parallel.

Programmers will find that after a piece of code has been written, it can be uploaded to an already running Gamma process with gsend/lsend by using a simple "cut and paste". The code is automatically assimilated into Gamma and ready to run. Better yet, if there is a problem with the code, the programmer receives immediate feedback and can track the problem down through an interactive debugging prompt that can be built right into the event-loop.