Museum

Home

Lab Overview

Retrotechnology Articles

⇒ Online Manual

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

acc(1)

bfs(1)

cc(1)

tail(1)

signal(2)

ctype(3)

fclose(3)

printf(3)

setjmp(3)

string(3)



  ctrace(1)                           CLIX                           ctrace(1)



  NAME

    ctrace - Runs a C program debugger

  SYNOPSIS

    ctrace [flags] [file]

  DESCRIPTION

    The ctrace command is a C program debugger that allows you to follow the
    execution of a C program, statement-by-statement.  The effect is similar
    to executing a shell procedure with the -x flag.  The command ctrace reads
    the C program in file (or from stdin if you do not specify file), inserts
    statements to display the text of each executable statement and the values
    of all variables referenced or modified, and writes the modified program
    to stdout.  You must put the output of ctrace into a temporary file
    because the cc command does not allow the use of a pipe.  You then compile
    and execute this file.

    As each statement in the program executes it will be 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 displayed every 1000 times through the
    loop to help you detect infinite loops.  The trace output goes to stdout
    so you can put it into a file for examination with an editor or the bfs or
    tail commands.

    The flags commonly used are:

    -ffunctions   Trace only these functions.

    -vfunctions   Trace all but these functions.

    You may want to add to the default formats for displaying variables.  Long
    and pointer variables are always displayed as signed integers.  Pointers
    to character arrays are also displayed as strings if appropriate.  Char,
    short, and int variables are also displayed as signed integers and, if
    appropriate, as characters.  Double variables are displayed as floating-
    point numbers in scientific notation.

    String arguments to the string functions and return values from fgets(),
    gets(), and sprintf() are displayed as strings.

    You can request that variables be displayed in additional formats, if
    appropriate, with these flags:

    -o   Octal




  2/94 - Intergraph Corporation                                              1






  ctrace(1)                           CLIX                           ctrace(1)



    -x   Hexadecimal

    -u   Unsigned

    -e   Floating-point

    These flags are used only in special circumstances:

    -ln   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 flag can hide a bug caused by
          use of the = operator in place of the == operator.

    -tn   Trace n variables per statement instead of the default of 10 (the
          maximum number is 20).  The Diagnostics section explains when to use
          this flag.

    -P    Run the C preprocessor on the input before tracing it.  You can also
          use the -D, -I, and -U cpp flags.

    These flags are used to tailor the run-time trace package when the traced
    program will run in a non-UNIX System environment:

    -b   Use only basic functions in the trace code, that is, those in ctype,
         printf(), and string.

    These are usually available even in cross-compilers for microprocessors.
    In particular, this flag is needed when the traced program runs under an
    operating system that does not have signal(), fflush(), longjmp(), or
    setjmpO.

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

    -rf        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 flag).

  Execution-Time Trace Control

    The default operation for ctrace is to trace the entire program file,
    unless you use the -f or -v flags to trace specific functions.  This 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



  2                                              Intergraph Corporation - 2/94






  ctrace(1)                           CLIX                           ctrace(1)



    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

    You can also call these functions from sdb if you compile with the -9
    flag.  For example, to trace all but lines 7 to 10 in the main function,
    enter:

    sdb a.out
    main:7b ctroff()
    main:11b ctron()
    r

    You can also turn the trace off and on by setting static variable tr_ct_
    to 0 and 1, respectively.  This is useful if you are using a debugger that
    cannot call these functions directly.

  EXAMPLE

    If the file lc.c contains this 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 these commands and test data:

    cc lc.c
    a.out
    1
    (cntl-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



  2/94 - Intergraph Corporation                                              3






  ctrace(1)                           CLIX                           ctrace(1)



    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 (cntl-d) the final output will
    be:

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

    Note that the program output displayed 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 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 in line 8 it has the value '\n'.  Once your attention is drawn to
    this if statement, you will probably realize that you used the assignment
    operator (=) in place of the equality operator (==).  You can easily miss
    this error during code reading.


  FILES

    /usr/lib/ctrace/runtime.c   Run-time trace package

  NOTES



  4                                              Intergraph Corporation - 2/94






  ctrace(1)                           CLIX                           ctrace(1)



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

    Pointer values are always treated as pointers to character strings.

    The loop trace output elimination is done separately for each file of a
    multi-file program.  This 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.

  CAUTIONS

    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.

    The command ctrace assumes that BADMAG is a preprocessor macro, and that
    EOF and NULL are #defined constants.  Declaring any of these to be
    variables, for example, ``int EOF;'', will cause a syntax error.

  DIAGNOSTICS

    This section contains diagnostic messages from both ctrace and cc, since
    the traced code often gets some cc warning messages.  You can get cc error
    messages in some rare cases, all of which can be avoided.

  ctrace 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 flag 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 flag
           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



  2/94 - Intergraph Corporation                                              5






  ctrace(1)                           CLIX                           ctrace(1)



           Split the sequence by removing an else from the middle.

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

  cc Diagnostics

    warning: illegal combination of pointer and integer
    warning: statement not reached
    warning: size of returns 0
           Ignore these messages.

    compiler takes size of function
           See the ctrace ``possible syntax error'' message above.

    yacc stack overflow
           See the ctrace ``'if ... else if' sequence too long'' message
           above.

    out of tree space; simplify expression
           Use the -t flag to reduce the number of traced variables per
           statement from the default of 10.  Ignore the ``ctrace: too many
           variables to trace'' warnings you will now get.

    redeclaration of signal
           Either correct this declaration of signal(), or remove it and
           #include <signal.h>.

  RELATED INFORMATION

    Commands: acc(1), bfs(1), cc(1), tail(1)

    Functions: signal(2), ctype(3), fclose(3), printf(3), setjmp(3), string(3)



















  6                                              Intergraph Corporation - 2/94




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