.ds RH Troubleshooting
.bp
.sp
.ce
.ps 16
Troubleshooting
.ps 12
.XS
Troubleshooting
.XE
.LP
See \fIGCT Troubleshooting\fR for help with general GCT problems.
.LP
If you have trouble that you think others might share, please mail a
description of the problem to marick@cs.uiuc.edu, so that this chapter
might be improved.

.NH 1
Trouble Instrumenting
.IP "\fBCompiler runs out of space\fR"
You are most likely using operand coverage and an old C compiler.
You'll have to turn off operand coverage.
.IP "\fBGCT panics.\fR"
GCT will panic if given an expression like
.nf

	((int) p) = 5;

.fi
This is not legal C, but some code contains it.  The only solution is
to change the source.
.IP "\fBWarnings about comparisons.\fR"
Suppose we have this code:
.nf

	(i < 10000000)

.fi
Suppose \fHc\fR is a character.  We will end up with this test, because
characters are comparison-compatible with integers:
.nf

	_G(i < 10000000 != c < 1000000)

.fi
Because the constant is larger than any character, 
this will lead to warnings:
.nf

Sun CC:
"file.c", line 208: warning: constant 1007 is out of range of char comparison
"file.c", line 208: warning: result of comparison is always true

GCC:
file.c: In function remove_intermediates:
file.c:208: warning: comparison is always 1 due to limited range of data type

.fi
It can also lead to warnings from the assembler.  You can safely
ignore all these warnings.
.NH 1
Trouble Handling Greport Output
.IP "\fBCannot figure out which complex operand is meant.\fR"
If you see
.nf

"example1.c", line 9: operand <...>[...] (2) might be C.

.fi
this refers to the second complex array reference on the line (even if
they are not identical).  For example, in this line:
.nf


	p->array[5] + Array[p->array[4]];

\fHp->array[5]\fR is printed as \fHoperand <...>[...]\fR.
\fHArray[p->array[4]]\fR is printed as \fHoperand Array[...]\fR.
\fHp->array[4]\fR is printed as \fHoperand <...>[...] (2)\fR.

.fi
.IP "\fBCannot rule out operand coverage when operand is in relational expression.\fR"
\fBGreport\fR messages of the form 
.nf

"example1.c", line 9: operand A might be B.

.fi
can be frustrating to rule out because of weak sufficiency.  (See the
discussion earlier in this document.)  If A is a part of a relational
operator expression, such as
.nf

	A < 3

.fi
It is not enough to provide a test case where \fHA!=B\fR.  You must
provide a test case where \fH(A<3)!=(B<3)\fR.
.IP "\fBCannot rule out operand coverage when operand is in nested operand.\fR"
(See also above case.)  Weak sufficiency also applies to operands
built up from structures, arrays, and pointer dereferences.  For
example, in the expression
.nf

	function(A[3].foo)

.fi
the "A might be B" message must be ruled out with
\fHA[3].foo!=B[3].foo\fR.  Even worse, if the expression is 
.nf

	A[3].foo < 5

.fi
the needed coverage condition is
.nf

	(A[3].foo) < 5 != (B[3].foo < 5)

.fi
.IP "\fBCannot rule out operand coverage when operand is array index.\fR"
In \fHA[I]\fR, "I might be J" can only be ruled out if \fH0<=J<I\fR.  It
would be dangerous to use other values of \fHJ\fR to index into the array.
GCT will also consider \fHJ\fR ruled out if it is less than zero.
That is, to eliminate the \fBgreport\fR message, you must satisfy this
coverage condition:
.nf

	j<0 || ( 0 <= j < i  && A[i]!=A[j])

.fi
.IP "\fBWrong variable seems to be named.\fR"
.sp
In lines like 
.nf

"example1.c", line 9: operand A (2) might be B.

.fi
the parenthetical number is NOT instances of A on the line, but rather
the number of instances that have had instrumentation generated for
them.  These are almost always the same number.  However, if a
particular instance of A on a line has no associated coverage conditions,
the numbering will be confusing.  The only common case of this is in
assignment.  For example, in
.nf

A = A + 1

.fi
the first A has no coverage conditions.  \fBgreport\fR
would therefore show:
.nf

"example1.c", line 9: operand A might be B.
"example1.c", line 9: operand A might be C.

.fi
referring to the \fIsecond\fR A on the line.  
.sp
Sorry about that.  
.IP "\fBVariable is always reported to be constant.\fR"
.sp
Operand mutation requires variables to actually vary; they must take
on two different values \fIin the same execution of the program\fR.
It is not enough for a variable to have the value 5 when the program
is run once, then value 3 when the program is run again.  This can
make certain variables impossible to vary, because they are set once
in the beginning and never change.  \fHargv\fR, \fHargc\fR, and
standard I/O library buffers (\fHstdin\fR, etc.) exhibit this problem.
You can use the \fH-constants\fR option to suppress constancy
instrumentation entirely.
.IP "\fBInstrumented program dumps core.\fR"
.sp
Most likely, instrumentation caused dereferencing of an uninitialized
(but non-zero) pointer or array.  See the discussion of the
-dereference and -array-substitutions options in the section on the
control file.  \fBgcorefrom\fR(1) can help you locate which
instrumentation caused the problem.
.sp
It's also possible the program has a bug.
.IP "\fBCannot rule out = might be ==.\fR"
.sp
.LP
You must have \fH(!!B) != (A==B)\fR.  The easiest thing to try for is
two non-equal, non-zero numbers.  (This also rules out "= is never needed".)
Having both \fHA\fR and \fHB\fR be 0 also works.
.LP
Watch out for the \fB!!\fR:  it means that \fHA==2,
B==2\fR, for example, will not rule out the condition.
