bob@xanadu.COM (Bob Schumaker) (01/06/89)
We are in the process of implementing a multi-tasking executive and we are running into a problem when we move the stack. The premise is that we can allocate some storage in the heap, make the stack pointer point to this storage (after setting up A6 and then copying the stack frame) and restarting execution with the new values (using setjmp/longjmp under LSC 3.01p3). (This clever hack was suggested to us by Michael McClary. It is known to work just fine on various onther systems, so the principle is sound if not particularly pleasing to purists). By the way, the stack sniffer *is* disabled during the process. As soon as the stack pointer and A6 contain the new values, the Mac environment behaves strangely -- the menus highlight with a black rectangle (no highlighted text shows) and/or the text disappears from the menus. Things get progressively weirder from there. As a check, we just copied the stack frame (using the same method) several K below the stack pointer (unused memory between the heap and the stack) and set up all the appropriate registers in an identical fashion -- and everything worked just fine! Does anyone out there have any idea what's going on? The only thing that we can figure is that somewhere in the Mac system software, some routine cares where the stack is -- someone that is, besides the stack sniffer, which *should* be disabled at this point... Thanks in advance.
tim@hoptoad.uucp (Tim Maroney) (01/06/89)
In article <ebmyn#1CMsZI=bob@xanadu.COM> bob@xanadu.COM (Bob Schumaker) writes: >We are in the process of implementing a multi-tasking executive and we are >running into a problem when we move the stack. The premise is that we >can allocate some storage in the heap, make the stack pointer point >to this storage (after setting up A6 and then copying the stack frame) >and restarting execution with the new values (using setjmp/longjmp under >LSC 3.01p3). > >As soon as the stack pointer and A6 contain the new values, the Mac >environment behaves strangely -- the menus highlight with a black >rectangle (no highlighted text shows) and/or the text disappears from >the menus. Things get progressively weirder from there. Clearly data in the heap are getting overwritten, therefore you are not leaving enough space for the stack. Bear in mind that the Mac OS has only one stack -- OS interrupt-driven code will run on whatever the current SP is set to, as will desk accessories if you give them time. Make sure you have left at least 8K of stack space. Check this by using MacsBug's heap check function. If you are overwriting heap data belonging to other blocks, the heap checker will almost surely give an error. I assume you have remembered that 68K stacks grow downwards, so you need to set the SP to the *end* of the block you've allocated, that is, the highest address, not the lowest address. (Actually it should be set to the highest address minus four bytes.) >As a check, we just copied the stack frame (using the same method) several K >below the stack pointer (unused memory between the heap and the stack) and >set up all the appropriate registers in an identical fashion -- and >everything worked just fine! Move the stack away from the heap and you're pretty darned unlikely to overwrite other data in the heap. >Does anyone out there have any idea what's going on? The only thing that >we can figure is that somewhere in the Mac system software, some routine >cares where the stack is -- someone that is, besides the stack sniffer, >which *should* be disabled at this point... "Looking for bugs in all the wrong places...." The menu manager problems indicate that the menu manager heap data structures are getting trashed. -- Tim Maroney, Consultant, Eclectic Software, sun!hoptoad!tim "Please help support the moratorium on meaningless quotes in .signatures." -- Doug Asherman on rec.music.cd
grg@berlin.acss.umn.edu (George Gonzalez) (01/07/89)
I ran into exactly the same problems when implementing multi-tasking within a program I was writing. I did a lot of head scratching until I peeked at the stack, and some of the ROM trap code. What's happening is that many of the ROM traps assume that they can use the space above the op of the appl heap up to the bottom of the stack for temporary storage. I think UnionRgn is one of the worst offenders, dividing up that space into 3-5 equal sized chunks and putting temporary QuicDraw regions in each chunk. This is OK under normal stack usage, but bad if you have several stacks in the stack area. Some of them will get creamed by the temporary vars. There's also a problem if you created the stacks in the appl heap. Now UnionRgn sees that there's no room below the stack and above the heap, as the stack is *inside* the heap. So it just quietly does nothing. This explains why screen redraws get garbled, as QuickDraw can't do its job. When I asked Apple how to solve the problem, they suggested doing all QuickDraw calls from the bottommost stack (the one that has clear space below it down to the top of the appl heap). So allocate your screen update task *last*, and don't draw from any other task. Ugly, but that's the way it is. It would be nice if Apple cleaned up their stack usage. But this would require new ROM's, so its not likely to happen to fix this problem.
jmunkki@kampi.hut.fi (Juri Munkki) (01/07/89)
In article <275@berlin.acss.umn.edu> grg@berlin.acss.umn.edu (George Gonzalez) writes: >What's happening is that many of the ROM traps assume that they can >use the space above the op of the appl heap up to the bottom of the stack >for temporary storage. I think UnionRgn is one of the worst offenders, >dividing up that space into 3-5 equal sized chunks and putting temporary >QuicDraw regions in each chunk. This is OK under normal stack usage, but >bad if you have several stacks in the stack area. Some of them will get >creamed by the temporary vars. Makes me wonder what happens if an exception happens when quickdraw is using the space below the stack. If this exception uses a lot of stack space, isn't it likely that it will overwrite some of the temporary storage? _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._ | Juri Munkki jmunkki@hut.fi jmunkki@fingate.bitnet I Want Ne | | Helsinki University of Technology Computing Centre My Own XT | ~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~
ts@cup.portal.com (Tim W Smith) (01/08/89)
Is the stack sniffer still around? I was developing a simple multitasking system to be downloaded to a stand-alone 68k system, and was using my Mac II to test the code ( TMON and LightspeedC make a great 68k development system ). There were several stacks in my heap area. Since my system did no Mac system calls, I didn't get any of the problems with screen manipulation or anything like that. But I definitely forgot about the stack sniffer. I did not disable it. Yet, I got no bombs. What's going on? Tim Smith
parent@Apple.COM (Sean Parent) (01/10/89)
In article <18694@santra.UUCP>, jmunkki@kampi.hut.fi (Juri Munkki) writes: > In article <275@berlin.acss.umn.edu> grg@berlin.acss.umn.edu (George Gonzalez) writes: > >What's happening is that many of the ROM traps assume that they can > >use the space above the op of the appl heap up to the bottom of the stack > >for temporary storage. I think UnionRgn is one of the worst offenders, > Makes me wonder what happens if an exception happens when quickdraw is > using the space below the stack. If this exception uses a lot of stack I believe that QD just moves A7 to gobble up a good sized piece of the stack. The worst problem is that it uses a couple different methods to determine where the bottom of the stack is (I believe they are all based on low memory globals). Using multible stacks with QD is very tricky and certinly not recomended. Sean
parent@Apple.COM (Sean Parent) (01/10/89)
In article <13322@cup.portal.com>, ts@cup.portal.com (Tim W Smith) writes: > Is the stack sniffer still around? I was developing a simple multitasking > development system ). There were several stacks in my heap area. > But I definitely forgot about the stack sniffer. I did not disable it. > Yet, I got no bombs. What's going on? I am not sure but a believe that that stack sniffer looks for the top of the heap to be overwritten when the SP is out of range. I do know that you do not need to worry about the stack sniffer if you are using A7 to manage your own stacks. Lot's of software uses A7 as just another address register for things like fast blitters. Note - You should not try to use QD while you are operating with an alternate stack there are major problems with doing so. (see other articles for more info) Sean
shebanow@Apple.COM (Andrew Shebanow) (01/15/89)
What you are experiencing is a common problem encountered by people trying to implement multiple threads of execution within a single Mac application. The problem is that QuickDraw (and certain Memory Manager calls) use the stack to store temporary data. They determine how much space is available by subtracting the top of the application heap from the current stack pointer. Since your stack pointer is INSIDE of your heap, you get a very large negative number for stack size. QuickDraw then proceeds to wipe some amount of memory doing its drawing. Depending on where your stack is, and how much stack QuickDraw thinks it has, all sorts of bad things can happen. The workaround is to switch to the main stack BEFORE calling any Mac traps. You can do this by a) patching the A-TRAP dispatcher or b) using glue for all traps. Andrew Shebanow Macintosh Developer Technical Support Apple Computer