DBUG(3L)

NAME
dbug - a toolset for internal debugging of C programs.

SYNOPSIS
Note, the following "functions" are C macros. Therefore, the description of the parameters are not necessarily correct C. The intention is, to describe as close as possible but shortly what type of "data" can be used for the parameters of the macros.

#include <dbug.h>

DBUG_ENTER ( aName )
    char *    aName;

        DBUG_RETURN ( aValue )
            int    aValue;

                DBUG_VOID_RETURN

                DBUG_PRINT ( aLabelString, (thePrintfParameters) )
                    char *    aLabelString;
                    ParameterList thePrintfParameters;

                        DBUG_PROCESS ( aName )
                            char *    aName;

                                DBUG_PUSH ( aDbugOptionString )
                                    char *    aDbugOptionString;

                                        DBUG_POP ()

                                        DBUG_FILE

                                        DBUG_EXECUTE ( aLabelString, someCode )
                                            char *    aLabelString;
                                            C-Code    someCode;

                                                DBUG_SETJMP ( env )
                                                    jmp_buf    env;

                                                        DBUG_LONGJMP ( env, val )
                                                            jmp_buf    env;
                                                            int    val;

DESCRIPTION
Dbug is a macro based C internal debugging package which has proven to be a very flexible and useful tool for debugging, testing, and porting C programs.

Internal debugging are typically "print statements" included into the program source. Dbug provides for enhanced capabilities to do so. In addition each capability can be individually enabled or disabled at the time a program is invoked by specifying the appropriate command line arguments.

So, all of the features of the dbug package can be enabled or disabled dynamically at execution time. This means that production programs will run normally when debugging is not enabled, and eliminates the need to maintain two separate versions of a program.

The following specifies a summary of the dbug capabilities:

-   Execution trace showing function level control flow in a semi-graphically manner using indentation to indicate nesting depth.

-   Output the values of all, or any subset of, key internal variables.

-   Limit actions to a specific set of named functions.

-   Limit function trace to a specified nesting depth.

-   Label each output line with source file name and line number.

-   Label each output line with name of current process.

-   Push or pop internal debugging state to allow execution with built in debugging defaults.

-   Redirect the debug output stream to standard output (stdout) or a named file. The default output stream is standard error (stderr).

Many of the things easily accomplished with conventional debugging tools, such as symbolic debuggers, are difficult or impossible with this package, and vice versa. Thus the dbug package should not be thought of as a replacement or substitute for other debugging tools, but simply as a useful addition to the program development and maintenance environment.

The dbug package imposes only a slight speed penalty on executing programs, typically much less than 10 percent, and a modest size penalty, typically 10 to 20 percent. By defining a specific C preprocessor symbol both of these can be reduced to zero with no changes required to the source code.

Notice, that all of the debugger functions are implemented via preprocessor macros. This does not detract from the readability of the code and makes disabling all debug compilation trivial (a single preprocessor symbol, DBUG_OFF , forces the macro expansions to be null).

SUMMARY OF MACROS
This summarizes the usage of all currently defined macros in the dbug package. The macros definitions are found in the user include file dbug.h from the standard include directory.

DBUG_ENTER
    Used to tell the runtime support module the name of the function being entered. The argument must be of type "pointer to character". The DBUG_ENTER macro must precede all executable lines in the function just entered, and must come after all local declarations. Each DBUG_ENTER macro must have a matching DBUG_RETURN or DBUG_VOID_RETURN macro at the function exit points. DBUG_ENTER macros used without a matching DBUG_RETURN or DBUG_VOID_RETURN macro will cause warning messages from the dbug package runtime support module.

    EX: DBUG_ENTER ("main");

DBUG_RETURN
    Used at each exit point of a function containing a DBUG_ENTER macro at the entry point. The argument is the value to return. Functions which return no value (void) should use the DBUG_VOID_RETURN macro. It is an error to have a DBUG_RETURN or DBUG_VOID_RETURN macro in a function which has no matching DBUG_ENTER macro, and the compiler will complain if the macros are actually used (expanded).

    EX: DBUG_RETURN (value);
    EX: DBUG_VOID_RETURN;

DBUG_PROCESS
    Used to name the current process being executed. A typical argument for this macro is "argv[0]", though it will be perfectly happy with any other string.

    EX: DBUG_PROCESS (argv[0]);

DBUG_PUSH
    Sets a new debugger state by pushing the current dbug state onto an internal stack and setting up the new state using the debug control string passed as the macro argument. The most common usage is to set the state specified by a debug control string retrieved from the argument list. Note that the leading "-#" in a debug control string specified as a command line argument must not be passed as part of the macro argument. The proper usage is to pass a pointer to the first character after the "-#" string.

    EX: DBUG_PUSH ((argv[i][2]));
    EX: DBUG_PUSH ("d:t");
    EX: DBUG_PUSH (" ");

DBUG_POP
    Restores the previous debugger state by popping the state stack. Attempting to pop more states than pushed will be ignored and no warning will be given. The DBUG_POP macro has no arguments.

    EX: DBUG_POP ();

DBUG_FILE
    The DBUG_FILE macro is used to do explicit I/O on the debug output stream. It is used in the same manner as the symbols "stdout" and "stderr" in the standard I/O package.

    EX: fprintf (DBUG_FILE, "Doing my own I/O!\n");

DBUG_EXECUTE
    The DBUG_EXECUTE macro is used to execute any arbitrary C code. The first argument is the debug keyword, used to trigger execution of the code specified as the second argument. This macro must be used cautiously because, like the DBUG_PRINT macro, it is automatically selected by default whenever the 'd' flag has no argument list (I.E., a "-#d:t" control string).

    EX: DBUG_EXECUTE ("abort", abort ());

DBUG_N
    These macros, where N is in the range 2-5, are currently obsolete and will be removed in a future release. Use the new DBUG_PRINT macro.

DBUG_PRINT
    Used to do printing via the "fprintf" library function on the current debug stream, DBUG_FILE. The first argument is a debug keyword, the second is a format string and the corresponding argument list. Note that the format string and argument list are all one macro argument and must be enclosed in parenthesis.

    EX: DBUG_PRINT ("eof", ("end of file found"));
    EX: DBUG_PRINT ("type", ("type is %x", type));
    EX: DBUG_PRINT ("stp", ("%x -> %s", stp, stp -> name));

DBUG_SETJMP
    Used in place of the setjmp() function to first save the current debugger state and then execute the standard setjmp call. This allows the debugger to restore its state when the DBUG_LONGJMP macro is used to invoke the standard longjmp() call. Currently all instances of DBUG_SETJMP must occur within the same function and at the same function nesting level.

    EX: DBUG_SETJMP (env);

DBUG_LONGJMP
    Used in place of the longjmp() function to first restore the previous debugger state at the time of the last DBUG_SETJMP and then execute the standard longjmp() call. Note that currently all DBUG_LONGJMP macros restore the state at the time of the last DBUG_SETJMP. It would be possible to maintain separate DBUG_SETJMP and DBUG_LONGJMP pairs by having the debugger runtime support module use the first argument to differentiate the pairs.

    EX: DBUG_LONGJMP (env,val);

DEBUG CONTROL STRING
The debug control string is used to control the "behaviour" of the dbug macros, when running the application. The debug control string is passed to the dbug package via the DBUG_PUSH() macro (note, that the parameter of this macro may be the value of a program argument; see example above).

The following list summarizes the currently available debugger options and the flag characters which enable or disable them. Debugger options may be concatenated to a debug control string using the ":" (colon) as a seperator (e.g., <option1>:<option2>:...:<optionN>).

Argument lists enclosed in '[' and ']' are optional.

d[,keywords]
    Enable output from macros with specified keywords. A null list of keywords implies that all keywords are selected.

D[,time]
    Delay for specified time after each output line, to let output drain. Time is given in tenths of a second (value of 10 is one second). Default is zero.

f[,functions]
    Limit debugger actions to the specified list of functions. A null list of functions implies that all functions are selected.

F   Mark each debugger output line with the name of the source file containing the macro causing the output.

g   Turn on machine independent profiling. A profiling data collection file, named dbugmon.out, will be written for postprocessing by the "analyze(1L)" program. The accuracy of this feature is relatively unknown at this time.

i   Identify the process emitting each line of debug or trace output with the process id for that process.

L   Mark each debugger output line with the source file line number of the macro causing the output.

n   Mark each debugger output line with the current function nesting depth.

N   Sequentially number each debugger output line starting at 1. This is useful for reference purposes when debugger output is interspersed with program output.

o[,file]
    Redirect the debugger output stream to the specified file. The default output stream is stderr. A null argument list causes output to be redirected to stdout.

p[,processes]
    Limit debugger actions to the specified processes. A null list implies all processes. This is useful for processes which run child processes. Note that each debugger output line can be marked with the name of the current process via the 'P' flag. The process name must match the argument passed to the DBUG_PROCESS macro.

P   Mark each debugger output line with the name of the current process from argv[0]. Most useful when used with a process which runs child processes that are also being debugged. Note that the parent process must arrange for the debugger control string to be passed to the child processes.

r   Used in conjunction with the DBUG_PUSH macro to reset the current indentation level back to zero. Most useful with DBUG_PUSH macros used to temporarily alter the debugger state.

t[,N]
    Enable function control flow tracing. The maximum nesting depth is specified by N, and defaults to 200.

USAGE
The following example shows a very simple use of the dbug facilities.

First, the source code including some dbug statements is given:

    #include <stdio.h>
    #include <dbug.h>
    main (argc, argv)
    int argc;
    char *argv[];
    {
        int i;
        int atoi();
        DBUG_ENTER ("main");
        DBUG_PROCESS (argv[0]);
        for (i = 1; i < argc && argv[i][0] == '-'; i++) {
    	switch (argv[i][1]) {
    	    case '#':
    		DBUG_PUSH (&(argv[i][2]));
    		break;
    	}
        }
        for (; i < argc; i++) {
    	DBUG_PRINT ("args", ("argv[%d] = %s", i, argv[i]));
    	printf ("%F\n", 1.0/atoi(argv[i]));
        }
        DBUG_RETURN (0);
    }

        The following invocation of the program "inverse" compiled from the source above would cause the corresponding outputs:

            $ inverse  2 4
            0.5
            0.25
            $ inverse -#t  2 4
            |
            0.5
            0.25
            < main
            inverse -#d:t  2 4
            | args: argv[2] = 2
            0.5
            | args: argv[3] = 4
            0.25
            < main

FILES
/LocalTools/lib/local/libdbug.a /LocalTools/include/local/dbug.h

SEE ALSO
DBUG Users Manual, analyze(1L)

ENVIRONMENT
none

BUGS
There still are some.

COPYRIGHT
none

AUTHORS
Fred Fish, Binayak Banerjee
Enhanced Software Technologies, Tempe, AZ
asuvax!mcdphx!estinc!fnf, seismo!bpa!sjuvax!bbanerje