home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!husc6!necntc!ncoast!allbery
- From: fnf@mcdsun.UUCP (Fred Fish)
- Newsgroups: comp.sources.misc
- Subject: Dbug package (2 of 3)
- Message-ID: <4561@ncoast.UUCP>
- Date: 24 Sep 87 02:36:26 GMT
- Sender: allbery@ncoast.UUCP
- Lines: 2385
- Approved: allbery@ncoast.UUCP
- X-Archive: comp.sources.misc/8709/dbug/2
-
- >From noao!cfa!harvard!ll-xn!scubed!MAILER-DAEMON Tue Sep 22 23:30:34 1987
- Return-Path: <noao!cfa!harvard!ll-xn!scubed!MAILER-DAEMON>
- Received: by noname.uucp (3.2/SMI-3.2)
- id AA00968; Tue, 22 Sep 87 23:30:28 MST
- Received: by noao.arizona.edu (5.51/SAG.7)
- id AA09968; Tue, 22 Sep 87 21:21:45 MST
- Received: from husc6.harvard.edu (husc6.ARPA) by cfa.HARVARD.EDU; Wed, 23 Sep 87 00:05:15 edt
- Received: by husc6.harvard.edu; Tue, 22 Sep 87 23:58:35 EDT
- Received: by harvard.harvard.edu; Wed, 23 Sep 87 00:06:22 EDT
- Received: by XN.LL.MIT.EDU; Tue, 22 Sep 87 23:57:03 EDT
- Posted-Date: Wed, 9 Sep 87 10:36:04 MST
- Received: by SCUBED.ARPA (1.2/5.20b)
- id AA07221; Tue, 22 Sep 87 20:41:20 pdt
- Date: Wed, 9 Sep 87 10:36:04 MST
- From: noao!cfa!harvard!ll-xn!scubed!MAILER-DAEMON (Mail Delivery Subsystem)
- Subject: Returned mail: Host unknown
- Message-Id: <8709230341.AA07221@SCUBED.ARPA>
- To: ll-xn!ames!NOAO.ARIZONA.EDU!mcdsun!fnf@scubed
- Status: R
-
- ----- Transcript of session follows -----
- 550 noao.arizona.edu.tcp... 550 Host unknown
- 550 seismo!adelie!necntc!ncoast!allbery@NOAO.ARIZONA.EDU... Host unknown
-
- ----- Unsent message follows -----
- Received: by SCUBED.ARPA (1.2/5.20b)
- id AA07217; Tue, 22 Sep 87 20:41:20 pdt
- Received: by SCUBED.ARPA (1.2/5.20b)
- id AA00771; Wed, 9 Sep 87 11:15:45 pdt
- Received: by XN.LL.MIT.EDU; Wed, 9 Sep 87 13:55:20 EDT
- Posted-Date: Wed, 9 Sep 87 10:36:04 MST
- Received: Wed, 9 Sep 87 11:00:10 PDT from HAO.UCAR.EDU by ames.arpa (5.58/1.2)
- Received: by hao.UCAR.EDU (5.54/1.00.UUCP-MOD.8-11-85)
- id AA15483; Wed, 9 Sep 87 11:49:57 MDT
- Received: by noao.arizona.edu (5.51/SAG.7)
- id AA04829; Wed, 9 Sep 87 10:52:25 MST
- Received: by noname.uucp (3.2/SMI-3.2)
- id AA14024; Wed, 9 Sep 87 10:36:04 MST
- Date: Wed, 9 Sep 87 10:36:04 MST
- From: ll-xn!ames!NOAO.ARIZONA.EDU!mcdsun!fnf@scubed.scubed.arpa (Fred Fish)
- Message-Id: <8709091736.AA14024@noname.uucp>
- To: adelie!necntc!ncoast!allbery@NOAO.ARIZONA.EDU
- Subject: My macro based C debugging package (2 of 3)
-
-
- #--------CUT---------CUT---------CUT---------CUT--------#
- #########################################################
- # #
- # This is a shell archive file. To extract files: #
- # #
- # 1) Make a directory for the files. #
- # 2) Write a file, such as "file.shar", containing #
- # this archive file into the directory. #
- # 3) Type "sh file.shar". Do not use csh. #
- # #
- #########################################################
- #
- #
- echo Extracting Makefile:
- sed 's/^Z//' >Makefile <<\STUNKYFLUFF
- Z#
- Z# FILE
- Z#
- Z# Makefile Makefile for dbug package
- Z#
- Z# SCCS ID
- Z#
- Z# @(#)Makefile 1.11 9/9/87
- Z#
- Z# DESCRIPTION
- Z#
- Z# Makefile for the dbug package (under UNIX system V or 4.2BSD).
- Z#
- Z# Interesting things to make are:
- Z#
- Z# lib => Makes the runtime support library in the
- Z# current directory.
- Z#
- Z# lintlib => Makes the lint library in the current directory.
- Z#
- Z# install => Install pieces from current directory to
- Z# where they belong.
- Z#
- Z# doc => Makes the documentation in the current
- Z# directory.
- Z#
- Z# clean => Remove objects, temporary files, etc from
- Z# current directory.
- Z#
- Z# superclean => Remove everything except sccs source files.
- Z# Uses interactive remove for verification.
- Z
- ZAR = ar
- ZRM = rm
- ZCFLAGS = -O
- ZGFLAGS = -s
- ZINSTALL = ./install.sh
- ZCHMOD = chmod
- ZMAKE = make
- ZINC = /usr/include/local
- ZLIB = /usr/lib
- ZRANLIB = ./ranlib.sh
- ZMODE = 664
- Z
- Z# The following is provided for example only, it is set by "doinstall.sh".
- ZLLIB = /usr/lib
- Z
- Z.SUFFIXES: .r .r~ .c .c~
- Z
- Z.c~.c:
- Z $(GET) $(GFLAGS) -p $< >$*.c
- Z
- Z.r~.r:
- Z $(GET) $(GFLAGS) -p $< >$*.r
- Z
- Z.c~.r:
- Z $(GET) $(GFLAGS) -p $< >$*.c
- Z sed "s/\\\/\\\e/" <$*.c >$*.r
- Z $(RM) -f $*.c
- Z
- Z.c.r:
- Z sed "s/\\\/\\\e/" <$< >$*.r
- Z
- ZEXAMPLES = example1.r example2.r example3.r
- ZOUTPUTS = output1.r output2.r output3.r output4.r output5.r
- Z
- ZNROFF_INC = main.r factorial.r $(OUTPUTS) $(EXAMPLES)
- Z
- Z
- Z#
- Z# The default thing to do is remake the local runtime support
- Z# library, local lint library, and local documentation as
- Z# necessary.
- Z#
- Z
- Zall : scripts lib lintlib analyze doc
- Z
- Zlib : libdbug.a
- Z
- Zlintlib : llib-ldbug.ln
- Z
- Zdoc : factorial user.t
- Z
- Z#
- Z# Make the local runtime support library "libdbug.a" from
- Z# sources.
- Z#
- Z
- Zlibdbug.a : dbug.o
- Z rm -f $@
- Z $(AR) cr $@ $?
- Z $(RANLIB) $@
- Z
- Z#
- Z# Clean up the local directory.
- Z#
- Z
- Zclean :
- Z $(RM) -f *.o *.ln *.a *.BAK nohup.out factorial $(NROFF_INC)
- Z
- Zsuperclean :
- Z $(RM) -i ?[!.]*
- Z
- Z#
- Z# Install the new header and library files. Since things go in
- Z# different places depending upon the system (lint libraries
- Z# go in /usr/lib under SV and /usr/lib/lint under BSD for example),
- Z# the shell script "doinstall.sh" figures out the environment and
- Z# does a recursive make with the appropriate pathnames set.
- Z#
- Z
- Zinstall : scripts
- Z ./doinstall.sh $(MAKE) sysinstall
- Z
- Zsysinstall: $(INC) $(INC)/dbug.h $(LIB)/libdbug.a \
- Z $(LLIB)/llib-ldbug.ln $(LLIB)/llib-ldbug
- Z
- Z$(INC) :
- Z -if test -d $@ ;then true ;else mkdir $@ ;fi
- Z
- Z$(INC)/dbug.h : dbug.h
- Z $(INSTALL) $? $@
- Z $(CHMOD) $(MODE) $@
- Z
- Z$(LIB)/libdbug.a : libdbug.a
- Z $(INSTALL) $? $@
- Z $(CHMOD) $(MODE) $@
- Z
- Z$(LLIB)/llib-ldbug.ln : llib-ldbug.ln
- Z $(INSTALL) $? $@
- Z $(CHMOD) $(MODE) $@
- Z
- Z$(LLIB)/llib-ldbug : llib-ldbug
- Z $(INSTALL) $? $@
- Z $(CHMOD) $(MODE) $@
- Z
- Z#
- Z# Make the local lint library.
- Z#
- Z
- Zllib-ldbug.ln : llib-ldbug
- Z ./mklintlib.sh $? $@
- Z
- Z#
- Z# Make the test/example program "factorial".
- Z#
- Z# Note that the objects depend on the LOCAL dbug.h file and
- Z# the compilations are set up to find dbug.h in the current
- Z# directory even though the sources have "#include <dbug.h>".
- Z# This allows the examples to look like the code a user would
- Z# write but still be used as test cases for new versions
- Z# of dbug.
- Z
- Zfactorial : main.o factorial.o libdbug.a
- Z $(CC) -o $@ main.o factorial.o libdbug.a
- Z
- Zmain.o : main.c dbug.h
- Z $(CC) $(CFLAGS) -c -I. main.c
- Z
- Zfactorial.o : factorial.c dbug.h
- Z $(CC) $(CFLAGS) -c -I. factorial.c
- Z
- Z
- Z#
- Z# Make the analyze program for runtime profiling support.
- Z#
- Z
- Zanalyze : analyze.o libdbug.a
- Z $(CC) -o $@ analyze.o libdbug.a
- Z
- Zanalyze.o : analyze.c useful.h dbug.h
- Z $(CC) $(CFLAGS) -c -I. analyze.c
- Z
- Z#
- Z# Rebuild the documentation
- Z#
- Z
- Zuser.t : user.r $(NROFF_INC)
- Z nroff -cm user.r >$@
- Z
- Z#
- Z# Run the factorial program to produce the sample outputs.
- Z#
- Z
- Zoutput1.r: factorial
- Z factorial 1 2 3 4 5 >$@
- Z
- Zoutput2.r: factorial
- Z factorial -#t:o 2 3 >$@
- Z
- Zoutput3.r: factorial
- Z factorial -#d:t:o 3 >$@
- Z
- Zoutput4.r: factorial
- Z factorial -#d,result:o 4 >$@
- Z
- Zoutput5.r: factorial
- Z factorial -#d:f,factorial:F:L:o 3 >$@
- Z
- Z#
- Z# All files included by user.r depend on user.r, thus
- Z# forcing them to be remade if user.r changes.
- Z#
- Z
- Z$(NROFF_INC) : user.r
- Z
- Z#
- Z# Make scripts executable (safeguard against forgetting to do it
- Z# when extracting scripts from a source code control system.
- Z#
- Z
- Zscripts:
- Z chmod a+x *.sh
- Z
- STUNKYFLUFF
- set `sum Makefile`
- if test 43870 != $1
- then
- echo Makefile: Checksum error. Is: $1, should be: 43870.
- fi
- #
- #
- echo Extracting README.prof:
- sed 's/^Z//' >README.prof <<\STUNKYFLUFF
- ZHi,
- Z
- ZI'm sending you the modifications I made to your Dbug routines to
- Zallow profiling in a (relatively) machine independent fashion.
- ZI use your Dbug routines fairly extensively. Unfortunately, it's
- Za royal pain to have to keep profiled versions of various libraries
- Zaround. The modifications allow profiling without the need for this.
- Z
- ZHow it works.
- Z------------
- Z
- ZBasically, I just added code in the dbug routines to write out a file
- Zcalled dbugmon.out (by default). This is an ascii file containing lines
- Zof the form:
- Z
- Z<function-name> E <time-entered>
- Z<function-name> X <time-exited>
- Z
- ZA second program (analyze) reads this file, and produces a report on
- Zstandard output.
- Z
- ZProfiling is enabled through the `g' flag. It can take a list of
- Zprocedure names for which profiling is enabled. By default, it
- Zprofiles all procedures.
- Z
- ZThe code in ``dbug.c'' opens the profile file for appending. This
- Zis in order that one can run a program several times, and get the
- Zsum total of all the times, etc.
- Z
- ZThe only system dependent part that I'm aware of is the routine
- ZClock() at the end of dbug.c. This returns the elapsed user time
- Zin milliseconds. The version which I have is for 4.3 BSD. As I
- Zdon't have access to other systems, I'm not certain how this would
- Zchange.
- Z
- ZAn example of the report generated follows:
- Z
- Z Profile of Execution
- Z Execution times are in milliseconds
- Z
- Z Calls Time
- Z ----- ----
- Z Times Percentage Time Spent Percentage
- ZFunction Called of total in Function of total Importance
- Z======== ====== ========== =========== ========== ==========
- Zfactorial 5 83.33 30 100.00 8333
- Zmain 1 16.67 0 0.00 0
- Z======== ====== ========== =========== ==========
- ZTotals 6 100.00 30 100.00
- Z
- Z
- ZAs you can see, it's quite self-evident. The ``Importance'' column is a
- Zmetric obtained by multiplying the percentage of the calls and the percentage
- Zof the time. Functions with higher 'importance' benefit the most from
- Zbeing sped up.
- Z
- ZI'm really not certain how to add support for setjmp/longjmp, or for
- Zchild processes, so I've ignored that for the time being. In most of
- Zthe code that I write, it isn't necessary. If you have any good ideas,
- Zfeel free to add them.
- Z
- ZThis has been very useful to me. If you can use it as part of your
- Zdbug distribution, please feel free to do so.
- Z
- ZRegards,
- Z
- Z Binayak Banerjee
- Z {allegra | astrovax | bpa | burdvax}!sjuvax!bbanerje
- Z bbanerje%sjuvax.sju.edu@relay.cs.net
- Z July 9, 1987
- STUNKYFLUFF
- set `sum README.prof`
- if test 29706 != $1
- then
- echo README.prof: Checksum error. Is: $1, should be: 29706.
- fi
- #
- #
- echo Extracting analyze.c:
- sed 's/^Z//' >analyze.c <<\STUNKYFLUFF
- Z/*
- Z * Analyze the profile file (cmon.out) written out by the dbug
- Z * routines with profiling enabled.
- Z *
- Z * Copyright June 1987, Binayak Banerjee
- Z * All rights reserved.
- Z *
- Z * This program may be freely distributed under the same terms and
- Z * conditions as Fred Fish's Dbug package.
- Z *
- Z * Compile with -- cc -O -s -o %s analyze.c
- Z *
- Z * Analyze will read an trace file created by the dbug package
- Z * (when run with traceing enabled). It will then produce a
- Z * summary on standard output listing the name of each traced
- Z * function, the number of times it was called, the percentage
- Z * of total calls, the time spent executing the function, the
- Z * proportion of the total time and the 'importance'. The last
- Z * is a metric which is obtained by multiplying the proportions
- Z * of calls and the proportions of time for each function. The
- Z * greater the importance, the more likely it is that a speedup
- Z * could be obtained by reducing the time taken by that function.
- Z *
- Z * Note that the timing values that you obtain are only rough
- Z * measures. The overhead of the dbug package is included
- Z * within. However, there is no need to link in special profiled
- Z * libraries and the like.
- Z *
- Z * CHANGES:
- Z *
- Z * 24-Jul-87: fnf
- Z * Because I tend to use functions names like
- Z * "ExternalFunctionDoingSomething", I've rearranged the
- Z * printout to put the function name last in each line, so
- Z * long names don't screw up the formatting unless they are
- Z * *very* long and wrap around the screen width...
- Z *
- Z * 24-Jul-87: fnf
- Z * Modified to put out table very similar to Unix profiler
- Z * by default, but also puts out original verbose table
- Z * if invoked with -v flag.
- Z */
- Z
- Z# include <stdio.h>
- Z# include "useful.h"
- Z
- Zchar *my_name;
- Zint verbose;
- Z
- Z/*
- Z * Structure of the stack.
- Z */
- Z
- Z# define PRO_FILE "dbugmon.out" /* Default output file name */
- Z# define STACKSIZ 100 /* Maximum function nesting */
- Z# define MAXPROCS 1000 /* Maximum number of function calls */
- Z
- Zstruct stack_t {
- Z unsigned int pos; /* which function? */
- Z unsigned long time; /* Time that this was entered */
- Z unsigned long children; /* Time spent in called funcs */
- Z}
- Z fn_stack[STACKSIZ+1];
- Z
- Zunsigned int stacktop = 0; /* Lowest stack position is a dummy */
- Z
- Z/*
- Z * top() returns a pointer to the top item on the stack.
- Z * (was a function, now a macro)
- Z */
- Z
- Z# define top() &fn_stack[stacktop]
- Z
- Z/*
- Z * Push - Push the given record on the stack.
- Z */
- Z
- Zvoid
- Zpush(name_pos,time_entered)
- Zregister unsigned int name_pos;
- Zregister unsigned long time_entered;
- Z{
- Z register struct stack_t *t;
- Z
- Z DBUG_ENTER("push");
- Z if (++stacktop > STACKSIZ)
- Z {
- Z fprintf(DBUG_FILE,"%s: stack overflow (%s:%d)\n",
- Z my_name,__FILE__,__LINE__);
- Z exit(EX_SOFTWARE);
- Z }
- Z
- Z DBUG_PRINT("push",("%d %ld",name_pos,time_entered));
- Z t = &fn_stack[stacktop];
- Z t->pos = name_pos;
- Z t->time = time_entered;
- Z t->children = 0;
- Z
- Z DBUG_VOID_RETURN;
- Z}
- Z
- Z/*
- Z * Pop - pop the top item off the stack, assigning the field values
- Z * to the arguments. Returns 0 on stack underflow, or on popping first
- Z * item off stack.
- Z */
- Z
- Zunsigned int
- Zpop(name_pos, time_entered, child_time)
- Zregister unsigned int *name_pos;
- Zregister unsigned long *time_entered;
- Zregister unsigned long *child_time;
- Z{
- Z register struct stack_t *temp;
- Z
- Z DBUG_ENTER("pop");
- Z
- Z if (stacktop < 1)
- Z DBUG_RETURN(0);
- Z
- Z temp = &fn_stack[stacktop];
- Z *name_pos = temp->pos;
- Z *time_entered = temp->time;
- Z *child_time = temp->children;
- Z
- Z DBUG_PRINT("pop",("%d %d %d",*name_pos,*time_entered,*child_time));
- Z DBUG_RETURN(stacktop--);
- Z}
- Z
- Z/*
- Z * We keep the function info in another array (serves as a simple
- Z * symbol table)
- Z */
- Z
- Zstruct module_t {
- Z char *name;
- Z unsigned long m_time;
- Z unsigned long m_calls;
- Z}
- Z modules[MAXPROCS];
- Z
- Z/*
- Z * We keep a binary search tree in order to look up function names
- Z * quickly (and sort them at the end.
- Z */
- Z
- Zstruct {
- Z unsigned int lchild; /* Index of left subtree */
- Z unsigned int rchild; /* Index of right subtree */
- Z unsigned int pos; /* Index of module_name entry */
- Z}
- Z s_table[MAXPROCS];
- Z
- Zunsigned int n_items = 0; /* No. of items in the array so far */
- Z
- Z/*
- Z * Need a function to allocate space for a string and squirrel it away.
- Z */
- Z
- Zchar *
- Zstrsave(s)
- Zchar *s;
- Z{
- Z register char *retval;
- Z register unsigned int len;
- Z extern char *malloc ();
- Z
- Z DBUG_ENTER("strsave");
- Z DBUG_PRINT("strsave",("%s",s));
- Z if (s == Nil(char) || (len = strlen(s)) == 0)
- Z DBUG_RETURN(Nil(char));
- Z
- Z MALLOC(retval, ++len, char);
- Z strcpy(retval,s);
- Z DBUG_RETURN(retval);
- Z}
- Z
- Z/*
- Z * add() - adds m_name to the table (if not already there), and returns
- Z * the index of its location in the table. Checks s_table (which is a
- Z * binary search tree) to see whether or not it should be added.
- Z */
- Z
- Zunsigned int
- Zadd(m_name)
- Zchar *m_name;
- Z{
- Z register unsigned int ind = 0;
- Z register int cmp;
- Z
- Z DBUG_ENTER("add");
- Z if (n_items == 0) /* First item to be added */
- Z {
- Z s_table[0].pos = ind;
- Z s_table[0].lchild = s_table[0].rchild = MAXPROCS;
- Zaddit:
- Z modules[n_items].name = strsave(m_name);
- Z modules[n_items].m_time = modules[n_items].m_calls = 0;
- Z DBUG_RETURN(n_items++);
- Z }
- Z while (cmp = strcmp(m_name,modules[ind].name)) {
- Z if (cmp < 0) { /* In left subtree */
- Z if (s_table[ind].lchild == MAXPROCS) {
- Z /* Add as left child */
- Z if (n_items >= MAXPROCS) {
- Z fprintf(DBUG_FILE,
- Z "%s: Too many functions being profiled\n",
- Z my_name);
- Z exit(EX_SOFTWARE);
- Z }
- Z s_table[n_items].pos =
- Z s_table[ind].lchild = n_items;
- Z s_table[n_items].lchild =
- Z s_table[n_items].rchild = MAXPROCS;
- Z# ifdef notdef
- Z modules[n_items].name = strsave(m_name);
- Z modules[n_items].m_time = modules[n_items].m_calls = 0;
- Z DBUG_RETURN(n_items++);
- Z# else
- Z goto addit;
- Z# endif
- Z
- Z }
- Z ind = s_table[ind].lchild; /* else traverse l-tree */
- Z } else {
- Z if (s_table[ind].rchild == MAXPROCS) {
- Z /* Add as right child */
- Z if (n_items >= MAXPROCS) {
- Z fprintf(DBUG_FILE,
- Z "%s: Too many functions being profiled\n",
- Z my_name);
- Z exit(EX_SOFTWARE);
- Z }
- Z s_table[n_items].pos =
- Z s_table[ind].rchild = n_items;
- Z s_table[n_items].lchild =
- Z s_table[n_items].rchild = MAXPROCS;
- Z# ifdef notdef
- Z modules[n_items].name = strsave(m_name);
- Z modules[n_items].m_time = modules[n_items].m_calls = 0;
- Z DBUG_RETURN(n_items++);
- Z# else
- Z goto addit;
- Z# endif
- Z
- Z }
- Z ind = s_table[ind].rchild; /* else traverse r-tree */
- Z }
- Z }
- Z DBUG_RETURN(ind);
- Z}
- Z
- Zunsigned long int tot_time = 0;
- Zunsigned long int tot_calls = 0;
- Z
- Z/*
- Z * process() - process the input file, filling in the modules table.
- Z */
- Z
- Zvoid
- Zprocess(inf)
- ZFILE *inf;
- Z{
- Z char buf[BUFSIZ];
- Z char fn_name[25]; /* Max length of fn_name */
- Z char fn_what[2];
- Z unsigned long fn_time;
- Z unsigned int pos;
- Z unsigned long time;
- Z unsigned int oldpos;
- Z unsigned long oldtime;
- Z unsigned long oldchild;
- Z struct stack_t *t;
- Z
- Z DBUG_ENTER("process");
- Z while (fgets(buf,BUFSIZ,inf) != NULL)
- Z {
- Z sscanf(buf,"%24s %1s %ld", fn_name, fn_what, &fn_time);
- Z pos = add(fn_name);
- Z DBUG_PRINT("enter",("%s %s %d",fn_name,fn_what,fn_time));
- Z if (fn_what[0] == 'E')
- Z push(pos,fn_time);
- Z else {
- Z /*
- Z * An exited function implies that all stacked
- Z * functions are also exited, until the matching
- Z * function is found on the stack.
- Z */
- Z while( pop(&oldpos, &oldtime, &oldchild) ) {
- Z DBUG_PRINT("popped",("%d %d",oldtime,oldchild));
- Z time = fn_time - oldtime;
- Z t = top();
- Z t -> children += time;
- Z DBUG_PRINT("update",("%s",modules[t->pos].name));
- Z DBUG_PRINT("update",("%d",t->children));
- Z time -= oldchild;
- Z modules[oldpos].m_time += time;
- Z modules[oldpos].m_calls++;
- Z tot_time += time;
- Z tot_calls++;
- Z if (pos == oldpos)
- Z goto next_line; /* Should be a break2 */
- Z }
- Z
- Z /*
- Z * Assume that item seen started at time 0.
- Z * (True for function main). But initialize
- Z * it so that it works the next time too.
- Z */
- Z t = top();
- Z time = fn_time - t->time - t->children;
- Z t->time = fn_time; t->children = 0;
- Z modules[pos].m_time += time;
- Z modules[pos].m_calls++;
- Z tot_time += time;
- Z tot_calls++;
- Z }
- Z next_line:;
- Z }
- Z
- Z /*
- Z * Now, we've hit eof. If we still have stuff stacked, then we
- Z * assume that the user called exit, so give everything the exited
- Z * time of fn_time.
- Z */
- Z while (pop(&oldpos,&oldtime,&oldchild))
- Z {
- Z time = fn_time - oldtime;
- Z t = top();
- Z t->children += time;
- Z time -= oldchild;
- Z modules[oldpos].m_time += time;
- Z modules[oldpos].m_calls++;
- Z tot_time += time;
- Z tot_calls++;
- Z }
- Z
- Z DBUG_VOID_RETURN;
- Z}
- Z
- Z/*
- Z * out_header() -- print out the header of the report.
- Z */
- Z
- Zvoid
- Zout_header(outf)
- ZFILE *outf;
- Z{
- Z DBUG_ENTER("out_header");
- Z if (verbose) {
- Z fprintf(outf,"Profile of Execution\n");
- Z fprintf(outf,"Execution times are in milliseconds\n\n");
- Z fprintf(outf," Calls\t\t\t Time\n");
- Z fprintf(outf," -----\t\t\t ----\n");
- Z fprintf(outf,"Times\tPercentage\tTime Spent\tPercentage\n");
- Z fprintf(outf,"Called\tof total\tin Function\tof total Importance\tFunction\n");
- Z fprintf(outf,"======\t==========\t===========\t========== ==========\t========\t\n");
- Z } else {
- Z fprintf(outf," %%time sec #call ms/call %%calls weight name\n");
- Z }
- Z DBUG_VOID_RETURN;
- Z}
- Z
- Z/*
- Z * out_trailer() - writes out the summary line of the report.
- Z */
- Zvoid
- Zout_trailer(outf,sum_calls,sum_time)
- ZFILE *outf;
- Zunsigned long int sum_calls, sum_time;
- Z{
- Z DBUG_ENTER("out_trailer");
- Z if (verbose) {
- Z fprintf(outf,"======\t==========\t===========\t==========\t========\n");
- Z fprintf(outf,"%6d\t%10.2f\t%11d\t%10.2f\t\t%-15s\n",
- Z sum_calls,100.0,sum_time,100.0,"Totals");
- Z }
- Z DBUG_VOID_RETURN;
- Z}
- Z
- Z/*
- Z * out_item() - prints out the output line for a single entry,
- Z * and sets the calls and time fields appropriately.
- Z */
- Z
- Zvoid
- Zout_item(outf,m,called,timed)
- ZFILE *outf;
- Zregister struct module_t *m;
- Zunsigned long int *called, *timed;
- Z{
- Z char *name = m->name;
- Z register unsigned int calls = m->m_calls;
- Z register unsigned long time = m->m_time;
- Z unsigned int import;
- Z double per_time = 0.0;
- Z double per_calls = 0.0;
- Z double ms_per_call, ftime;
- Z
- Z DBUG_ENTER("out_item");
- Z
- Z if (tot_time > 0) {
- Z per_time = (double) (time * 100) / (double) tot_time;
- Z }
- Z if (tot_calls > 0) {
- Z per_calls = (double) (calls * 100) / (double) tot_calls;
- Z }
- Z import = (unsigned int) (per_time * per_calls);
- Z
- Z if (verbose) {
- Z fprintf(outf,"%6d\t%10.2f\t%11d\t%10.2f %10d\t%-15s\n",
- Z calls, per_calls, time, per_time, import, name);
- Z } else {
- Z ms_per_call = time;
- Z ms_per_call /= calls;
- Z ftime = time;
- Z ftime /= 1000;
- Z fprintf(outf,"%8.2f%8.3f%8u%8.3f%8.2f%8u %-s\n",
- Z per_time, ftime, calls, ms_per_call, per_calls, import, name);
- Z }
- Z *called = calls; *timed = time;
- Z DBUG_VOID_RETURN;
- Z}
- Z
- Z/*
- Z * out_body(outf,root,s_calls,s_time) -- Performs an inorder traversal
- Z * on the binary search tree (root). Calls out_item to actually print
- Z * the item out.
- Z */
- Z
- Zvoid
- Zout_body(outf,root,s_calls,s_time)
- ZFILE *outf;
- Zregister unsigned int root;
- Zregister unsigned long int *s_calls, *s_time;
- Z{
- Z unsigned long int calls, time;
- Z
- Z DBUG_ENTER("out_body");
- Z DBUG_PRINT("out_body",("%d,%d",*s_calls,*s_time));
- Z if (root == MAXPROCS) {
- Z DBUG_PRINT("out_body",("%d,%d",*s_calls,*s_time));
- Z DBUG_VOID_RETURN;
- Z }
- Z
- Z while (root != MAXPROCS) {
- Z out_body(outf,s_table[root].lchild,s_calls,s_time);
- Z out_item(outf,&modules[s_table[root].pos],&calls,&time);
- Z DBUG_PRINT("out_body",("-- %d -- %d --", calls, time));
- Z *s_calls += calls;
- Z *s_time += time;
- Z root = s_table[root].rchild;
- Z }
- Z
- Z DBUG_PRINT("out_body",("%d,%d",*s_calls,*s_time));
- Z DBUG_VOID_RETURN;
- Z}
- Z/*
- Z * output() - print out a nice sorted output report on outf.
- Z */
- Z
- Zvoid
- Zoutput(outf)
- ZFILE *outf;
- Z{
- Z unsigned long int sum_calls = 0;
- Z unsigned long int sum_time = 0;
- Z
- Z DBUG_ENTER("output");
- Z if (n_items == 0)
- Z {
- Z fprintf(outf,"%s: No functions to trace\n",my_name);
- Z exit(EX_DATAERR);
- Z }
- Z out_header(outf);
- Z out_body(outf,0,&sum_calls,&sum_time);
- Z out_trailer(outf,sum_calls,sum_time);
- Z DBUG_VOID_RETURN;
- Z}
- Z
- Z
- Z# define usage() fprintf(DBUG_FILE,"Usage: %s [-v] [prof-file]\n",my_name)
- Z
- Zmain(argc, argv, environ)
- Zint argc;
- Zchar *argv[], *environ[];
- Z{
- Z extern int optind, getopt();
- Z extern char *optarg;
- Z register int c;
- Z int badflg = 0;
- Z FILE *infile;
- Z FILE *outfile = {stdout};
- Z
- Z DBUG_ENTER("main");
- Z DBUG_PROCESS(argv[0]);
- Z my_name = argv[0];
- Z
- Z while ((c = getopt(argc,argv,"#:v")) != EOF)
- Z {
- Z switch (c)
- Z {
- Z case '#': /* Debugging Macro enable */
- Z DBUG_PUSH(optarg);
- Z break;
- Z
- Z case 'v': /* Verbose mode */
- Z verbose++;
- Z break;
- Z
- Z default:
- Z badflg++;
- Z break;
- Z }
- Z }
- Z
- Z if (badflg)
- Z {
- Z usage();
- Z DBUG_RETURN(EX_USAGE);
- Z }
- Z
- Z if (optind < argc)
- Z FILEOPEN(infile,argv[optind],"r");
- Z else
- Z FILEOPEN(infile,PRO_FILE,"r");
- Z
- Z process(infile);
- Z output(outfile);
- Z DBUG_RETURN(EX_OK);
- Z}
- STUNKYFLUFF
- set `sum analyze.c`
- if test 22754 != $1
- then
- echo analyze.c: Checksum error. Is: $1, should be: 22754.
- fi
- #
- #
- echo Extracting doinstall.sh:
- sed 's/^Z//' >doinstall.sh <<\STUNKYFLUFF
- Z
- Z# Warning - first line left blank for sh/csh/ksh compatibility. Do not
- Z# remove it. fnf@Unisoft
- Z
- Z# doinstall.sh --- figure out environment and do recursive make with
- Z# appropriate pathnames. Works under SV or BSD.
- Z
- Zif [ -r /usr/include/search.h ]
- Zthen
- Z # System V
- Z $* LLIB=/usr/lib
- Zelse
- Z # 4.2 BSD
- Z $* LLIB=/usr/lib/lint
- Zfi
- STUNKYFLUFF
- set `sum doinstall.sh`
- if test 16801 != $1
- then
- echo doinstall.sh: Checksum error. Is: $1, should be: 16801.
- fi
- #
- #
- echo Extracting example1.c:
- sed 's/^Z//' >example1.c <<\STUNKYFLUFF
- Z#include <stdio.h>
- Z
- Zmain (argc, argv)
- Zint argc;
- Zchar *argv[];
- Z{
- Z printf ("argv[0] = %d\n", argv[0]);
- Z /*
- Z * Rest of program
- Z */
- Z printf ("== done ==\n");
- Z}
- STUNKYFLUFF
- set `sum example1.c`
- if test 55211 != $1
- then
- echo example1.c: Checksum error. Is: $1, should be: 55211.
- fi
- #
- #
- echo Extracting example2.c:
- sed 's/^Z//' >example2.c <<\STUNKYFLUFF
- Z#include <stdio.h>
- Z
- Zint debug = 0;
- Z
- Zmain (argc, argv)
- Zint argc;
- Zchar *argv[];
- Z{
- Z /* printf ("argv = %x\n", argv) */
- Z if (debug) printf ("argv[0] = %d\n", argv[0]);
- Z /*
- Z * Rest of program
- Z */
- Z#ifdef DEBUG
- Z printf ("== done ==\n");
- Z#endif
- Z}
- STUNKYFLUFF
- set `sum example2.c`
- if test 55108 != $1
- then
- echo example2.c: Checksum error. Is: $1, should be: 55108.
- fi
- #
- #
- echo Extracting example3.c:
- sed 's/^Z//' >example3.c <<\STUNKYFLUFF
- Z#include <stdio.h>
- Z
- Zmain (argc, argv)
- Zint argc;
- Zchar *argv[];
- Z{
- Z# ifdef DEBUG
- Z printf ("argv[0] = %d\n", argv[0]);
- Z# endif
- Z /*
- Z * Rest of program
- Z */
- Z# ifdef DEBUG
- Z printf ("== done ==\n");
- Z# endif
- Z}
- STUNKYFLUFF
- set `sum example3.c`
- if test 54881 != $1
- then
- echo example3.c: Checksum error. Is: $1, should be: 54881.
- fi
- #
- #
- echo Extracting factorial.c:
- sed 's/^Z//' >factorial.c <<\STUNKYFLUFF
- Z#include <stdio.h>
- Z/* User programs should use <local/dbug.h> */
- Z#include "dbug.h"
- Z
- Zint factorial (value)
- Zregister int value;
- Z{
- Z DBUG_ENTER ("factorial");
- Z DBUG_PRINT ("find", ("find %d factorial", value));
- Z if (value > 1) {
- Z value *= factorial (value - 1);
- Z }
- Z DBUG_PRINT ("result", ("result is %d", value));
- Z DBUG_RETURN (value);
- Z}
- STUNKYFLUFF
- set `sum factorial.c`
- if test 15834 != $1
- then
- echo factorial.c: Checksum error. Is: $1, should be: 15834.
- fi
- #
- #
- echo Extracting install.sh:
- sed 's/^Z//' >install.sh <<\STUNKYFLUFF
- Z
- Z# WARNING -- first line intentionally left blank for sh/csh/ksh
- Z# compatibility. Do not remove it! FNF, UniSoft Systems.
- Z#
- Z# Usage is:
- Z# install <from> <to>
- Z#
- Z# The file <to> is replaced with the file <from>, after first
- Z# moving <to> to a backup file. The backup file name is created
- Z# by prepending the filename (after removing any leading pathname
- Z# components) with "OLD".
- Z#
- Z# This script is currently not real robust in the face of signals
- Z# or permission problems. It also does not do (by intention) all
- Z# the things that the System V or BSD install scripts try to do
- Z#
- Z
- Zif [ $# -ne 2 ]
- Zthen
- Z echo "usage: $0 <from> <to>"
- Z exit 1
- Zfi
- Z
- Z# Now extract the dirname and basename components. Unfortunately, BSD does
- Z# not have dirname, so we do it the hard way.
- Z
- Zfd=`expr $1'/' : '\(/\)[^/]*/$' \| $1'/' : '\(.*[^/]\)//*[^/][^/]*//*$' \| .`
- Zff=`basename $1`
- Ztd=`expr $2'/' : '\(/\)[^/]*/$' \| $2'/' : '\(.*[^/]\)//*[^/][^/]*//*$' \| .`
- Ztf=`basename $2`
- Z
- Z# Now test to make sure that they are not the same files.
- Z
- Zif [ $fd/$ff = $td/$tf ]
- Zthen
- Z echo "install: input and output are same files"
- Z exit 2
- Zfi
- Z
- Z# Save a copy of the "to" file as a backup.
- Z
- Zif test -f $td/$tf
- Zthen
- Z if test -f $td/OLD$tf
- Z then
- Z rm -f $td/OLD$tf
- Z fi
- Z mv $td/$tf $td/OLD$tf
- Z if [ $? != 0 ]
- Z then
- Z exit 3
- Z fi
- Zfi
- Z
- Z# Now do the copy and return appropriate status
- Z
- Zcp $fd/$ff $td/$tf
- Zif [ $? != 0 ]
- Zthen
- Z exit 4
- Zelse
- Z exit 0
- Zfi
- Z
- STUNKYFLUFF
- set `sum install.sh`
- if test 30596 != $1
- then
- echo install.sh: Checksum error. Is: $1, should be: 30596.
- fi
- #
- #
- echo Extracting llib-ldbug:
- sed 's/^Z//' >llib-ldbug <<\STUNKYFLUFF
- Z/*
- Z ******************************************************************************
- Z * *
- Z * N O T I C E *
- Z * *
- Z * Copyright Abandoned, 1987, Fred Fish *
- Z * *
- Z * *
- Z * This previously copyrighted work has been placed into the public *
- Z * domain by the author and may be freely used for any purpose, *
- Z * private or commercial. *
- Z * *
- Z * Because of the number of inquiries I was receiving about the use *
- Z * of this product in commercially developed works I have decided to *
- Z * simply make it public domain to further its unrestricted use. I *
- Z * specifically would be most happy to see this material become a *
- Z * part of the standard Unix distributions by AT&T and the Berkeley *
- Z * Computer Science Research Group, and a standard part of the GNU *
- Z * system from the Free Software Foundation. *
- Z * *
- Z * I would appreciate it, as a courtesy, if this notice is left in *
- Z * all copies and derivative works. Thank you. *
- Z * *
- Z * The author makes no warranty of any kind with respect to this *
- Z * product and explicitly disclaims any implied warranties of mer- *
- Z * chantability or fitness for any particular purpose. *
- Z * *
- Z ******************************************************************************
- Z */
- Z
- Z
- Z/*
- Z * FILE
- Z *
- Z * llib-ldbug lint library source for debugging package
- Z *
- Z * SCCS ID
- Z *
- Z * @(#)llib-ldbug 1.8 9/9/87
- Z *
- Z * DESCRIPTION
- Z *
- Z * Function definitions for use in building lint library.
- Z * Note that these must stay in syncronization with actual
- Z * declarations in "dbug.c".
- Z *
- Z */
- Z
- Z
- Z/*LINTLIBRARY*/
- Z
- Z#include <stdio.h>
- Z
- Z#define VOID void
- Ztypedef int BOOLEAN;
- Z#define FALSE 0
- Z#define ARGLIST a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15
- Z
- Zint _db_on_ = FALSE;
- Zint _db_pon_ = FALSE;
- ZFILE *_db_fp_ = stderr;
- ZFILE *_db_pfp_ = stderr;
- Zchar *_db_process_ = "dbug";
- Z
- ZVOID _db_push_ (control)
- Zchar *control;
- Z{
- Z}
- Z
- ZVOID _db_pop_ ()
- Z{
- Z}
- Z
- ZVOID _db_enter_ (_func_, _file_, _line_, _sfunc_, _sfile_, _slevel_)
- Zchar *_func_;
- Zchar *_file_;
- Zint _line_;
- Zchar **_sfunc_;
- Zchar **_sfile_;
- Zint *_slevel_;
- Z{
- Z}
- Z
- ZVOID _db_return_ (_line_, _sfunc_, _sfile_, _slevel_)
- Zint _line_;
- Zchar **_sfunc_;
- Zchar **_sfile_;
- Zint *_slevel_;
- Z{
- Z}
- Z
- ZVOID _db_pargs_ (_line_, keyword)
- Zint _line_;
- Zchar *keyword;
- Z{
- Z}
- Z
- Z/*VARARGS1*/
- ZVOID _db_doprnt_ (format, ARGLIST)
- Zchar *format;
- Zlong ARGLIST;
- Z{
- Z}
- Z
- Z/* WARNING -- the following function is obsolete and may not be supported */
- Z/* in future releases... */
- Z
- Z/*VARARGS3*/
- ZVOID _db_printf_ (_line_, keyword, format, ARGLIST)
- Zint _line_;
- Zchar *keyword, *format;
- Zlong ARGLIST;
- Z{
- Z}
- Z
- ZBOOLEAN _db_keyword_ (keyword)
- Zchar *keyword;
- Z{
- Z return (0);
- Z}
- Z
- ZVOID _db_longjmp_ ()
- Z{
- Z}
- Z
- ZVOID _db_setjmp_ ()
- Z{
- Z}
- STUNKYFLUFF
- set `sum llib-ldbug`
- if test 37792 != $1
- then
- echo llib-ldbug: Checksum error. Is: $1, should be: 37792.
- fi
- #
- #
- echo Extracting main.c:
- sed 's/^Z//' >main.c <<\STUNKYFLUFF
- Z#include <stdio.h>
- Z/* User programs should use <local/dbug.h> */
- Z#include "dbug.h"
- Z
- Zmain (argc, argv)
- Zint argc;
- Zchar *argv[];
- Z{
- Z register int result, ix;
- Z extern int factorial (), atoi ();
- Z
- Z DBUG_ENTER ("main");
- Z DBUG_PROCESS (argv[0]);
- Z for (ix = 1; ix < argc && argv[ix][0] == '-'; ix++) {
- Z switch (argv[ix][1]) {
- Z case '#':
- Z DBUG_PUSH (&(argv[ix][2]));
- Z break;
- Z }
- Z }
- Z for (; ix < argc; ix++) {
- Z DBUG_PRINT ("args", ("argv[%d] = %s", ix, argv[ix]));
- Z result = factorial (atoi (argv[ix]));
- Z printf ("%d\n", result);
- Z }
- Z DBUG_RETURN (0);
- Z}
- STUNKYFLUFF
- set `sum main.c`
- if test 63585 != $1
- then
- echo main.c: Checksum error. Is: $1, should be: 63585.
- fi
- #
- #
- echo Extracting mklintlib.sh:
- sed 's/^Z//' >mklintlib.sh <<\STUNKYFLUFF
- Z
- Z# Warning - first line left blank for sh/csh/ksh compatibility. Do not
- Z# remove it. fnf@Unisoft
- Z
- Z# mklintlib --- make a lint library, under either System V or 4.2 BSD
- Z#
- Z# usage: mklintlib <infile> <outfile>
- Z#
- Z
- Zif test $# -ne 2
- Zthen
- Z echo "usage: mklintlib <infile> <outfile>"
- Z exit 1
- Zfi
- Z
- Zif grep SIGTSTP /usr/include/signal.h >/dev/null
- Zthen # BSD
- Z if test -r /usr/include/whoami.h # 4.1
- Z then
- Z /lib/cpp -C -Dlint $1 >hlint
- Z (/usr/lib/lint/lint1 <hlint >$2) 2>&1 | grep -v warning
- Z else # 4.2
- Z lint -Cxxxx $1
- Z mv llib-lxxxx.ln $2
- Z fi
- Zelse # USG
- Z cc -E -C -Dlint $1 | /usr/lib/lint1 -vx -Hhlint >$2
- Z rm -f hlint
- Zfi
- Zexit 0 # don't kill make
- STUNKYFLUFF
- set `sum mklintlib.sh`
- if test 51735 != $1
- then
- echo mklintlib.sh: Checksum error. Is: $1, should be: 51735.
- fi
- #
- #
- echo Extracting ranlib.sh:
- sed 's/^Z//' >ranlib.sh <<\STUNKYFLUFF
- Z
- Z# Warning - first line left blank for sh/csh/ksh compatibility. Do not
- Z# remove it. fnf@Unisoft
- Z
- Z# ranlib --- do a ranlib if necessary
- Z
- Zif [ -r /usr/bin/ranlib ]
- Zthen
- Z /usr/bin/ranlib $*
- Zelif [ -r /bin/ranlib ]
- Zthen
- Z /bin/ranlib $*
- Zelse
- Z :
- Zfi
- STUNKYFLUFF
- set `sum ranlib.sh`
- if test 13298 != $1
- then
- echo ranlib.sh: Checksum error. Is: $1, should be: 13298.
- fi
- #
- #
- echo Extracting useful.h:
- sed 's/^Z//' >useful.h <<\STUNKYFLUFF
- Z/*
- Z * Copyright June 1987, Binayak Banerjee
- Z * All rights reserved.
- Z *
- Z * This program may be freely distributed under the same terms and
- Z * conditions as Fred Fish's Dbug package.
- Z *
- Z * Useful macros which I use a lot.
- Z *
- Z * Conditionally include some useful files.
- Z */
- Z
- Z# ifndef EOF
- Z# include <stdio.h>
- Z# endif
- Z
- Z/*
- Z * For BSD systems, you can include <sysexits.h> for more detailed
- Z * exit information. For non-BSD systems (which also includes
- Z * non-unix systems) just map everything to "failure" = 1 and
- Z * "success" = 0. -Fred Fish 9-Sep-87
- Z */
- Z
- Z# ifdef BSD
- Z# include <sysexits.h>
- Z# else
- Z# define EX_SOFTWARE 1
- Z# define EX_DATAERR 1
- Z# define EX_USAGE 1
- Z# define EX_OSERR 1
- Z# define EX_IOERR 1
- Z# define EX_OK 0
- Z# endif
- Z
- Z
- Z/*
- Z * Fred Fish's debugging stuff. Define DBUG_OFF in order to disable if
- Z * you don't have these.
- Z */
- Z
- Z# ifndef DBUG_OFF
- Z# include "dbug.h" /* Use local version */
- Z# else
- Z# define DBUG_ENTER(a1)
- Z# define DBUG_RETURN(a1) return(a1)
- Z# define DBUG_VOID_RETURN return
- Z# define DBUG_EXECUTE(keyword,a1)
- Z# define DBUG_2(keyword,format)
- Z# define DBUG_3(keyword,format,a1)
- Z# define DBUG_4(keyword,format,a1,a2)
- Z# define DBUG_5(keyword,format,a1,a2,a3)
- Z# define DBUG_PUSH(a1)
- Z# define DBUG_POP()
- Z# define DBUG_PROCESS(a1)
- Z# define DBUG_PRINT(x,y)
- Z# define DBUG_FILE (stderr)
- Z# endif
- Z
- Z#define __MERF_OO_ "%s: Malloc Failed in %s: %d\n"
- Z
- Z#define Nil(Typ) ((Typ *) 0) /* Make Lint happy */
- Z
- Z#define MALLOC(Ptr,Num,Typ) do /* Malloc w/error checking & exit */ \
- Z if ((Ptr = (Typ *)malloc((Num)*(sizeof(Typ)))) == Nil(Typ)) \
- Z {fprintf(stderr,__MERF_OO_,my_name,__FILE__,__LINE__);\
- Z exit(EX_OSERR);} while(0)
- Z
- Z#define Malloc(Ptr,Num,Typ) do /* Weaker version of above */\
- Z if ((Ptr = (Typ *)malloc((Num)*(sizeof(Typ)))) == Nil(Typ)) \
- Z fprintf(stderr,__MERF_OO_,my_name,__FILE__,__LINE__);\
- Z while(0)
- Z
- Z#define FILEOPEN(Fp,Fn,Mod) do /* File open with error exit */ \
- Z if((Fp = fopen(Fn,Mod)) == Nil(FILE))\
- Z {fprintf(stderr,"%s: Couldn't open %s\n",my_name,Fn);\
- Z exit(EX_IOERR);} while(0)
- Z
- Z#define Fileopen(Fp,Fn,Mod) do /* Weaker version of above */ \
- Z if((Fp = fopen(Fn,Mod)) == Nil(FILE)) \
- Z fprintf(stderr,"%s: Couldn't open %s\n",my_name,Fn);\
- Z while(0)
- Z
- Z
- Zextern char *my_name; /* The name that this was called as */
- STUNKYFLUFF
- set `sum useful.h`
- if test 28861 != $1
- then
- echo useful.h: Checksum error. Is: $1, should be: 28861.
- fi
- #
- #
- echo Extracting user.r:
- sed 's/^Z//' >user.r <<\STUNKYFLUFF
- Z.\" @(#)user.r 1.15 7/27/87
- Z.\"
- Z.\" DBUG (Macro Debugger Package) nroff source
- Z.\"
- Z.\" nroff -mm user.r >user.t
- Z.\"
- Z.\" ===================================================
- Z.\"
- Z.\" === Some sort of black magic, but I forget...
- Z.tr ~
- Z.\" === Hyphenation control (1 = on)
- Z.\".nr Hy 1
- Z.\" === Force all first level headings to start on new page
- Z.nr Ej 1
- Z.\" === Set for breaks after headings for levels 1-3
- Z.nr Hb 3
- Z.\" === Set for space after headings for levels 1-3
- Z.nr Hs 3
- Z.\" === Set standard indent for one/half inch
- Z.nr Si 10
- Z.\" === Set page header
- Z.PH "/DBUG User Manual//\*(DT/"
- Z.\" === Set page footer
- Z.PF "// - % - //"
- Z.\" === Set page offset
- Z.\".po 0.60i
- Z.\" === Set line length
- Z.\".ll 6.5i
- Z.TL
- ZD B U G
- Z.P 0
- ZC Program Debugging Package
- Z.P 0
- Zby
- Z.AU "Fred Fish"
- Z.AF ""
- Z.SA 1
- Z.\" === All paragraphs indented.
- Z.nr Pt 1
- Z.AS 1
- ZThis document introduces
- Z.I dbug ,
- Za macro based C debugging
- Zpackage which has proven to be a very flexible and useful tool
- Zfor debugging, testing, and porting C programs.
- Z
- Z.P
- ZAll of the features of the
- Z.I dbug
- Zpackage can be enabled or disabled dynamically at execution time.
- ZThis means that production programs will run normally when
- Zdebugging is not enabled, and eliminates the need to maintain two
- Zseparate versions of a program.
- Z
- Z.P
- ZMany of the things easily accomplished with conventional debugging
- Ztools, such as symbolic debuggers, are difficult or impossible with this
- Zpackage, and vice versa.
- ZThus the
- Z.I dbug
- Zpackage should
- Z.I not
- Zbe thought of as a replacement or substitute for
- Zother debugging tools, but simply as a useful
- Z.I addition
- Zto the
- Zprogram development and maintenance environment.
- Z
- Z.AE
- Z.MT 4
- Z.SK
- Z.B
- ZINTRODUCTION
- Z.R
- Z
- Z.P
- ZAlmost every program development environment worthy of the name
- Zprovides some sort of debugging facility.
- ZUsually this takes the form of a program which is capable of
- Zcontrolling execution of other programs and examining the internal
- Zstate of other executing programs.
- ZThese types of programs will be referred to as external debuggers
- Zsince the debugger is not part of the executing program.
- ZExamples of this type of debugger include the
- Z.B adb
- Zand
- Z.B sdb
- Zdebuggers provided with the
- Z.B UNIX\*F
- Z.FS
- ZUNIX is a trademark of AT&T Bell Laboratories.
- Z.FE
- Zoperating system.
- Z
- Z.P
- ZOne of the problems associated with developing programs in an environment
- Zwith good external debuggers is that developed programs tend to have
- Zlittle or no internal instrumentation.
- ZThis is usually not a problem for the developer since he is,
- Zor at least should be, intimately familiar with the internal organization,
- Zdata structures, and control flow of the program being debugged.
- ZIt is a serious problem for maintenance programmers, who
- Zare unlikely to have such familiarity with the program being
- Zmaintained, modified, or ported to another environment.
- ZIt is also a problem, even for the developer, when the program is
- Zmoved to an environment with a primitive or unfamiliar debugger,
- Zor even no debugger.
- Z
- Z.P
- ZOn the other hand,
- Z.I dbug
- Zis an example of an internal debugger.
- ZBecause it requires internal instrumentation of a program,
- Zand its usage does not depend on any special capabilities of
- Zthe execution environment, it is always available and will
- Zexecute in any environment that the program itself will
- Zexecute in.
- ZIn addition, since it is a complete package with a specific
- Zuser interface, all programs which use it will be provided
- Zwith similar debugging capabilities.
- ZThis is in sharp contrast to other forms of internal instrumentation
- Zwhere each developer has their own, usually less capable, form
- Zof internal debugger.
- ZIn summary,
- Zbecause
- Z.I dbug
- Zis an internal debugger it provides consistency across operating
- Zenvironments,
- Zand because it is available to all developers it provides
- Zconsistency across all programs in the same environment.
- Z
- Z.P
- ZThe
- Z.I dbug
- Zpackage imposes only a slight speed penalty on executing
- Zprograms, typically much less than 10 percent, and a modest size
- Zpenalty, typically 10 to 20 percent.
- ZBy defining a specific C preprocessor symbol both of these
- Zcan be reduced to zero with no changes required to the
- Zsource code.
- Z
- Z.P
- ZThe following list is a quick summary of the capabilities
- Zof the
- Z.I dbug
- Zpackage.
- ZEach capability can be individually enabled or disabled
- Zat the time a program is invoked by specifying the appropriate
- Zcommand line arguments.
- Z.SP 1
- Z.ML o 1i
- Z.LI
- ZExecution trace showing function level control flow in a
- Zsemi-graphically manner using indentation to indicate nesting
- Zdepth.
- Z.LI
- ZOutput the values of all, or any subset of, key internal variables.
- Z.LI
- ZLimit actions to a specific set of named functions.
- Z.LI
- ZLimit function trace to a specified nesting depth.
- Z.LI
- ZLabel each output line with source file name and line number.
- Z.LI
- ZLabel each output line with name of current process.
- Z.LI
- ZPush or pop internal debugging state to allow execution with
- Zbuilt in debugging defaults.
- Z.LI
- ZRedirect the debug output stream to standard output (stdout)
- Zor a named file.
- ZThe default output stream is standard error (stderr).
- ZThe redirection mechanism is completely independent of
- Znormal command line redirection to avoid output conflicts.
- Z.LE
- Z
- Z.SK
- Z.B
- ZPRIMITIVE DEBUGGING TECHNIQUES
- Z.R
- Z
- Z.P
- ZInternal instrumentation is already a familiar concept
- Zto most programmers, since it is usually the first debugging
- Ztechnique learned.
- ZTypically, "print\ statements" are inserted in the source
- Zcode at interesting points, the code is recompiled and executed,
- Zand the resulting output is examined in an attempt to determine
- Zwhere the problem is.
- Z
- ZThe procedure is iterative, with each iteration yielding more
- Zand more output, and hopefully the source of the problem is
- Zdiscovered before the output becomes too large to deal with
- Zor previously inserted statements need to be removed.
- ZFigure 1 is an example of this type of primitive debugging
- Ztechnique.
- Z.DS I N
- Z.SP 2
- Z.so example1.r
- Z.SP 2
- Z.ll -5
- Z.ce
- ZFigure 1
- Z.ce
- ZPrimitive Debugging Technique
- Z.ll +5
- Z.SP 2
- Z.DE
- Z
- Z.P
- ZEventually, and usually after at least several iterations, the
- Zproblem will be found and corrected.
- ZAt this point, the newly inserted print statements must be
- Zdealt with.
- ZOne obvious solution is to simply delete them all.
- ZBeginners usually do this a few times until they have to
- Zrepeat the entire process every time a new bug pops up.
- ZThe second most obvious solution is to somehow disable
- Zthe output, either through the source code comment facility,
- Zcreation of a debug variable to be switched on or off, or by using the
- ZC preprocessor.
- ZFigure 2 is an example of all three techniques.
- Z.DS I N
- Z.SP 2
- Z.so example2.r
- Z.SP 2
- Z.ll -5
- Z.ce
- ZFigure 2
- Z.ce
- ZDebug Disable Techniques
- Z.ll +5
- Z.SP 2
- Z.DE
- Z
- Z.P
- ZEach technique has its advantages and disadvantages with respect
- Zto dynamic vs static activation, source code overhead, recompilation
- Zrequirements, ease of use, program readability, etc.
- ZOveruse of the preprocessor solution quickly leads to problems with
- Zsource code readability and maintainability when multiple
- Z.B #ifdef
- Zsymbols are to be defined or undefined based on specific types
- Zof debug desired.
- ZThe source code can be made slightly more readable by suitable indentation
- Zof the
- Z.B #ifdef
- Zarguments to match the indentation of the code, but
- Znot all C preprocessors allow this.
- ZThe only requirement for the standard
- Z.B UNIX
- ZC preprocessor is for the '#' character to appear
- Zin the first column, but even this seems
- Zlike an arbitrary and unreasonable restriction.
- ZFigure 3 is an example of this usage.
- Z.DS I N
- Z.SP 2
- Z.so example3.r
- Z.SP 2
- Z.ll -5
- Z.ce
- ZFigure 3
- Z.ce
- ZMore Readable Preprocessor Usage
- Z.ll +5
- Z.SP 2
- Z.DE
- Z
- Z.SK
- Z.B
- ZFUNCTION TRACE EXAMPLE
- Z.R
- Z
- Z.P
- ZWe will start off learning about the capabilities of the
- Z.I dbug
- Zpackage by using a simple minded program which computes the
- Zfactorial of a number.
- ZIn order to better demonstrate the function trace mechanism, this
- Zprogram is implemented recursively.
- ZFigure 4 is the main function for this factorial program.
- Z.DS I N
- Z.SP 2
- Z.so main.r
- Z.SP 2
- Z.ll -5
- Z.ce
- ZFigure 4
- Z.ce
- ZFactorial Program Mainline
- Z.ll +5
- Z.SP 2
- Z.DE
- Z
- Z.P
- ZThe
- Z.B main
- Zfunction is responsible for processing any command line
- Zoption arguments and then computing and printing the factorial of
- Zeach non-option argument.
- Z.P
- ZFirst of all, notice that all of the debugger functions are implemented
- Zvia preprocessor macros.
- ZThis does not detract from the readability of the code and makes disabling
- Zall debug compilation trivial (a single preprocessor symbol,
- Z.B DBUG_OFF ,
- Zforces the macro expansions to be null).
- Z.P
- ZAlso notice the inclusion of the header file
- Z.B dbug.h
- Zfrom the local header file directory.
- Z(The version included here is the test version in the dbug source
- Zdistribution directory).
- ZThis file contains all the definitions for the debugger macros, which
- Zall have the form
- Z.B DBUG_XX...XX .
- Z
- Z.P
- ZThe
- Z.B DBUG_ENTER
- Zmacro informs that debugger that we have entered the
- Zfunction named
- Z.B main .
- ZIt must be the very first "executable" line in a function, after
- Zall declarations and before any other executable line.
- ZThe
- Z.B DBUG_PROCESS
- Zmacro is generally used only once per program to
- Zinform the debugger what name the program was invoked with.
- ZThe
- Z.B DBUG_PUSH
- Zmacro modifies the current debugger state by
- Zsaving the previous state and setting a new state based on the
- Zcontrol string passed as its argument.
- ZThe
- Z.B DBUG_PRINT
- Zmacro is used to print the values of each argument
- Zfor which a factorial is to be computed.
- ZThe
- Z.B DBUG_RETURN
- Zmacro tells the debugger that the end of the current
- Zfunction has been reached and returns a value to the calling
- Zfunction.
- ZAll of these macros will be fully explained in subsequent sections.
- Z.P
- ZTo use the debugger, the factorial program is invoked with a command
- Zline of the form:
- Z.DS CB N
- Zfactorial -#d:t 1 2 3
- Z.DE
- ZThe
- Z.B main
- Zfunction recognizes the "-#d:t" string as a debugger control
- Zstring, and passes the debugger arguments ("d:t") to the
- Z.I dbug
- Zruntime support routines via the
- Z.B DBUG_PUSH
- Zmacro.
- ZThis particular string enables output from the
- Z.B DBUG_PRINT
- Zmacro with the 'd' flag and enables function tracing with the 't' flag.
- ZThe factorial function is then called three times, with the arguments
- Z"1", "2", and "3".
- ZNote that the DBUG_PRINT takes exactly
- Z.B two
- Zarguments, with the second argument (a format string and list
- Zof printable values) enclosed in parenthesis.
- Z.P
- ZDebug control strings consist of a header, the "-#", followed
- Zby a colon separated list of debugger arguments.
- ZEach debugger argument is a single character flag followed
- Zby an optional comma separated list of arguments specific
- Zto the given flag.
- ZSome examples are:
- Z.DS CB N
- Z-#d:t:o
- Z-#d,in,out:f,main:F:L
- Z.DE
- ZNote that previously enabled debugger actions can be disabled by the
- Zcontrol string "-#".
- Z
- Z.P
- ZThe definition of the factorial function, symbolized as "N!", is
- Zgiven by:
- Z.DS CB N
- ZN! = N * N-1 * ... 2 * 1
- Z.DE
- ZFigure 5 is the factorial function which implements this algorithm
- Zrecursively.
- ZNote that this is not necessarily the best way to do factorials
- Zand error conditions are ignored completely.
- Z.DS I N
- Z.SP 2
- Z.so factorial.r
- Z.SP 2
- Z.ll -5
- Z.ce
- ZFigure 5
- Z.ce
- ZFactorial Function
- Z.ll +5
- Z.SP 2
- Z.DE
- Z
- Z.P
- ZOne advantage (some may not consider it so) to using the
- Z.I dbug
- Zpackage is that it strongly encourages fully structured coding
- Zwith only one entry and one exit point in each function.
- ZMultiple exit points, such as early returns to escape a loop,
- Zmay be used, but each such point requires the use of an
- Zappropriate
- Z.B DBUG_RETURN
- Zor
- Z.B DBUG_VOID_RETURN
- Zmacro.
- Z
- Z.P
- ZTo build the factorial program on a
- Z.B UNIX
- Zsystem, compile and
- Zlink with the command:
- Z.DS CB N
- Zcc -o factorial main.c factorial.c -ldbug
- Z.DE
- ZThe "-ldbug" argument tells the loader to link in the
- Zruntime support modules for the
- Z.I dbug
- Zpackage.
- ZExecuting the factorial program with a command of the form:
- Z.DS CB N
- Zfactorial 1 2 3 4 5
- Z.DE
- Zgenerates the output shown in figure 6.
- Z.DS I N
- Z.SP 2
- Z.so output1.r
- Z.SP 2
- Z.ll -5
- Z.ce
- ZFigure 6
- Z.ce
- Zfactorial 1 2 3 4 5
- Z.ll +5
- Z.SP 2
- Z.DE
- Z
- Z.P
- ZFunction level tracing is enabled by passing the debugger
- Zthe 't' flag in the debug control string.
- ZFigure 7 is the output resulting from the command
- Z"factorial\ -#t:o\ 3\ 2".
- Z.DS I N
- Z.SP 2
- Z.so output2.r
- Z.SP 2
- Z.ll -5
- Z.ce
- ZFigure 7
- Z.ce
- Zfactorial -#t:o 3 2
- Z.ll +5
- Z.SP 2
- Z.DE
- Z
- Z.P
- ZEach entry to or return from a function is indicated by '>' for the
- Zentry point and '<' for the exit point, connected by
- Zvertical bars to allow matching points to be easily found
- Zwhen separated by large distances.
- Z
- Z.P
- ZThis trace output indicates that there was an initial call
- Zto factorial from main (to compute 2!), followed by
- Za single recursive call to factorial to compute 1!.
- ZThe main program then output the result for 2! and called the
- Zfactorial function again with the second argument, 3.
- ZFactorial called itself recursively to compute 2! and 1!, then
- Zreturned control to main, which output the value for 3! and exited.
- Z
- Z.P
- ZNote that there is no matching entry point "main>" for the
- Zreturn point "<main" because at the time the
- Z.B DBUG_ENTER
- Zmacro was reached in main, tracing was not enabled yet.
- ZIt was only after the macro
- Z.B DBUG_PUSH
- Zwas executing that tracing became enabled.
- ZThis implies that the argument list should be processed as early as
- Zpossible since all code preceding the first call to
- Z.B DBUG_PUSH
- Zis
- Zessentially invisible to
- Z.B dbug
- Z(this can be worked around by
- Zinserting a temporary
- Z.B DBUG_PUSH(argv[1])
- Zimmediately after the
- Z.B DBUG_ENTER("main")
- Zmacro.
- Z
- Z.P
- ZOne last note,
- Zthe trace output normally comes out on the standard error.
- ZSince the factorial program prints its result on the standard
- Zoutput, there is the possibility of the output on the terminal
- Zbeing scrambled if the two streams are not synchronized.
- ZThus the debugger is told to write its output on the standard
- Zoutput instead, via the 'o' flag character.
- ZNote that no 'o' implies the default (standard error), a 'o'
- Zwith no arguments means standard output, and a 'o'
- Zwith an argument means used the named file.
- ZI.E, "factorial\ -#t:o,logfile\ 3\ 2" would write the trace
- Zoutput in "logfile".
- ZBecause of
- Z.B UNIX
- Zimplementation details, programs usually run
- Zfaster when writing to stdout rather than stderr, though this
- Zis not a prime consideration in this example.
- Z
- Z.SK
- Z.B
- ZUSE OF DBUG_PRINT MACRO
- Z.R
- Z
- Z.P
- ZThe mechanism used to produce "printf" style output is the
- Z.B DBUG_PRINT
- Zmacro.
- Z
- Z.P
- ZTo allow selection of output from specific macros, the first argument
- Zto every
- Z.B DBUG_PRINT
- Zmacro is a
- Z.I dbug
- Zkeyword.
- ZWhen this keyword appears in the argument list of the 'd' flag in
- Za debug control string, as in "-#d,keyword1,keyword2,...:t",
- Zoutput from the corresponding macro is enabled.
- ZThe default when there is no 'd' flag in the control string is to
- Zenable output from all
- Z.B DBUG_PRINT
- Zmacros.
- Z
- Z.P
- ZTypically, a program will be run once, with no keywords specified,
- Zto determine what keywords are significant for the current problem
- Z(the keywords are printed in the macro output line).
- ZThen the program will be run again, with the desired keywords,
- Zto examine only specific areas of interest.
- Z
- Z.P
- ZThe second argument to a
- Z.B DBUG_PRINT
- Zmacro is a standard printf style
- Zformat string and one or more arguments to print, all
- Zenclosed in parenthesis so that they collectively become a single macro
- Zargument.
- ZThis is how variable numbers of printf arguments are supported.
- ZAlso note that no explicit newline is required at the end of the format string.
- ZAs a matter of style, two or three small
- Z.B DBUG_PRINT
- Zmacros are preferable
- Zto a single macro with a huge format string.
- ZFigure 8 shows the output for default tracing and debug.
- Z.DS I N
- Z.SP 2
- Z.so output3.r
- Z.SP 2
- Z.ll -5
- Z.ce
- ZFigure 8
- Z.ce
- Zfactorial -#d:t:o 3
- Z.ll +5
- Z.SP 2
- Z.DE
- Z
- Z.P
- ZThe output from the
- Z.B DBUG_PRINT
- Zmacro is indented to match the trace output
- Zfor the function in which the macro occurs.
- ZWhen debugging is enabled, but not trace, the output starts at the left
- Zmargin, without indentation.
- Z
- Z.P
- ZTo demonstrate selection of specific macros for output, figure
- Z9 shows the result when the factorial program is invoked with
- Zthe debug control string "-#d,result:o".
- Z.DS I N
- Z.SP 2
- Z.so output4.r
- Z.SP 2
- Z.ll -5
- Z.ce
- ZFigure 9
- Z.ce
- Zfactorial -#d,result:o 4
- Z.ll +5
- Z.SP 2
- Z.DE
- Z
- Z.P
- ZIt is sometimes desirable to restrict debugging and trace actions
- Zto a specific function or list of functions.
- ZThis is accomplished with the 'f' flag character in the debug
- Zcontrol string.
- ZFigure 10 is the output of the factorial program when run with the
- Zcontrol string "-#d:f,factorial:F:L:o".
- ZThe 'F' flag enables printing of the source file name and the 'L'
- Zflag enables printing of the source file line number.
- Z.DS I N
- Z.SP 2
- Z.so output5.r
- Z.SP 2
- Z.ll -5
- Z.ce
- ZFigure 10
- Z.ce
- Zfactorial -#d:f,factorial:F:L:o 3
- Z.ll +5
- Z.SP 2
- Z.DE
- Z
- Z.P
- ZThe output in figure 10 shows that the "find" macro is in file
- Z"factorial.c" at source line 8 and the "result" macro is in the same
- Zfile at source line 12.
- Z
- Z.SK
- Z.B
- ZSUMMARY OF MACROS
- Z.R
- Z
- Z.P
- ZThis section summarizes the usage of all currently defined macros
- Zin the
- Z.I dbug
- Zpackage.
- ZThe macros definitions are found in the user include file
- Z.B dbug.h
- Zfrom the standard include directory.
- Z
- Z.SP 2
- Z.BL 20
- Z.LI DBUG_ENTER\
- ZUsed to tell the runtime support module the name of the function
- Zbeing entered.
- ZThe argument must be of type "pointer to character".
- ZThe
- ZDBUG_ENTER
- Zmacro must precede all executable lines in the
- Zfunction just entered, and must come after all local declarations.
- ZEach
- ZDBUG_ENTER
- Zmacro must have a matching
- ZDBUG_RETURN
- Zor
- ZDBUG_VOID_RETURN
- Zmacro
- Zat the function exit points.
- ZDBUG_ENTER
- Zmacros used without a matching
- ZDBUG_RETURN
- Zor
- ZDBUG_VOID_RETURN
- Zmacro
- Zwill cause warning messages from the
- Z.I dbug
- Zpackage runtime support module.
- Z.SP 1
- ZEX:\ DBUG_ENTER\ ("main");
- Z.SP 1
- Z.LI DBUG_RETURN\
- ZUsed at each exit point of a function containing a
- ZDBUG_ENTER
- Zmacro
- Zat the entry point.
- ZThe argument is the value to return.
- ZFunctions which return no value (void) should use the
- ZDBUG_VOID_RETURN
- Zmacro.
- ZIt
- Zis an error to have a
- ZDBUG_RETURN
- Zor
- ZDBUG_VOID_RETURN
- Zmacro in a function
- Zwhich has no matching
- ZDBUG_ENTER
- Zmacro, and the compiler will complain
- Zif the macros are actually used (expanded).
- Z.SP 1
- ZEX:\ DBUG_RETURN\ (value);
- Z.br
- ZEX:\ DBUG_VOID_RETURN;
- Z.SP 1
- Z.LI DBUG_PROCESS\
- ZUsed to name the current process being executed.
- ZA typical argument for this macro is "argv[0]", though
- Zit will be perfectly happy with any other string.
- Z.SP 1
- ZEX:\ DBUG_PROCESS\ (argv[0]);
- Z.SP 1
- Z.LI DBUG_PUSH\
- ZSets a new debugger state by pushing the current
- Z.B dbug
- Zstate onto an
- Zinternal stack and setting up the new state using the debug control
- Zstring passed as the macro argument.
- ZThe most common usage is to set the state specified by a debug
- Zcontrol string retrieved from the argument list.
- ZNote that the leading "-#" in a debug control string specified
- Zas a command line argument must
- Z.B not
- Zbe passed as part of the macro argument.
- ZThe proper usage is to pass a pointer to the first character
- Z.B after
- Zthe "-#" string.
- Z.SP 1
- ZEX:\ DBUG_PUSH\ (\&(argv[i][2]));
- Z.br
- ZEX:\ DBUG_PUSH\ ("d:t");
- Z.br
- ZEX:\ DBUG_PUSH\ ("");
- Z.SP 1
- Z.LI DBUG_POP\
- ZRestores the previous debugger state by popping the state stack.
- ZAttempting to pop more states than pushed will be ignored and no
- Zwarning will be given.
- ZThe
- ZDBUG_POP
- Zmacro has no arguments.
- Z.SP 1
- ZEX:\ DBUG_POP\ ();
- Z.SP 1
- Z.LI DBUG_FILE\
- ZThe
- ZDBUG_FILE
- Zmacro is used to do explicit I/O on the debug output
- Zstream.
- ZIt is used in the same manner as the symbols "stdout" and "stderr"
- Zin the standard I/O package.
- Z.SP 1
- ZEX:\ fprintf\ (DBUG_FILE,\ "Doing my own I/O!\n");
- Z.SP 1
- Z.LI DBUG_EXECUTE\
- ZThe DBUG_EXECUTE macro is used to execute any arbitrary C code.
- ZThe first argument is the debug keyword, used to trigger execution
- Zof the code specified as the second argument.
- ZThis macro must be used cautiously because, like the
- ZDBUG_PRINT
- Zmacro,
- Zit is automatically selected by default whenever the 'd' flag has
- Zno argument list (I.E., a "-#d:t" control string).
- Z.SP 1
- ZEX:\ DBUG_EXECUTE\ ("abort",\ abort\ ());
- Z.SP 1
- Z.LI DBUG_N\
- ZThese macros, where N is in the range 2-5, are currently obsolete
- Zand will be removed in a future release.
- ZUse the new DBUG_PRINT macro.
- Z.LI DBUG_PRINT\
- ZUsed to do printing via the "fprintf" library function on the
- Zcurrent debug stream,
- ZDBUG_FILE.
- ZThe first argument is a debug keyword, the second is a format string
- Zand the corresponding argument list.
- ZNote that the format string and argument list are all one macro argument
- Zand
- Z.B must
- Zbe enclosed in parenthesis.
- Z.SP 1
- ZEX:\ DBUG_PRINT\ ("eof",\ ("end\ of\ file\ found"));
- Z.br
- ZEX:\ DBUG_PRINT\ ("type",\ ("type\ is\ %x", type));
- Z.br
- ZEX:\ DBUG_PRINT\ ("stp",\ ("%x\ ->\ %s", stp, stp\ ->\ name));
- Z.LI DBUG_SETJMP\
- ZUsed in place of the setjmp() function to first save the current
- Zdebugger state and then execute the standard setjmp call.
- ZThis allows the debugger to restore its state when the
- ZDBUG_LONGJMP macro is used to invoke the standard longjmp() call.
- ZCurrently all instances of DBUG_SETJMP must occur within the
- Zsame function and at the same function nesting level.
- Z.SP 1
- ZEX:\ DBUG_SETJMP\ (env);
- Z.LI DBUG_LONGJMP\
- ZUsed in place of the longjmp() function to first restore the
- Zprevious debugger state at the time of the last DBUG_SETJMP
- Zand then execute the standard longjmp() call.
- ZNote that currently all DBUG_LONGJMP macros restore the state
- Zat the time of the last DBUG_SETJMP.
- ZIt would be possible to maintain separate DBUG_SETJMP and DBUG_LONGJMP
- Zpairs by having the debugger runtime support module use the first
- Zargument to differentiate the pairs.
- Z.SP 1
- ZEX:\ DBUG_LONGJMP\ (env,val);
- Z.LE
- Z
- Z.SK
- Z.B
- ZDEBUG CONTROL STRING
- Z.R
- Z
- Z.P
- ZThe debug control string is used to set the state of the debugger
- Zvia the
- Z.B DBUG_PUSH
- Zmacro.
- ZThis section summarizes the currently available debugger options
- Zand the flag characters which enable or disable them.
- ZArgument lists enclosed in '[' and ']' are optional.
- Z.SP 2
- Z.BL 22
- Z.LI d[,keywords]
- ZEnable output from macros with specified keywords.
- ZA null list of keywords implies that all keywords are selected.
- Z.LI D[,time]
- ZDelay for specified time after each output line, to let output drain.
- ZTime is given in tenths of a second (value of 10 is one second).
- ZDefault is zero.
- Z.LI f[,functions]
- ZLimit debugger actions to the specified list of functions.
- ZA null list of functions implies that all functions are selected.
- Z.LI F
- ZMark each debugger output line with the name of the source file
- Zcontaining the macro causing the output.
- Z.LI g
- ZTurn on machine independent profiling.
- ZA profiling data collection file, named dbugmon.out, will be written
- Zfor postprocessing by the "analyze" program.
- ZThe accuracy of this feature is relatively unknown at this time.
- Z.LI L
- ZMark each debugger output line with the source file line number of
- Zthe macro causing the output.
- Z.LI n
- ZMark each debugger output line with the current function nesting depth.
- Z.LI N
- ZSequentially number each debugger output line starting at 1.
- ZThis is useful for reference purposes when debugger output is
- Zinterspersed with program output.
- Z.LI o[,file]
- ZRedirect the debugger output stream to the specified file.
- ZThe default output stream is stderr.
- ZA null argument list causes output to be redirected to stdout.
- Z.LI p[,processes]
- ZLimit debugger actions to the specified processes.
- ZA null list implies all processes.
- ZThis is useful for processes which run child processes.
- ZNote that each debugger output line can be marked with the name of
- Zthe current process via the 'P' flag.
- ZThe process name must match the argument passed to the
- Z.B DBUG_PROCESS
- Zmacro.
- Z.LI P
- ZMark each debugger output line with the name of the current process.
- ZMost useful when used with a process which runs child processes that
- Zare also being debugged.
- ZNote that the parent process must arrange for the debugger control
- Zstring to be passed to the child processes.
- Z.LI r
- ZUsed in conjunction with the
- Z.B DBUG_PUSH
- Zmacro to reset the current
- Zindentation level back to zero.
- ZMost useful with
- Z.B DBUG_PUSH
- Zmacros used to temporarily alter the
- Zdebugger state.
- Z.LI t[,N]
- ZEnable function control flow tracing.
- ZThe maximum nesting depth is specified by N, and defaults to
- Z200.
- Z.LE
- Z.SK
- Z.B
- ZHINTS AND MISCELLANEOUS
- Z.R
- Z
- Z.P
- ZOne of the most useful capabilities of the
- Z.I dbug
- Zpackage is to compare the executions of a given program in two
- Zdifferent environments.
- ZThis is typically done by executing the program in the environment
- Zwhere it behaves properly and saving the debugger output in a
- Zreference file.
- ZThe program is then run with identical inputs in the environment where
- Zit misbehaves and the output is again captured in a reference file.
- ZThe two reference files can then be differentially compared to
- Zdetermine exactly where execution of the two processes diverges.
- Z
- Z.P
- ZA related usage is regression testing where the execution of a current
- Zversion is compared against executions of previous versions.
- ZThis is most useful when there are only minor changes.
- Z
- Z.P
- ZIt is not difficult to modify an existing compiler to implement
- Zsome of the functionality of the
- Z.I dbug
- Zpackage automatically, without source code changes to the
- Zprogram being debugged.
- ZIn fact, such changes were implemented in a version of the
- ZPortable C Compiler by the author in less than a day.
- ZHowever, it is strongly encouraged that all newly
- Zdeveloped code continue to use the debugger macros
- Zfor the portability reasons noted earlier.
- ZThe modified compiler should be used only for testing existing
- Zprograms.
- Z
- Z.SK
- Z.B
- ZCAVEATS
- Z.R
- Z
- Z.P
- ZThe
- Z.I dbug
- Zpackage works best with programs which have "line\ oriented"
- Zoutput, such as text processors, general purpose utilities, etc.
- ZIt can be interfaced with screen oriented programs such as
- Zvisual editors by redefining the appropriate macros to call
- Zspecial functions for displaying the debugger results.
- ZOf course, this caveat is not applicable if the debugger output
- Zis simply dumped into a file for post-execution examination.
- Z
- Z.P
- ZPrograms which use memory allocation functions other than
- Z.B malloc
- Zwill usually have problems using the standard
- Z.I dbug
- Zpackage.
- ZThe most common problem is multiply allocated memory.
- Z.SP 2
- Z.CS
- STUNKYFLUFF
- set `sum user.r`
- if test 36933 != $1
- then
- echo user.r: Checksum error. Is: $1, should be: 36933.
- fi
- echo ALL DONE BUNKY!
- exit 0
-