Debuggers For FronTier

FronTier's own debugger

FronTier has its own debugger, maintained by its developers. This debugger is essentially a smart version of printing, which can be turned on or off through a keyword from the input file. The developer can change the flow of the code when the keyword is chosen, and produce for instance additional output, or initiate additional diagnostics.

We have such a system for a number of important reasons:

  1. Sophisticated debuggers are usually not available on new architectures.
  2. FronTier is a heavy user of pointers, a place where many standard debuggers have deficiences.
  3. The structures used by FronTier are complicated. It is important to be able make intelligently structured output for debugging. For instance you may suspect that something is wrong in a structure or in some element in a huge array. To be able to redirect the code to produce easily comprehended output is a big asset.
  4. This debugging system is part of the development of new code, where most bugs arise. Since it is maintained it indicates places where bugs existed at some point, and can provide already comprehensible information. This feature is particularly important when one needs to debug an unfamiliar part of the code.
  5. This debugging system remains in the code: just remove the keyword from the the input file when you are done! No need to recompile.
  6. When trying to locate a bug, it is not necessary to recompile part of the code with the "-g" option, for use with UNIX debuggers. A systematic use of this debugging system can tremendously shorten the time required to find the troubled area.

The debugging system is explained in "util/debug.c". The list of debugging keywords is initiated by the user in the very beginning of input to FronTier:

: debug
: file
: keyword_1
: keyword_2
(etc)
: keyword_n
: end
and the code memorizes the sequence of keywords "keyword_1",....,"keyword_n". Whenever FronTier sees the command:
	debug("keyword",string);
It will print "string", if "keyword" is in the list.

The function "debugging("keyword")" returns TRUE exactly when the "keyword" is in the list. A typical debugging fragment is then:

if(debugging("keyword"))
	{
		STUFF
	}
A good first choice for keyword is as the name of the function in which debugging needs to be done. It is defined in "util/fnamedebug.h", and works as follows:
	return_type my_function(argument_list)
{
	set_function_name(my_function)   /* defines a string "my_function" */

	DEBUG_ENTER                      /* prints: "Entered my_function", when
	                                            my_function is a keyword */

	STUFF

	if(DEBUG)                        /* DEBUG is TRUE, if my_function is keyword */
		{
			STUFF for debugging
		}
	DEBUG_LEAVE                      /* prints: "Left my_function", when 
						    my_function is a keyword */
	return (whatever);
}
We insist that new functions added to the code have this structure

A last use of this debugging system is for tracing back at "clean_up". FronTier maintains two lists:

Unless the code ends with a succesfull run ("ERROR = 0"), the function "clean_up" will print these two lists. This allows some form of localization of the error.

Generic Debuggers.

Most UNIX systems have various C-program debuggers. Besides serving debugging purposes, they can give a very quickly a good idea of the logic of a code segment. To run FronTier from UNIX debuggers requires a specially formatted input
Sparc
dbx, dbxtool (dbx with graphical interface)

Sgi
dbx, xdbx (dbx with graphical interface), and CVD (most useful).

Galaxy
ddd, a visual frontend to dbx, xdbx or gdb.
These debuggers require symbol tables for the files you want to look at. As a result parts of FronTier relevant to your investigation have to be compiled with the "-g" option. The best thing to do is:

Advantages
Standard Debuggers will give you a very good idea of the flow of FronTier, they will allow you to find some run-time errors (for instance segmentation violations) very easily, and allow to check how every variable changes.

Disadvantages
Most generic debuggers have difficulties with pointers Debuggers can provide you with an ernormous of detailed information. It is easy to forget that the place where you find the error first (bug symptom), and the place where the error is created (the bug) may be totally unrelated.

User-friendly debuggers are not the first priority of developers of new platforms. As a result generic debuggers for new platforms are usually primitive, and themselves buggy.



Back to Main Page


Comments?

Authors: Folkert Tangerman
Last revision: December 2, 1998

Copyright 1997 This article may be redistributed to other individuals for noncommercial use, provided that the entire text, all HTML codes, and this copyright notice remains intact and unaltered in any way. This article may not be resold, reprinted, or redistributed in whole or in part for compensation of any kind without prior written permission of the author.