Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sun-barr!olivea!uunet!sparky!kent From: dvadura@watdragon.waterloo.edu (Dennis Vadura) Newsgroups: comp.sources.misc Subject: v19i025: dmake - dmake version 3.7, Part04/37 Message-ID: <1991May9.192646.23512@sparky.IMD.Sterling.COM> Date: 9 May 91 19:26:46 GMT Sender: kent@sparky.IMD.Sterling.COM (Kent Landfield) Organization: Sterling Software, IMD Lines: 1301 Approved: kent@sparky.imd.sterling.com X-Md4-Signature: 63e3c986a2f10d698d7a76a6cdd90127 Submitted-by: Dennis Vadura Posting-number: Volume 19, Issue 25 Archive-name: dmake/part04 Supersedes: dmake-3.6: Volume 15, Issue 52-77 ---- Cut Here and feed the following to sh ---- #!/bin/sh # this is dmake.shar.04 (part 4 of a multipart archive) # do not concatenate these parts, unpack them in order with /bin/sh # file dmake/dbug/dbug/dbug.p continued # if test ! -r _shar_seq_.tmp; then echo 'Please unpack part 1 first!' exit 1 fi (read Scheck if test "$Scheck" != 4; then echo Please unpack part "$Scheck" next! exit 1 else exit 0 fi ) < _shar_seq_.tmp || exit 1 if test -f _shar_wnt_.tmp; then sed 's/^X//' << 'SHAR_EOF' >> 'dmake/dbug/dbug/dbug.p' && X X X X X X Function level tracing is enabled by passing the X debugger the 't' flag in the debug control string. Figure 7 X is the output resulting from the command "factorial - X #t:o 3 2". X X X X X X X X X X X X X X X X X X X X X X - 9 - X X X X X X X X DBUG User Manual October 29, 1986 X X X X X X | >factorial X | | >factorial X | | factorial X | | >factorial X | | | >factorial X | | | ' for the entry point and '<' for the exit point, X connected by vertical bars to allow matching points to be X easily found when separated by large distances. X X X This trace output indicates that there was an initial X call to factorial from main (to compute 2!), followed by a X single recursive call to factorial to compute 1!. The main X program then output the result for 2! and called the X factorial function again with the second argument, 3. X Factorial called itself recursively to compute 2! and 1!, X then returned control to main, which output the value for 3! X and exited. X X X Note that there is no matching entry point "main>" for X the return point "factorial X | | find: find 3 factorial X | | >factorial X | | | find: find 2 factorial X | | | >factorial X | | | | find: find 1 factorial X | | | | result: result is 1 X | | | %s", stp, X stp -> name)); X X DBUG_SETJMP Used in place of the setjmp() function X to first save the current debugger state X and then execute the standard setjmp X call. This allows to the debugger to X restore it's state when the DBUG_LONGJMP X macro is used to invoke the standard X longjmp() call. Currently all instances X of DBUG_SETJMP must occur within the X same function and at the same function X nesting level. X X EX: DBUG_SETJMP (env); X X DBUG_LONGJMP Used in place of the longjmp() function X to first restore the previous debugger X state at the time of the last X DBUG_SETJMP and then execute the X standard longjmp() call. Note that X currently all DBUG_LONGJMP macros X restore the state at the time of the X last DBUG_SETJMP. It would be possible X to maintain separate DBUG_SETJMP and X DBUG_LONGJMP pairs by having the X debugger runtime support module use the X first argument to differentiate the X pairs. X X EX: DBUG_LONGJMP (env,val); X X X X X X X X X X X - 17 - X X X X X X X X DBUG User Manual October 29, 1986 X X X X DDDDEEEEBBBBUUUUGGGG CCCCOOOONNNNTTTTRRRROOOOLLLL SSSSTTTTRRRRIIIINNNNGGGG X X X The debug control string is used to set the state of X the debugger via the DDDDBBBBUUUUGGGG____PPPPUUUUSSSSHHHH macro. This section X summarizes the currently available debugger options and the X flag characters which enable or disable them. Argument X lists enclosed in '[' and ']' are optional. X X X d[,keywords] Enable output from macros with X specified keywords. A null list of X keywords implies that all keywords are X selected. X X D[,time] Delay for specified time after each X output line, to let output drain. X Time is given in tenths of a second X (value of 10 is one second). Default X is zero. X X f[,functions] Limit debugger actions to the X specified list of functions. A null X list of functions implies that all X functions are selected. X X F Mark each debugger output line with X the name of the source file containing X the macro causing the output. X X L Mark each debugger output line with X the source file line number of the X macro causing the output. X X n Mark each debugger output line with X the current function nesting depth. X X N Sequentially number each debugger X output line starting at 1. This is X useful for reference purposes when X debugger output is interspersed with X program output. X X o[,file] Redirect the debugger output stream to X the specified file. The default X output stream is stderr. A null X argument list causes output to be X redirected to stdout. X X p[,processes] Limit debugger actions to the X specified processes. A null list X X X X - 18 - X X X X X X X X DBUG User Manual October 29, 1986 X X X X implies all processes. This is useful X for processes which run child X processes. Note that each debugger X output line can be marked with the X name of the current process via the X 'P' flag. The process name must match X the argument passed to the X DDDDBBBBUUUUGGGG____PPPPRRRROOOOCCCCEEEESSSSSSSS macro. X X P Mark each debugger output line with X the name of the current process. Most X useful when used with a process which X runs child processes that are also X being debugged. Note that the parent X process must arrange for the debugger X control string to be passed to the X child processes. X X r Used in conjunction with the DDDDBBBBUUUUGGGG____PPPPUUUUSSSSHHHH X macro to reset the current indentation X level back to zero. Most useful with X DDDDBBBBUUUUGGGG____PPPPUUUUSSSSHHHH macros used to temporarily X alter the debugger state. X X t[,N] Enable function control flow tracing. X The maximum nesting depth is specified X by N, and defaults to 200. X X X X X X X X X X X X X X X X X X X X X X X X X X X X - 19 - X X X X X X X X DBUG User Manual October 29, 1986 X X X X HHHHIIIINNNNTTTTSSSS AAAANNNNDDDD MMMMIIIISSSSCCCCEEEELLLLLLLLAAAANNNNEEEEOOOOUUUUSSSS X X X One of the most useful capabilities of the _d_b_u_g package X is to compare the executions of a given program in two X different environments. This is typically done by executing X the program in the environment where it behaves properly and X saving the debugger output in a reference file. The program X is then run with identical inputs in the environment where X it misbehaves and the output is again captured in a X reference file. The two reference files can then be X differentially compared to determine exactly where execution X of the two processes diverges. X X X A related usage is regression testing where the X execution of a current version is compared against X executions of previous versions. This is most useful when X there are only minor changes. X X X It is not difficult to modify an existing compiler to X implement some of the functionality of the _d_b_u_g package X automatically, without source code changes to the program X being debugged. In fact, such changes were implemented in a X version of the Portable C Compiler by the author in less X than a day. However, it is strongly encouraged that all X newly developed code continue to use the debugger macros for X the portability reasons noted earlier. The modified X compiler should be used only for testing existing programs. X X X X X X X X X X X X X X X X X X X X X X X X X - 20 - X X X X X X X X DBUG User Manual October 29, 1986 X X X X CCCCAAAAVVVVEEEEAAAATTTTSSSS X X X The _d_b_u_g package works best with programs which have X "line oriented" output, such as text processors, general X purpose utilities, etc. It can be interfaced with screen X oriented programs such as visual editors by redefining the X appropriate macros to call special functions for displaying X the debugger results. Of course, this caveat is not X applicable if the debugger output is simply dumped into a X file for post-execution examination. X X X Programs which use memory allocation functions other X than mmmmaaaalllllllloooocccc will usually have problems using the standard X _d_b_u_g package. The most common problem is multiply allocated X memory. X X SHAR_EOF chmod 0650 dmake/dbug/dbug/dbug.p || echo 'restore of dmake/dbug/dbug/dbug.p failed' Wc_c="`wc -c < 'dmake/dbug/dbug/dbug.p'`" test 42891 -eq "$Wc_c" || echo 'dmake/dbug/dbug/dbug.p: original size 42891, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= dmake/dbug/getwd.c ============== if test -f 'dmake/dbug/getwd.c' -a X"$1" != X"-c"; then echo 'x - skipping dmake/dbug/getwd.c (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp sed 's/^X//' << 'SHAR_EOF' > 'dmake/dbug/getwd.c' && char * getwd(pathname) char *pathname; { X return("delete this code if your getwd.c works correctly"); } SHAR_EOF chmod 0640 dmake/dbug/getwd.c || echo 'restore of dmake/dbug/getwd.c failed' Wc_c="`wc -c < 'dmake/dbug/getwd.c'`" test 106 -eq "$Wc_c" || echo 'dmake/dbug/getwd.c: original size 106, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= dmake/dbug/malloc/Makefile ============== if test ! -d 'dmake/dbug/malloc'; then mkdir 'dmake/dbug/malloc' fi if test -f 'dmake/dbug/malloc/Makefile' -a X"$1" != X"-c"; then echo 'x - skipping dmake/dbug/malloc/Makefile (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp sed 's/^X//' << 'SHAR_EOF' > 'dmake/dbug/malloc/Makefile' && # # (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil). # You may copy, distribute, and use this software as long as this # copyright statement is not removed. # # # This is the Makefile for the malloc debugging library # # $Id: Makefile,v 1.5 90/08/29 22:34:27 cpcahil Exp $ # CC=cc # for System V systems use this CFLAGS #CFLAGS=-g -DSYS5 # else for BSD use: #CFLAGS=-g LINT=lint SHARCMD=shar -o mallocshar -l50 -x -a -n Malloclib SHELL=/bin/sh X LIB=libmalloc.a X SRCS= malloc.c \ X free.c \ X realloc.c \ X calloc.c \ X string.c \ X mlc_chk.c \ X mlc_chn.c \ X memory.c \ X tostring.c \ X m_perror.c \ X m_init.c \ X mallopt.c \ X dump.c X OBJS= malloc.o \ X free.o \ X realloc.o \ X calloc.o \ X string.o \ X mlc_chk.o \ X mlc_chn.o \ X memory.o \ X tostring.o \ X m_perror.o \ X m_init.o \ X mallopt.o \ X dump.o X TESTS=testmlc testmem X all: $(LIB) $(TESTS) X clean: X rm -f $(TESTS) pgm $(LIB) *.o *.ln X sharfile: X $(SHARCMD) Makefile README patchlevel *.[ch3] X $(LIB): $(OBJS) X ar ru $(LIB) $(OBJS) X -if test -s /bin/ranlib; then /bin/ranlib $(LIB); else exit 0; fi X -if test -s /usr/bin/ranlib; then /usr/bin/ranlib $(LIB); else exit 0; fi X testmlc: $(LIB) testmlc.o X $(CC) -o $@ testmlc.o $(LIB) X testmem: $(LIB) testmem.o X $(CC) -o $@ testmem.o $(LIB) X lint: X $(LINT) $(CFLAGS) $(SRCS) testmlc.c testmem.c X X $(OBJS): malloc.h X tostring.o malloc.o dump.o: tostring.h SHAR_EOF chmod 0640 dmake/dbug/malloc/Makefile || echo 'restore of dmake/dbug/malloc/Makefile failed' Wc_c="`wc -c < 'dmake/dbug/malloc/Makefile'`" test 1365 -eq "$Wc_c" || echo 'dmake/dbug/malloc/Makefile: original size 1365, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= dmake/dbug/malloc/_changes ============== if test -f 'dmake/dbug/malloc/_changes' -a X"$1" != X"-c"; then echo 'x - skipping dmake/dbug/malloc/_changes (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp sed 's/^X//' << 'SHAR_EOF' > 'dmake/dbug/malloc/_changes' && I made the following changes to the malloc package as found in comp.sources.unix: X X 1. created this file _changes. X 2. moved README to _readme (facilitates transfer to DOS and back to X unix) X 3. renamed testmalloc.c, malloc_chk.c, and malloc_chn.c to testmlc.c, X mlc_chk.c, and mlc_chn.c respectively. Again DOS has trouble with X long basenames in filenames. SHAR_EOF chmod 0640 dmake/dbug/malloc/_changes || echo 'restore of dmake/dbug/malloc/_changes failed' Wc_c="`wc -c < 'dmake/dbug/malloc/_changes'`" test 369 -eq "$Wc_c" || echo 'dmake/dbug/malloc/_changes: original size 369, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= dmake/dbug/malloc/_readme ============== if test -f 'dmake/dbug/malloc/_readme' -a X"$1" != X"-c"; then echo 'x - skipping dmake/dbug/malloc/_readme (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp sed 's/^X//' << 'SHAR_EOF' > 'dmake/dbug/malloc/_readme' && # (c) Copyright 1990 Conor P. Cahill. (uunet!virtech!cpcahil) # You may copy, distribute, and use this software as long as this # copyright statement is not removed. X This package is a collection of routines which are a drop-in replacement for the malloc(3), memory(3), string(3), and bstring(3) library functions. X The purpose of these programs is to aid the development and/or debugging of programs using these functions by providing a high level of consistancy checking whenever a malloc pointer is used. Due to this increased level of consistancy checking, these functions have a considerably larger overhead than the standard functions, but the extra checking should be well worth it in a development environment. X To use these functions all you need to do is compile the library and include it on your loader command line. You do not need to recompile your code, only a relink is necessary. X Features of this library: X X 1. The malloced area returned from each call to malloc is filled with X non-null bytes. This should catch any use of uninitialized malloc X area. The fill pattern for malloced area is 0x01. X X 2. When free is called numerous validity checks are made on the X pointer it is passed. In addition, the data in the malloc block X beyound the size requested on the initial malloc is checked to X verify that it is still filled with the original fill characters. X X This is usefull for catching things like: X X ptr = malloc(5); X ptr[5] = '\0'; X X /* X * You should not that this will be caught when it is X * freed not when it is done X */ X X And finally, the freed block is filled with a different fill pattern X so that you can easily determine if you are still using free'd space. X The fill pattern for free'd areas is 0x02. X X This is usefull for catching things like: X X ptr = malloc(20); X X bptr = ptr+10; X X /* do something usefule with bptr */ X X free(ptr); X X /* X * now try to do something useful with bptr, it should X * be trashed enough that it would cause real problems X * and when you went to debug the problem it would be X * filled with 0x02's and you would then know to look X * for something free'ing what bptr points to. X */ X X X 3. Whenever a bstring(3)/string(3)/memory(3) function is called, it's X parameters are checked as follows: X X If they point somewhere in the malloc arena X If the operation goes beyond requested malloc space X call malloc_warning() X X This is usefull for catching things like: X X ptr = malloc(5); X strcpy(ptr,"abcde"); X X X 4. Malloc_warning() and malloc_fatal() are used when an error condition X is detected. If the error is severe, malloc_fatal is called. X Malloc_warning is used otherwise. The decision about what is fatal X and what is a warning was made somewhat arbitrarily. X X Warning messages include: X X Calling free with a bad pointer X Calling a bstring/string/memory (3) function which will go beyond X the end of a malloc block (Note that the library function is X not modified to refuse the operation. If malloc warnings are X in the default IGNORE case, the operation will continue and X at some point cause a real problem). X X Fatal errors are: X X Detectable corruption to the malloc chain. X X X 5. The operations to perform when an error is detected are specified at X run time by the use of environment variables. X X MALLOC_WARN - specifies the warning error message handling X MALLOC_FATAL - specifies the fatal error handling X X X When one of these error conditions occur you will get an error X message and the handler will execute based upon what setting X is in the environment variables. Currently understood settings X are as follows: X X 0 - continue operations X 1 - drop core and exit X 2 - just exit X 3 - drop core, but continue executing. Core files will X be placed into core.[PID].[counter] i.e: core.00123.001 X 128 - dump malloc chain and continue X 129 - dump malloc chain, dump core, and exit X 130 - dump malloc chain, exit X 131 - dump malloc chain, dump core, continue processing X X X There is an additional environment variable MALLOC_ERRFILE which X is used to indicate the name of the file for error message output. X X For example, to set up the session to generate a core file for X every malloc warning, to drop core and exit on a malloc fatal, and X to log all messages to the file "malloc_log" do the following: X X MALLOC_WARN=131 X MALLOC_FATAL=1 X MALLOC_ERRFILE=malloc_log X X export MALLOC_WARN MALLOC_FATAL MALLOC_ERRFILE X X 6. The function malloc_dump() is available to dump the malloc chain whenever X you might want. It's only argument is a file descriptor to use to write X the data. Review the code if you need to know what data is printed. SHAR_EOF chmod 0640 dmake/dbug/malloc/_readme || echo 'restore of dmake/dbug/malloc/_readme failed' Wc_c="`wc -c < 'dmake/dbug/malloc/_readme'`" test 4758 -eq "$Wc_c" || echo 'dmake/dbug/malloc/_readme: original size 4758, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= dmake/dbug/malloc/calloc.c ============== if test -f 'dmake/dbug/malloc/calloc.c' -a X"$1" != X"-c"; then echo 'x - skipping dmake/dbug/malloc/calloc.c (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp sed 's/^X//' << 'SHAR_EOF' > 'dmake/dbug/malloc/calloc.c' && /* X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil). X * You may copy, distribute, and use this software as long as this X * copyright statement is not removed. X */ #include X /* X * Function: calloc() X * X * Purpose: to allocate and nullify a data area X * X * Arguments: nelem - number of elements X * elsize - size of each element X * X * Returns: NULL - if malloc fails X * or pointer to allocated space X * X * Narrative: determine size of area to malloc X * malloc area. X * if malloc succeeds X * fill area with nulls X * return ptr to malloc'd region X */ #ifndef lint static char rcs_header[] = "$Id: calloc.c,v 1.6 90/05/11 00:13:07 cpcahil Exp $"; #endif X char * calloc(nelem,elsize) X unsigned int nelem; X unsigned int elsize; { X char * malloc(); X char * memset(); X char * ptr; X unsigned int size; X X size = elsize * nelem; X X if( (ptr = malloc(size)) != NULL) X { X (void) memset(ptr,'\0',(int)size); X } X X return(ptr); } X X /* X * $Log: calloc.c,v $ X * Revision 1.6 90/05/11 00:13:07 cpcahil X * added copyright statment X * X * Revision 1.5 90/02/24 20:41:57 cpcahil X * lint changes. X * X * Revision 1.4 90/02/24 17:25:47 cpcahil X * changed $header to $id so full path isn't included. X * X * Revision 1.3 90/02/24 13:32:24 cpcahil X * added function header. moved log to end of file. X * X * Revision 1.2 90/02/22 23:08:26 cpcahil X * fixed rcs_header line X * X * Revision 1.1 90/02/22 23:07:38 cpcahil X * Initial revision X * X */ SHAR_EOF chmod 0640 dmake/dbug/malloc/calloc.c || echo 'restore of dmake/dbug/malloc/calloc.c failed' Wc_c="`wc -c < 'dmake/dbug/malloc/calloc.c'`" test 1481 -eq "$Wc_c" || echo 'dmake/dbug/malloc/calloc.c: original size 1481, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= dmake/dbug/malloc/debug.h ============== if test -f 'dmake/dbug/malloc/debug.h' -a X"$1" != X"-c"; then echo 'x - skipping dmake/dbug/malloc/debug.h (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp sed 's/^X//' << 'SHAR_EOF' > 'dmake/dbug/malloc/debug.h' && /* X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil). X * You may copy, distribute, and use this software as long as this X * copyright statement is not removed. X */ /************************************************************************/ /* */ /* this include sets up some macro functions which can be used while */ /* debugging the program, and then left in the code, but turned of by */ /* just not defining "DEBUG". This way your production version of */ /* the program will not be filled with bunches of debugging junk */ /* */ /************************************************************************/ /* X * $Id: debug.h,v 1.2 90/05/11 00:13:08 cpcahil Exp $ X */ X #ifdef DEBUG X #if DEBUG == 1 /* if default level */ #undef DEBUG #define DEBUG 100 /* use level 100 */ #endif X #include X #define DEBUG0(val,str)\ X {\ X if( DEBUG > val ) \ X fprintf(stderr,"%s(%d): %s\n",\ X __FILE__,__LINE__,str);\ X } #define DEBUG1(val,str,a1)\ X {\ X char _debugbuf[100];\ X if( DEBUG > val )\ X {\ X sprintf(_debugbuf,str,a1);\ X fprintf(stderr,"%s(%d): %s\n",\ X __FILE__,__LINE__,_debugbuf);\ X }\ X } X #define DEBUG2(val,str,a1,a2)\ X {\ X char _debugbuf[100];\ X if( DEBUG > val )\ X {\ X sprintf(_debugbuf,str,a1,a2);\ X fprintf(stderr,"%s(%d): %s\n",\ X __FILE__,__LINE__,_debugbuf);\ X }\ X } X #define DEBUG3(val,str,a1,a2,a3)\ X {\ X char _debugbuf[100];\ X if( DEBUG > val )\ X {\ X sprintf(_debugbuf,str,a1,a2,a3);\ X fprintf(stderr,"%s(%d): %s\n",\ X __FILE__,__LINE__,_debugbuf);\ X }\ X } X #define DEBUG4(val,str,a1,a2,a3,a4)\ X {\ X char _debugbuf[100];\ X if( DEBUG > val )\ X {\ X sprintf(_debugbuf,str,a1,a2,a3,a4);\ X fprintf(stderr,"%s(%d): %s\n",\ X __FILE__,__LINE__,_debugbuf);\ X }\ X } X #define DEBUG5(val,str,a1,a2,a3,a4,a5)\ X {\ X char _debugbuf[100];\ X if( DEBUG > val )\ X {\ X sprintf(_debugbuf,str,a1,a2,a3,a4,a5);\ X fprintf(stderr,"%s(%d): %s\n",\ X __FILE__,__LINE__,_debugbuf);\ X }\ X } X #else SHAR_EOF true || echo 'restore of dmake/dbug/malloc/debug.h failed' fi echo 'End of part 4, continue with part 5' echo 5 > _shar_seq_.tmp exit 0 exit 0 # Just in case... -- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM Sterling Software, IMD UUCP: uunet!sparky!kent Phone: (402) 291-8300 FAX: (402) 291-4362 Please send comp.sources.misc-related mail to kent@uunet.uu.net.