Museum

Home

Lab Overview

Retrotechnology Articles

⇒ Online Manual

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

signal(2)

ctype(3C)

fflush(3S)

longjmp(3C)

printf(3S)

setjmp(3C)

string(3C)



ctrace(1)                         SDK R4.11                        ctrace(1)


NAME
       ctrace - trace a C program to debug it

SYNOPSIS
       ctrace [ options ] [ file ]

DESCRIPTION
       Ctrace lets you follow the execution of a C program, statement by
       statement.  The effect is similar to executing a shell procedure with
       the -x option.  Ctrace reads the C program in file (or from standard
       input if you omit file), inserts statements to print the text of each
       executable statement and the values of all variables referenced or
       modified, and writes the modified program to the standard output.
       You must put the output of ctrace into a temporary file because the
       cc(1) command does not allow the use of a pipe.  You then compile and
       execute this file.

       As each statement in the program executes, it is listed at the
       terminal, followed by the name and value of any variables referenced
       or modified in the statement, followed by any output from the
       statement.  Loops in the trace output are detected and tracing is
       stopped until the loop is exited or a different sequence of
       statements within the loop is executed.  A warning message is printed
       every 1000 times through the loop to help you detect infinite loops.
       The trace output goes to the standard output so you can put it into a
       file for examination with an editor or the bfs(1) or tail(1)
       commands.

       Commonly used options are:

       -f functions  Trace only these functions.
       -v functions  Trace all but these functions.

       You may want to add to the default formats for printing variables.
       Long and pointer variables are always printed as signed integers.
       Pointers to character arrays are also printed as strings if
       appropriate.  Char, short, and int variables are also printed as
       signed integers and, if appropriate, as characters.  Double variables
       are printed as floating point numbers in scientific notation.  The
       options that print variables in additional formats are:

       -o     Octal
       -x     Hexadecimal
       -u     Unsigned
       -e     Floating point

       Other options for special circumstances are:


       -l n   Check n consecutively executed statements for looping trace
              output, instead of the default of 20.  Use 0 to get all the
              trace output from loops.

       -s     Suppress redundant trace output from simple assignment
              statements and string copy function calls.  This option can
              hide a bug caused by using the = operator in place of the ==
              operator.

       -t n   Trace n variables per statement instead of the default of 10
              (the maximum number is 20).  The DIAGNOSTICS section below
              explains when to use this option.

       -P     Run the C preprocessor on the input before tracing it.  You
              can also use the -D, -I, and -U cc(1) preprocessor options.

       The options that tailor the run-time trace package for the traced
       program to run in a non-UNIX system environment are:

       -p 'string'
              Change the trace print function from the default of 'printf('.
              For example, 'fprintf(stderr,' would send the trace to the
              standard error output.

       -r f   Use file f in place of the runtime.c trace function package.
              This lets you change the entire print function, instead of
              just the name and leading arguments (see the -p option).

       -Qarg  If arg is y, identification information about ctrace will be
              added to the output files.  This can be useful for software
              administration.  Giving n for arg explicitly asks for no such
              information, which is the default behavior.

       -V     Prints version information on the standard error.

EXAMPLES
       If the file lc.c contains the following C program:

               1 #include <stdio.h>
               2 main() /* count lines in input */
               3 {
               4   int c, nl;
               5
               6   nl = 0;
               7   while ((c = getchar()) != EOF)
               8        if (c = '\n')
               9             ++nl;
              10   printf("%d\n", nl);
              11 }

       and you enter the following commands and test data:

              cc lc.c
              a.out
              1
              (ctrl-d)

       the program will be compiled and executed.

       The output of the program will be the number 2, which is not correct
       because there is only one line in the test data.  The error in this
       program is common, but subtle.

       If you invoke ctrace with these commands:

              ctrace lc.c >temp.c
              cc temp.c
              a.out

       the output will be:

               2 main()
               6   nl = 0;
                   /* nl == 0 */
               7   while ((c = getchar()) != EOF)

       The program is now waiting for input.  If you enter the same test
       data as before, the output will be:

                   /* c == 49 or '1' */
               8        if (c = '\n')
                        /* c == 10 or '\n' */
               9             ++nl;
                             /* nl == 1 */
               7   while ((c = getchar()) != EOF)
                   /* c == 10 or '\n' */
               8        if (c = '\n')
                        /* c == 10 or '\n' */
               9             ++nl;
                             /* nl == 2 */
               7   while ((c = getchar()) != EOF)

       If you now enter an end of file character (ctrl-d), the final output
       will be:

                   /* c == -1 */
              10   printf("%d\n", nl);
                   /* nl == 2 */2
                   /* return */

       Note the program output printed at the end of the trace line for the
       nl variable.  Also note the return comment added by ctrace at the end
       of the trace output.  This comment shows the implicit return at the
       terminating brace in the function.

       The trace output shows that variable c is assigned the value 1 in
       line 7, but `\n' in line 8.  Once your attention is drawn to the if
       statement in line 8, you will probably realize that you used the
       assignment operator (=) in place of the equal operator (==).  You can
       easily miss this error during code reading.

   Execution-time Trace Control
       The default operation for ctrace is to trace the entire program file,
       unless you use the -f or -v options to trace specific functions.  The
       default does not give you statement by statement control of the
       tracing, nor does it let you turn the tracing off and on when
       executing the traced program.

       You can do both of these by adding ctroff() and ctron() function
       calls to your program to turn the tracing off and on, respectively,
       at execution time.  Thus, you can code arbitrarily complex criteria
       for trace control with if statements, and you can even conditionally
       include this code because ctrace defines the CTRACE preprocessor
       variable.  For example:

              #ifdef CTRACE
                   if (c == '!' && i > 1000)
                        ctron();
              #endif

       These functions can also be called from symbolic debuggers such as
       mxdb(1) or dbx(1) if they are compiled with the -g option.  For
       example, to trace all but lines 7 to 10 in the main function, enter:

              mxdb a.out
              b 7, action {eval ctroff(); c}
              b 11, action {eval ctron(); c}
              c

       You can also turn the trace off and on by setting the static variable
       tr_ct_ to 0 and 1, respectively.

FILES
       runtime.c      run-time trace package

DIAGNOSTICS
       warning: some variables are not traced in this statement
              Only 10 variables are traced in a statement to prevent the C
              compiler "out of tree space; simplify expression" error.  Use
              the -t option to increase this number.

       warning: statement too long to trace
              This statement is over 400 characters long.  Make sure that
              you are using tabs to indent your code, not spaces.

       cannot handle preprocessor code, use -P option
              This is usually caused by #ifdef/#endif preprocessor
              statements in the middle of a C statement, or by a semicolon
              at the end of a #define preprocessor statement.

       'if ... else if' sequence too long
              Split the sequence by removing an else from the middle.

       possible syntax error, try -P option
              Use the -P option to preprocess the ctrace input, along with
              any appropriate -D, -I, and -U preprocessor options.  If you
              still get the error message, check the NOTES section below.

SEE ALSO
       signal(2), ctype(3C), fflush(3S), longjmp(3C), printf(3S),
       setjmp(3C), string(3C).

NOTES
       You will get a ctrace syntax error if you omit the semicolon at the
       end of the last element declaration in a structure or union, just
       before the right brace (}).  This is optional in some C compilers.

       Defining a function with the same name as a system function may cause
       a syntax error if the number of arguments is changed.  Just use a
       different name.

       Ctrace assumes that BADMAG is a preprocessor macro, and that EOF and
       NULL are #defined constants.  Declaring any of these to be variables,
       e.g., "int EOF;", will cause a syntax error.

       Pointer values are always treated as pointers to character strings.

       Ctrace does not know about the components of aggregates like
       structures, unions, and arrays.  It cannot choose a format to print
       all the components of an aggregate when an assignment is made to the
       entire aggregate.  Ctrace may choose to print the address of an
       aggregate or use the wrong format (e.g., 3.149050e-311 for a
       structure with two integer members) when printing the value of an
       aggregate.

       The loop trace output elimination is done separately for each file of
       a multi-file program.  Separate output elimination can result in
       functions called from a loop still being traced, or the elimination
       of trace output from one function in a file until another in the same
       file is called.


Licensed material--property of copyright holder(s)

Typewritten Software • bear@typewritten.org • Edmonds, WA 98026