If you have a problem with GCT, search for the symptom (in bold, below),
then read the following text.  
.NH 1
Trouble Instrumenting your System
.IP "\fBFiles not instrumented\fR"
Is the file in the control file?

If you are using a makefile, is the source file newer than the object file?
Normally, \fBgrestore\fR ensures this.  However, copying files to the
test directory (or extracting them from a configuration control
system) can leave object files newer than source files.
.IP "\fBWarning when compiling \fBgct-ps-defs.c\fR\fR"
.nf
"gct-ps-defs", line 10: warning: zero or negative subscript
.fi

This warning means that no file was instrumented.  See \fIFiles not
instrumented\fR, above.
.IP "\fBMake fails on non-compilation commands\fR"
When using \fBgct\fR with a makefile, there is a recursive
invocation of the makefile:
.nf

	$(MAKE) all "CC=gct"

.fi
In some cases, the actions performed by the makefile fail unless $(CC)
creates an object or executable file.  A typical example is a make
target like this:
.nf

	all: $(OBJ)
	    $(CC) -o temp $(OBJ)
	    mv temp final

.fi
The \fBmv\fR fails because \fBtemp\fR is not created.  In many
versions of \fBmake\fR, you can use \fBmake -k\fR to print error
messages and continue.  This also ignores legitimate errors, so
examine the make log carefully.
.sp
In some cases,
the recursive call can be preceded by a minus sign:
.nf

	-$(MAKE) all "CC=btool"

.fi
but in other cases the makefile must be changed more extensively to
put minus signs in front of many non-compilation actions.
.IP "\fB#pragmas within functions are dangerous.\fR"
All pragmas in the original source are copied into the instrumented
source.  Instrumentation rearranges code within functions.  If the
pragma is within a function and is intended to apply to a following
token (or expression, or statement), that token might have been moved.
Some other token might follow the pragma.  The original token might
even have been moved before the pragma.

This is less likely to be a problem if the pragma is between
statements or inside declarations, but you should check the
instrumented code to make sure.  Instrumentation never rearranges code
outside of functions.

This version of GCT cannot tell whether a pragma is within a function,
so the warning is often spurious.
.IP "\fBGCT warns about variable-length argument lists.\fR
GCT issues this warning when it sees you've written a function
with a variable-length argument list on a machine where such functions
may have to be handled specially.  This note explains the problem, 
what to do about it, and how to find out if you have it.

In C, variable-length argument lists are implemented using the
va_start(), va_arg(), and va_end() macros.  You define them to your
program by including <varargs.h> (for pre-ANSI programs) or <stdarg.h>
(for ANSI-compliant programs).  GCT expands these macros during
instrumentation, just as it expands all macros.  Unfortunately,
<varargs.h> and <stdarg.h> are often written expecting a particular
compiler, and the expanded macros will only work with that compiler.
If so, the versions in \fI/usr/include\fR work with the standard C
compiler (\fI/bin/cc\fR), and other compilers are expected to have
their own private copies of <varargs.h> and <stdarg.h>.

So, on some machines, GCT must "know" which compiler you'll use to
compile the instrumented file, so that it can include the appropriate
files.  Normally, it expects you to use "cc", but it might have been
configured differently.  If you don't use the compiler GCT expects,
you may have to tell it which one you will use.  This is done with the
\fH-test-cc\fR option.  For example, if you use "gcc", you would do
something like this:
.nf

    gct -test-cc gcc varargs.c
    gcc varargs.c

.fi

You need to give the \fH-test-cc\fR argument even if the 
function with a variable number of arguments is not instrumented, but
is only included in a file with other functions that are.

To find out the status of your machine, type
.nf

    gct -test-varargs

.fi 
The output tells you which different compilers you can use, how to
invoke GCT, and how well varargs-using functions work.  In the best case,
alternate compilers can be freely substituted for the
default and you don't have to worry about -test-cc.

If the compiler you use is not mentioned in the output, contact the
GCT installer.  The GCT installation instructions describe scripts
you can use to discover how to use your compiler with GCT.
.IP "\fBControl file not found with multi-directory makefiles\fR"
Have you given the -test-dir argument to \fBgct\fR?

Is the argument correct?  When using `pwd` in your makefile to find
the current directory, you must make sure it is evaluated at the right
time.  For example, if your makefile does not call itself, but rather
changes its directory and calls another makefile, the following will
\fInot\fR work:
.nf

gct:
	gct-init;
	cd subdir; $(MAKE) all "CC=gct -test-dir `pwd`"
	...

.fi
\fBpwd\fR is not evaluated until after the \fBcd\fR.  A correct
solution is
.nf

gct:
	gct-init;
	MYDIR=`pwd`; cd subdir; $(MAKE) all "CC=gct -test-dir $$MYDIR"
	...

.fi
(Note the double dollar signs, which prevent \fBmake\fR from
evaluating "$M" as one of its variables.)
.IP "\fBgct-init: gct-init: No such file or directory\fR"
If you see this message when using your makefile, your version of
\fBmake\fR has a bug.  Add a semicolon after the call to \fBgct-init\fR.
.IP "\fBCompiler Dependencies\fR"
Some programs take advantage of the fact that they are compiled by
the GNU C compiler. They refer to functions or features supported by
\fBgcc\fR but not by other compilers. The commmon way to do that is
by testing whether the actual compiler is gcc or not: #ifdef __GNUC__

Since \fBgct\fR is a modified GNU gcc, the #ifdef __GNUC__ is
evaluated to 1. If you compile the instrumented version of the source
code with any other compiler, difficulties might occur. In this case
you must change the #if to something that will evaluated to 0 (e.g.
__XGNUC__) or place 
.nf

#undef __GNUC__

.fi
in a common include file.
.IP "\fBCompiling with non-ANSI C compilers:  __STDC__\fR"
\fBgct\fR defines \fB__STDC__\fR to indicate that it accepts
ANSI-compliant C code.  If the source has code like
.nf

#ifdef __STDC__
	/* Code dependent on having an ANSI compiler. */
#endif

.fi
the ANSI-dependent code will be included in the instrumented source.
Then compiling with a non-ANSI compiler may lead to compile errors. 
The solution is to give the \fB-traditional\fR switch to \fBgct\fR,
which causes it to undefine \fB__STDC__\fR.  The \fB-traditional\fR
switch is explained in the gcc(1) manpage, which is included with the
distribution.
.IP "\fBgct finds compile errors.\fR
GCC, the compiler that \fBgct\fR is based on, sometimes finds legitimate
errors that other C compilers miss.  You may have to correct the
source.
.sp
Some programs are dependent on features that C compilers have
traditionally supported but that are not part of the language. 
One example is using comments for token concatenation:
.nf 

#define concat(str1, str2)    str1/**/str2

concat(x, 4) ==> x4

.fi
The \fB-traditional\fR switch may persuade \fBgct\fR to let these
programs pass.  See the gcc(1) manpage, which is included with the
distribution.
.NH 1
Errors in Greport Output
.IP "\fBMapfile and Logfile are inconsistent\fR"
.sp
Here \fBgreport\fR reports that the mapfile and logfile have different
sizes.  The most likely cause is that you're using the wrong mapfile.
There's one obscure case, though, where GCT creates an incorrect mapfile.
Suppose you've instrumented your program, you're using a mapfile
name other than \fIgct-map\fR, and you decide to re-instrument.
The first step in the normal sequence is \fBgct-init\fR, which removes
\fIgct-map\fR.  It does not remove your mapfile, so GCT appends to it
during instrumentation.
Since \fBgct-init\fR did initialize \fIgct-ps-defs.h\fR, the mapfile
ends up twice the size of the log file.
.sp
Solution:  Explicitly remove your mapfile each time you instrument (in
addition to calling \fBgct-init\fR).  (It would be better if
\fBgct-init\fR took a \fB-test-map\fR option.
.NH 1
Trouble Working with Greport Output
.IP "\fBLines about included files in greport output\fR"
You may be surprised to find that functions in an #included file are
instrumented, even when that included file is not mentioned in the
control file.  
The decision about
whether to instrument or not is based on the filename passed to GCT,
and that decision applies to all included files.  
There is no way around this.  It is almost
certainly a design flaw, but the fix isn't completely obvious.
.IP "\fBCannot rule out right-hand multicondition.\fR"
In a test like \fHA && B\fR, people often are surprised that \fHB\fR can be
both true and false, but GCT will insist that 
.nf

"test.c", line 4: condition 2 (b, 1) was taken TRUE 1, FALSE 0 times.

.fi
GCT obeys C's rules for short-circuit evaluation. The value of \fHB\fR
is never tested unless \fHA\fR is true.  Not every execution where
\fHB\fR is false will rule out this coverage condition, only one where
\fHA!=0, B==0\fR. 
.sp
It would not be safe to evaluate the right-hand side to see if coverage would be
satisfied.  Consider 
.nf

ptr!=0 && ptr->field==5

.fi
.IP "\fBCannot rule out loop coverage for a do...while loop\fR"
Most likely your tests are doing what you think they are, but the
\fBgreport\fR output doesn't mean what you think it means.  This is a
design flaw that will eventually be fixed.  In the meantime, see the
description of loop coverage in the User's Manual.
