ain@j.cc.purdue.edu (Patrick White) (12/19/87)
Program Name: debug source Submitted By: John G. Hardie <rutgers!cisunx.psu.edu!psuvax1!pitt! jgh2@uunet.uu.net> Summary: a set of rotines that aid in debugging programs. Poster Boy: Pat White (ain@j.cc.purdue.edu) Compiled, but not used. NOTES: I had to change the void for go_away() to an int to get it to compile, but that was probably because I was too brain dead at the time to figure out what he was doing. -- Pat White (co-moderator comp.sources/binaries.amiga) UUCP: j.cc.purdue.edu!ain BITNET: PATWHITE@PURCCVM PHONE: (317) 743-8421 U.S. Mail: 320 Brown St. apt. 406, West Lafayette, IN 47906 ---------------------------------------- # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # README # debug.c # This archive created: Fri Dec 18 15:59:15 1987 # By: Patrick White (PUCC Land, USA) cat << \SHAR_EOF > README The following are two routines that I wrote to make tracing C programs easier. They aren't sophisticated, nor fancy but they are usually sufficient for the purpose, and they are easy to use. USAGE: 1) compile debug.c -> debug.o 2) call the debugging routines wherever desired in your source code. 3) compile and link with debug.o That's all folks. I hope that you find these routines useful. Let me know. -- John G. Hardie UUCP: jgh2@cisunx.UUCP Dept. of Physics, -or- jgh2@unix.cis.pittsburgh.edu@pitt Univ. of Pittsburgh BIX: jhardie Pittsburgh, PA 15260 BITNET: JGH2@PITTVMS SHAR_EOF if test 600 -ne "`wc -c README`" then echo shar: error transmitting README '(should have been 600 characters)' fi cat << \SHAR_EOF > debug.c /************************************************************************* * Debugging/Tracing routines. * * * DEBUGGING ROUTINE * * void debug(level,str,int1,int2,doubl1,doubl2) * where: * level - integer - level of debug call. * str - char * - labelling string (may be NULL) * int1,2 - int * - integer args (may be NULL) * doubl1,2 - double * - double args (may be NULL) * * if an argument is NULL, it will not be printed in the debug * message. The format of the debug message is: * * 'DEBUGGER called at level:<lev> with:' * 'Str: <string>' * 'I1=<int1> I2=<int2>' * 'F1=<doub1> F2=<doub2>' * * The level of debugging can be controlled by setting the * appropriate bits in the debugging mask defined below. The mask * globalmask controlls whether there is complete (at all levels) * debugging, selective debugging or no debugging. * * The debugging mask works as follows, * The mask is a 32 bit unsigned integer, so there are 32 possible * debugging levels. Each bit corresponds to a level. If a * bit is set, then that level is enabled and debugging info * is printed for that level. If all the bits are set, then the * message is printed for all levels, if no bits are set, then * no debugging info is printed. * * In addition, if the flag 'trace' is set, the debug funcion will * stop the program after each message is printed and give the user * the option to a) continue the program - or - * b) abort the program. * In the case of b, the debug funtion will call the function * *exitfunc(). The default exitfunc() is the ANSI function * exit(), but it may be reassigned by the user in the debug_level() * call. If any memory is allocated, files opened, libraries opened, * etc. it is recommended that you reassign the exit function so * that any allocated resources are closed before the program * exits. * * Also, if the constant NODEBUGGER is defined, the debug function * will be #ifdef'ed out and simply become a Jump/Return pair. * (actually, the function will simply do a return, but the compiler * will still insert the parameter setup code, stack checking (if * enabled) and any other overhead...<sigh> * * SET UP/ DEBUG LEVEL CHANGES * * void debug_level(mask,trace,func) * where mask - int - mask to be used in defining * the debug level. * trace - int - flag. If set, then debug() * will stop after each message * and wait for the user to signal * that it is OK to continue. * func -(*function)() - pointer to the function that will * be called on exit (if trace is set) * if this field is NULL, the default * function exit() will be called. * * This function may be called to change the default debugging * level ( default - NO DEBUGGING ENABLED, TRACE OFF) * ie to turn debugging on/off. * The routine uses the first parameter to toggle the particular * debug level. For example, if the first argument is 1, then * debugging level 1 will be turned on if it is off, and off if it * is on. If the value is negative, then one of three things can * happen. If the param is -1, debugging will be turned off. If * it is -2, debugging will be turned on globally, and if it is * any other negative value, then the mask will be complemented, * ie, all levels that are on will be turned off, and all that are * off will be turned on. * * Problems: None that I know of. * * Programmed by: John G. Hardie * UUCP: jgh2@unix.cis.pittsburgh.edu@pitt * **************************************************************************/ #include "stdio.h" #include "string.h" #include "math.h" #include "ctype.h" int (*exitfunc)(); /* pointer to exit function */ static int trace = 0; /* trace flag */ static unsigned int globalmask = 0; /* debug mask flags */ static reset_defaults = 0; /* detects the first call and */ /* allows exitfunc to be init'ld */ void debug(lev,str,int1,int2,dbl1,dbl2) int lev; char *str; int *int1,*int2; double *dbl1,*dbl2; { #ifndef NODEBUGGER void go_away(); char resp; if (!reset_defaults) { exitfunc = go_away; reset_defaults++; } if (globalmask & (1<<lev)) { printf("\n Debugger entered at level %d with:\n",lev); if (str) printf(" str: %s\n",str); if (int1) printf(" int 1= %d",*int1); if (int2) printf(" int 2= %d",*int2); putchar('\n'); if (dbl1) printf(" dbl 1= %g",*dbl1); if (dbl2) printf(" dbl 2= %g",*dbl2); putchar('\n'); if (trace) { printf("\nTrace: continue program execution? (y or n) "); while (!isalpha((resp = getchar()))) ; if (resp == 'n') (*exitfunc)(); } } #endif } void debug_level(mask,trflag,func) int mask; int trflag; int (*func)(); { #ifndef NODEBUGGER void go_away(); if (mask >= 0) globalmask |= (1<<mask); else if (mask == -1) globalmask = 0; else if (mask = -2 ) globalmask = 0xffffffff; else globalmask = ~globalmask; trace = trflag; if (func == NULL) exitfunc = go_away; else exitfunc = func; #endif } void go_away() { #ifndef NODEBUGGER puts("DEBUGGER: KILLING PROGRAM - EXITING THROUGH DEFAULT HANDLER"); exit(1999); #endif } SHAR_EOF if test 5114 -ne "`wc -c debug.c`" then echo shar: error transmitting debug.c '(should have been 5114 characters)' fi # End of shell archive exit 0