


      CCCCTTTTRRRRAAAACCCCEEEE((((1111))))                   ((((UUUUNNNNIIIIXXXX 5555....2222))))                  CCCCTTTTRRRRAAAACCCCEEEE((((1111))))



      NNNNAAAAMMMMEEEE
           ctrace - C program debugger

      SSSSYYYYNNNNTTTTAAAAXXXX
           ccccttttrrrraaaacccceeee [ options ] [ file ]

      DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
           _C_t_r_a_c_e allows you to follow the execution of  a  C  program,
           statement  by statement.  The effect is similar to executing
           a shell procedure with the ----xxxx option.  _C_t_r_a_c_e  reads  the  C
           program  in  _f_i_l_e  (or  from  standard  input  if you do not
           specify _f_i_l_e), 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 _c_t_r_a_c_e into
           a temporary file because the _c_c(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 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  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 _b_f_s(1) or
           _t_a_i_l(1) commands.

           The only _o_p_t_i_o_n_s you will commonly use are:

           ----ffff _f_u_n_c_t_i_o_n_s  Trace only these _f_u_n_c_t_i_o_n_s.
           ----vvvv _f_u_n_c_t_i_o_n_s  Trace all but these _f_u_n_c_t_i_o_n_s.

           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.   You  can
           request  that variables be printed in additional formats, if
           appropriate, with these _o_p_t_i_o_n_s:

           ----oooo     Octal
           ----xxxx     Hexadecimal
           ----uuuu     Unsigned
           ----eeee     Floating point

           These _o_p_t_i_o_n_s are used only in special circumstances:




      Page 1                                                   (9010-E)






      CCCCTTTTRRRRAAAACCCCEEEE((((1111))))                   ((((UUUUNNNNIIIIXXXX 5555....2222))))                  CCCCTTTTRRRRAAAACCCCEEEE((((1111))))



           ----llll _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.
           ----ssss     Suppress   redundant   trace   output   from   simple
                  assignment statements and string copy function calls.
                  This option can hide a bug caused by  use  of  the  =
                  operator in place of the == operator.
           ----tttt _n   Trace  _n  variables  per  statement  instead  of  the
                  default  of  10  (the  maximum  number  is  20).  The
                  Diagnostics section explains when to use this option.
           ----PPPP     Run the C preprocessor on the  input  before  tracing
                  it.   You  can  also  use  the  ----DDDD,  ----IIII, and ----UUUU _c_c(1)
                  preprocessor options.

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

           ----bbbb     Use only basic functions in the trace code, that  is,
                  those   in  _c_t_y_p_e(3C),  _p_r_i_n_t_f(3S),  and  _s_t_r_i_n_g(3C).
                  These are usually available even  in  cross-compilers
                  for  microprocessors.   In particular, this option is
                  needed  when  the  traced  program  runs   under   an
                  operating   system  that  does  not  have  _s_i_g_n_a_l(2),
                  _f_f_l_u_s_h(3S), _l_o_n_g_j_m_p(3C), or _s_e_t_j_m_p(3C).
           ----pppp '_s' Change the trace print function from the  default  of
                  'printf('.  For example, 'fprintf(stderr,' would send
                  the trace to the standard error output.
           ----rrrr ffff   Use file _f in place of the _r_u_n_t_i_m_e._c  trace  function
                  package.   This  lets  you  change  the  entire print
                  function,  instead  of  just  the  name  and  leading
                  arguments (see the ----pppp option).

      EEEEXXXXAAAAMMMMPPPPLLLLEEEE
           If the file _l_c._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



      Page 2                                                   (9010-E)






      CCCCTTTTRRRRAAAACCCCEEEE((((1111))))                   ((((UUUUNNNNIIIIXXXX 5555....2222))))                  CCCCTTTTRRRRAAAACCCCEEEE((((1111))))



           1
           (cntl-d),

           the program will be compiled and executed.   The  output  of
           the  program  will  be  the  number  2222, 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 _c_t_r_a_c_e
           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 (cntl-d) the final
           output will be:

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

           Note that the program output printed at the end of the trace
           line  for  the  nnnnllll  variable.   Also note the rrrreeeettttuuuurrrrnnnn comment
           added by _c_t_r_a_c_e 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 cccc is assigned the value
           '1'  in  line  7, but in line 8 it has the value '\n'.  Once



      Page 3                                                   (9010-E)






      CCCCTTTTRRRRAAAACCCCEEEE((((1111))))                   ((((UUUUNNNNIIIIXXXX 5555....2222))))                  CCCCTTTTRRRRAAAACCCCEEEE((((1111))))



           your attention is drawn  to  this  iiiiffff  statement,  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.

      EEEEXXXXEEEECCCCUUUUTTTTIIIIOOOONNNN----TTTTIIIIMMMMEEEE TTTTRRRRAAAACCCCEEEE CCCCOOOONNNNTTTTRRRROOOOLLLL
           The default operation for _c_t_r_a_c_e  is  to  trace  the  entire
           program  file,  unless you use the ----ffff or ----vvvv options 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  _c_t_r_o_f_f()  and  _c_t_r_o_n()
           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 _i_f
           statements, and you can even conditionally include this code
           because  _c_t_r_a_c_e  defines  the  CCCCTTTTRRRRAAAACCCCEEEE preprocessor variable.
           For example:

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

           You can also call these functions from _d_b_x(1) if you compile
           with the ----gggg option.

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

      DDDDIIIIAAAAGGGGNNNNOOOOSSSSTTTTIIIICCCCSSSS
           This section contains diagnostic messages from  both  _c_t_r_a_c_e
           and  _c_c(1), since the traced code often gets some _c_c warning
           messages.  You can get _c_c error messages in some rare cases,
           all of which can be avoided.

         CCCCttttrrrraaaacccceeee DDDDiiiiaaaaggggnnnnoooossssttttiiiiccccssss
           _w_a_r_n_i_n_g: _s_o_m_e _v_a_r_i_a_b_l_e_s _a_r_e _n_o_t _t_r_a_c_e_d _i_n _t_h_i_s _s_t_a_t_e_m_e_n_t
                Only 10 variables are traced in a statement to  prevent
                the C compiler "out of tree space; simplify expression"
                error.  Use the ----tttt option to increase this number.

           _w_a_r_n_i_n_g: _s_t_a_t_e_m_e_n_t _t_o_o _l_o_n_g _t_o _t_r_a_c_e
                This statement is over 400 characters long.  Make  sure
                that  you  are  using  tabs  to  indent  your code, not
                spaces.

           _c_a_n_n_o_t _h_a_n_d_l_e _p_r_e_p_r_o_c_e_s_s_o_r _c_o_d_e, _u_s_e -_P _o_p_t_i_o_n
                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



      Page 4                                                   (9010-E)






      CCCCTTTTRRRRAAAACCCCEEEE((((1111))))                   ((((UUUUNNNNIIIIXXXX 5555....2222))))                  CCCCTTTTRRRRAAAACCCCEEEE((((1111))))



                statement.

           '_i_f ... _e_l_s_e _i_f' _s_e_q_u_e_n_c_e _t_o_o _l_o_n_g
                Split the sequence by removing an eeeellllsssseeee from the middle.

           _p_o_s_s_i_b_l_e _s_y_n_t_a_x _e_r_r_o_r, _t_r_y -_P _o_p_t_i_o_n
                Use the ----PPPP option to preprocess the _c_t_r_a_c_e input, along
                with  any  appropriate  ----DDDD,  ----IIII,  and  ----UUUU  preprocessor
                options.  If you still get the error message, check the
                Warnings section below.

         CCCCcccc DDDDiiiiaaaaggggnnnnoooossssttttiiiiccccssss
           _w_a_r_n_i_n_g: _f_l_o_a_t_i_n_g _p_o_i_n_t _n_o_t _i_m_p_l_e_m_e_n_t_e_d
           _w_a_r_n_i_n_g: _i_l_l_e_g_a_l _c_o_m_b_i_n_a_t_i_o_n _o_f _p_o_i_n_t_e_r _a_n_d _i_n_t_e_g_e_r
           _w_a_r_n_i_n_g: _s_t_a_t_e_m_e_n_t _n_o_t _r_e_a_c_h_e_d
           _w_a_r_n_i_n_g: _s_i_z_e_o_f _r_e_t_u_r_n_s _0
                Ignore these messages.

           _c_o_m_p_i_l_e_r _t_a_k_e_s _s_i_z_e _o_f _f_u_n_c_t_i_o_n
                See the _c_t_r_a_c_e "possible syntax error" message above.

           _y_a_c_c _s_t_a_c_k _o_v_e_r_f_l_o_w
                See the _c_t_r_a_c_e "'if ... else  if'  sequence  too  long"
                message above.

           _o_u_t _o_f _t_r_e_e _s_p_a_c_e; _s_i_m_p_l_i_f_y _e_x_p_r_e_s_s_i_o_n
                Use the ----tttt  option  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.

           _r_e_d_e_c_l_a_r_a_t_i_o_n _o_f _s_i_g_n_a_l
                Either correct this declaration of _s_i_g_n_a_l(2), or remove
                it and #include <signal.h>.

           _e_x_p_r_e_s_s_i_o_n _c_a_u_s_e_s _c_o_m_p_i_l_e_r _l_o_o_p: _t_r_y _s_i_m_p_l_i_f_y_i_n_g
                This is caused by a bug in  the  UNIX/370  C  compiler.
                Unfortunately,  the  only way to avoid it is to use the
                _c_t_r_a_c_e ----vvvv option to not trace the  function  containing
                this line.

      WWWWAAAARRRRNNNNIIIINNNNGGGGSSSS
           You will get a _c_t_r_a_c_e 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 (}).

           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.

           _C_t_r_a_c_e assumes that BADMAG is a preprocessor macro, and that
           EOF and NULL are #defined constants.  Declaring any of these



      Page 5                                                   (9010-E)






      CCCCTTTTRRRRAAAACCCCEEEE((((1111))))                   ((((UUUUNNNNIIIIXXXX 5555....2222))))                  CCCCTTTTRRRRAAAACCCCEEEE((((1111))))



           to be variables, e.g. "int EOF;", will cause a syntax error.

      BBBBUUUUGGGGSSSS
           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.,  %e for a structure with two integer members)
           when printing 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.

      FFFFIIIILLLLEEEESSSS
           runtime.c      run-time trace package

      SSSSEEEEEEEE AAAALLLLSSSSOOOO
           signal(2), ctype(3C), fflush(3S),  longjmp(3C),  printf(3S),
           setjmp(3C), string(3C).





























      Page 6                                                   (9010-E)



