[comp.sys.mac] stack sniffer evils

conybear@moncsbruce.oz (Roland Conybeare) (02/02/88)

	I have a problem, a solution, and a gripe.

The problem:
	I have written a multitasking kernel for the Mac.  It is intended
for use within an application rather than between applications, and 
features lightweight processes with fast context switch.
	A consequence of using such multitasking is that you often want
to allocate a process's stack space using memory from the heap.  However,
once your process actually runs with register A7 in the heap, the stack
sniffer picks this up and bombs your application.

The solution:
	The ideal solution to this inappropriate bomb would be for Apple
to have provided some way of turning off the stack sniffer.  The next best
thing would be to do it ourselves.
	Starting with this approach, I tried looking at the vertical
retrace queue, only to find that all the 'system functions' are done
by *one* queue entry - so removing it would disable the mouse, floppy etc.
	My current solution is to replace the SysError() trap with my
own version, which ignores 'stack in the heap' errors while passing other
errors on to the original trap handler.  This means the stack sniffer still
detects 'stack in the heap' up to 60 times a second, but my SysError() trap
says the application managed to recover from the error.
	I am unhappy with this solution for several reasons:
	o It's a hack.
	o The sniffer is still there, wasting clock cycles
	  (and thumbing its nose at me :-)
	o It's a hack.
	o I think it is a fragile solution.  It depends on the sniffer
	  not checking again for 1/60th of a second after my fake
	  SysError() returns, so my app. can get some work done.  In other
	  words, it's a hack!

The gripe:
	I think the event-based structure of the macintosh makes it hard
to program.  This is because different events may belong to different
execution contexts (for example a mousedown in an application window vs.
a DA menu selection), but we have to handle such events in a single
context, the main event loop.  This means we end up with lots of global
variables encoding the state of various 'natural execution contexts',
and our code is obscure to say the least.
	An excellent solution to this problem is to move to process-based
structure.  Each process has its own stack and PC which together encode
a 'natural execution context'.  When combined with some form of event
dispatching, we find our programming task is no harder than in a stream-
oriented environment.
	Thus my *GRIPE* is that the toolbox is trying to stop me programming
the way I want to!!! 

Roland Conybeare
(conybear@moncsbruce)

P.S. I would very much appreciate a response from Apple.

cck@cunixc.columbia.edu (Charlie C. Kim) (02/04/88)

You can disable the stack sniffer with the following Pascal code:
	PROCEDURE DisableStackSniffer;
	CONST StkLowPt = $110;      { system global }
	TYPE LongPtr = ^LongInt;
	VAR p : LongPtr;
	BEGIN
	  p := longptr(StkLowPt);
	  p^ := 0;
	END;
(makes you appreciate C).

StkLowPt is documented someplace in Inside Macintosh, but I forget
where...  StkLowPt is the point that the sniffer decides that the
stack has gone too far.

All this aside, be very careful.  Some toolbox routines may assume
that the space between the bottom of the stack and the top of the
application heap is fair game to do with as it pleases--and it does.
I believe its mainly some quickdraw routines that do this, but others
may too.  This might have been changed with the Multifinder release of
the system, but I doubt it.

I think is that it is better to avoid the entire problem of having
multiple stacks: whether it be on the heap or by splitting up the
stack area.  Very strange things can happen when you do.

Charlie C. Kim
User Services
Columbia University

jimc@iscuva.ISCS.COM (Jim Cathey) (02/05/88)

In article <363@moncsbruce.oz> conybear@moncsbruce.oz (Roland Conybeare) writes:
>The solution:
>	The ideal solution to this inappropriate bomb would be for Apple
>to have provided some way of turning off the stack sniffer.  The next best
>thing would be to do it ourselves.
>	My current solution is to replace the SysError() trap with my
>own version, which ignores 'stack in the heap' errors while passing other
>errors on to the original trap handler.  This means the stack sniffer still
>detects 'stack in the heap' up to 60 times a second, but my SysError() trap
>says the application managed to recover from the error.

The stack sniffer is easily disabled by placing a zero in the global
variable StkLowPt ($110-$113).  The sniffer code then ignores the
stack.  When you're done, you should restore it to whatever it was so
that the stack sniffer will start working again.  I don't remember
where this was documented, but it is a relatively well-known technique.

+----------------+
! II      CCCCCC !  Jim Cathey
! II  SSSSCC     !  ISC Systems Corp.
! II      CC     !  TAF-C8;  Spokane, WA  99220
! IISSSS  CC     !  UUCP: uunet!iscuva!jimc
! II      CCCCCC !  (509) 927-5757
+----------------+
			"With excitement like this, who is needing enemas?"

smethers@psu-cs.UUCP (Paul Smethers) (02/13/88)

In article <1142@iscuva.ISCS.COM> jimc@iscuva.ISCS.COM (Jim Cathey) writes:
>In article <363@moncsbruce.oz> conybear@moncsbruce.oz (Roland Conybeare) writes:
>>The solution:
>>	The ideal solution to this inappropriate bomb would be for Apple
>>to have provided some way of turning off the stack sniffer.  The next best
>>thing would be to do it ourselves.
>
>The stack sniffer is easily disabled by placing a zero in the global
>variable StkLowPt ($110-$113).  The sniffer code then ignores the
>stack.  When you're done, you should restore it to whatever it was so
>that the stack sniffer will start working again.  I don't remember
>where this was documented, but it is a relatively well-known technique.
>
I'm not sure if your new code is generated from a compiler or not, but if
you have control over it yourself (i.e. its your own assembler output), then
you may consider using a register other than A7 for your stack pointer.

Paul Smethers
SmethersBarnes