shf@well.UUCP (Stuart H. Ferguson) (02/26/88)
A while ago I asked for help regarding a bug that was giving me piles of trouble. Thanx for all the response. I've found the problem. It was embarrassingly simple, but very difficult to locate for various reasons. I was passing uninitialized auto variables to a function which was using them to reference into an auto array. Storing to the array with the uninitialized variables as indices was trashing some part of memory causing the mysterious crash when the program tried to exit. Making the array static made the problems go away (but not really!) since a different part of memory would get trashed. The head-bashing I did while bug-hunting brings home one the major difficulties inherient with programming on the Amiga. The kind of problem would be much less likely if the Amiga had memory protection. The "C" language is bad enough, with its arbitrary use of pointers and its intrinsic lack of bounds checking, but coupled with the lack of memory protection on the Amiga -- well, the Amiga is not for the faint of heart. (And people wonder why so many commercial programs have bugs...) So, how to keep this from being a problem in the future... Obvoiusly, I've learned and grown from the experience and I know better about where to look, etc, etc. But what can really be done about it? What about emulating memory protection? I don't know much about the 68000, but I would assume it has some ability to single step. A host program could load and simulate another program watching for bad memory references. It would have to examine the seglist to find the locations of data memory, and it would have to trap all AllocMem's to keep the list current. It would have to examine every instruction and test the location of any memory it refers to against its master list of valid memory locations. Valid memory areas could be kept in a sorted list and binary searched to test them, which could be fairly fast. The host program could patch AllocMem and keep a separate list of MEMF_PUBLIC memory areas to manage the case of data passed from one task to another. If the simulation ran even 5 or 10 percent of full speed, it could be an invaluable debugging tool. In my case, for example, I found a way to produce the failure reliably and quickly. If all else had failed, I could have run the memory protection emulator and spend a few minutes of a slow simulation run to reproduce the bug and find out what's happening. Since the host program is keeping track of resources to perform its function, it aught to be able to do a clean exit also. Well, there's the idea. Is it possible? And if possible, is it practical? And if practical, does anyone want to do it? :-) It's a little beyond what I'm up to at this point. I've seen such a thing on the Commodore 64 which doesn't have a hardware single step, so it should be at least theoretically possible on the Amiga. -- Stuart Ferguson (shf@well.UUCP) Action by HAVOC (shf@Solar.Stanford.EDU)