[comp.sys.mac.programmer] Think C 3.0 Bug?

phil@mit-amt (a phil sohn) (09/02/88)

	I am having some problems with Think C 3.0, and I wonder if
anyone can shed some light.  I am getting many illegal errors and
trying to execute odd address on my two meg Mac II.  Sometimes it even
just hangs or crashes right through Macsbug.  (Not into, but through
maybe killing video sync.) I have no idea how I can be generating
these errors since I am writting no in line assembly.  Why is the
compiler generating code that produces illegal errors?  This is
espically agravating since I am running the symbolic debugger!  Why
do things get through it like that?


						phil

jwhitnell@cup.portal.com (09/04/88)

phil@mit-amt (a phil sohn) writes...
|        I am having some problems with Think C 3.0, and I wonder if
|anyone can shed some light.  I am getting many illegal errors and
|trying to execute odd address on my two meg Mac II.  Sometimes it even
|just hangs or crashes right through Macsbug.  (Not into, but through
|maybe killing video sync.) I have no idea how I can be generating
|these errors since I am writting no in line assembly.  Why is the
|compiler generating code that produces illegal errors?  This is
|espically agravating since I am running the symbolic debugger!  Why
|do things get through it like that?

The problem is most likly a bug (or bugs) in your code.  But because
LSD depends on the ROM and MultiFinder to be in a working state, if your
program trashs low memory or the heap, it can crash LSD.  And since the
crash can happen in ROM or elsewhere, you'll get illegal instructions,
bus errors (MAC II only) and dead systems.  I've talked to people at THINK
about this, suggesting they add more error checking, but if and when they'll
do it is anybodies guess.

Some things to check are the menu bar data structures (calling SetMenuBar
with a non-MBAR is a real quick way to trash your machine) and the window
list.  Trashing either of these guarentees a quick and violent death.

Another think to try is run TMON with strict trap discipline.  This will
catch some of the above, but not all.  Finally, use prototypes and Check
Pointer Types options to check your code at compile time.

Jerry

--
Jerry Whitnell
jwhitnell@cup.portal.com
..!sun!cup.portal.com!jwhitnell

atchison@hpindda.HP.COM (Lee Atchison) (09/08/88)

I ran into almost this exact same problem on at least two occasions.  I
would get a bomb, usually (but not always) with the debugger saying
something like "Illegal Instruction" or "Odd Address".  The problem in
my case was that I was passing (by reference) a local variable to
a Mac Routine that wasn't declared correctly.  In particular, the variable
I passed was a structure of the wrong type (the structure I declared was
smaller than the structure the Mac Routine was expecting).  What happened
was the Mac routine (it was a toolbox routine) wrote beyond the end of
the structure and overwrote part of my stack.  This caused references to
other local variables to go haywire, and occasionally, the return value
to be messed up, so that when I returned from the current routine, I'd
get the Illegal Instruction or Odd Address error.

Like I said, I've had this problem show up on at least two occasions, and
both times it was the same cause -- my program messed up.

This is a sample code segment that could cause the problem:

typedef struct { .... } atype,*Patype,**Hatype;

routine(a,b)
	int *a,*b;
{
	Patype avariable;

	ToolBoxRoutine(&avariable); /* Expects an atype "passed by reference" */

	...other code...

}


It would crash when I tried to access a or b in the "...other code...", or
when I tried to return from this routine (return value overwritten).
The code should be written as:

typedef struct { .... } atype,*Patype,**Hatype;
routine(a,b)
	int *a,*b;
{
	atype avariable;	/* NOT Patype */

	ToolBoxRoutine(&avariable); /* atype passed by reference */

	...other code...
}

This, of course, is a dumb mistake, but an easy mistake to make, and a
hard mistake to catch.  But it will DEFINITELY cause the problems you
are seeing.

I found it by single stepping with the debugger and waiting for it to
crash, then look at the declarations in the rouine it crashed in.

Hope this helps.

			-lee
----
Lee Atchison
Hewlett Packard, Business Networks Division
Cupertino, CA 95014
atchison%hpindda@hplabs.hp.com