freeman@spar.SPAR.SLB.COM (Jay Freeman) (06/14/88)
I have a possible bug in MPW C 2.0.2, that is sufficiently subtle that I am having great difficulty localizing it well enough to report neatly; I seek advice on how best to do so. I am running on a Mac II with finder 6.0, system 4.2, compiling C with the "-g" flag set but with no other compile options. In a large, messy function (which I will call "foo") I have a declaration like this: long myLong; In "foo", "myLong" is initialized to a value. Subsequently, "foo" calls "bar", and "bar" calls "SFGetFile". "myLong" is entirely local to "foo"; before I started putting in "printf" statements to debug, neither "myLong" nor its address were passed to any other function or assigned to any extern or static variable; in particular they are NOT passed to "bar". Something was wrong with "foo", and in due course I found that the value of "myLong" changed mysteriously during the call of "bar". That is, I "printf"ed out "myLong" immediately before and immediately after the call of "bar", and got different values. On fiddling around inside "bar", I found that commenting out the call to "SFGetFile" made the problem go away. I don't know much about the internals of "SFGetFile", so I couldn't follow that lead. So I restored the call of "SFGetFile". Gosh, I thought, maybe I am messing up the toolbox-calling syntax somehow, so that something is scrambling the stack. To test for that possibility, I bracketed the declaration of "myLong" with dummy declarations of big arrays on the stack, like this: char dummy1[ 500 ]; long myLong; char dummy2[ 500 ]; Notwithstanding these arrays, the mysterious change in "myLong" persisted. That's pretty convincing evidence that the culprit is not run-of-the-mill stack-scrambling. So I took out the dummy declarations. Gosh, I thought, maybe there's a problem with register saves and restores. I know that MPW C tries hard to put automatics in register, but there is no easy way to find out which ones. First I changed the declaration of "myLong" to look like this: register long myLong: There was no change in the bug. Perhaps "myLong" was being put into a register anyway. So I restored the declaration of "myLong" to its original form, and added to "foo" a call to a bogus function: bogus( &myLong ); where "bogus" is a void function that ignores all its arguments and immediately returns: void bogus() {;} The idea here is that the MPW C manual indicates that taking the address of an automatic will prevent the compiler from automagically making it a "register" variable. WITH THE CALL TO "bogus" INSTALLED, THE BUG WENT AWAY! I now have a strong feeling that the code generated for the original version of "foo" put "myLong" in a register that was not saved across the call to "bar", and that "SFGetFile" uses that register. But I am not at all sure how to proceed to localize the problem further. "foo" is about 50-100 lines of code with about 10 locals; "bar" is about half as complex. Both of these functions are in turn pretty well out to the leaves of the call graph of a program that presently has something like 20,000 lines of C. The only debugger/disassembler I have is Macsbug, I have in essence never used it at all, and I am not particularly a 68XXX assembly-language programmer anyway. If there is indeed a problem with register saves, it would be a very serious compiler bug, well worth tracking down and reporting. (On the other hand, if I am indeed making some unrecognized stupid C programming error, I will feel very seriously foolish.) Does anyone on the net -- in particular, any Apple net-watcher -- have any suggestions as to what I should do next in order to localize and report the bug. I'm not asking for a work-around, the business with "bogus" already provides that. I'd just like to nail this one so it will get fixed in the future. -- Jay Freeman <canonical disclaimer; these are my opinions only>
gz@spt.entity.com (Gail Zacharias) (06/14/88)
In article <1215@spar.SPAR.SLB.COM> freeman@spar.UUCP (Jay Freeman) writes: >I have a possible bug in MPW C 2.0.2, that is sufficiently subtle that I am >having great difficulty localizing it well enough to report neatly; I seek >advice on how best to do so. > .... So I restored the declaration of "myLong" to its original >form, and added to "foo" a call to a bogus function: > bogus( &myLong ); >WITH THE CALL TO "bogus" INSTALLED, THE BUG WENT AWAY! Sounds like you've localized it. Now just disassemble (i.e. dumpobj) "foo" both with and without the call to "bogus" and take a good look at the code generated. (I won't even mention the relevance of this kind of situation to a certain other discussion taking place in this group...) -- gz@entity.com ...!mit-eddie!spt!gz Now let's all repeat the non-conformist oath.
earleh@eleazar.dartmouth.edu (Earle R. Horton) (06/14/88)
In article <1215@spar.SPAR.SLB.COM> freeman@spar.UUCP (Jay Freeman) writes: > >I now have a strong feeling that the code generated for the original version >of "foo" put "myLong" in a register that was not saved across the call to >"bar", and that "SFGetFile" uses that register. This is a wild guess, but do you perchance have an INIT named "QuickFolder" or something in your system folder? I ran into exactly this problem, and finally found out QuickFolder was using D2, and not restoring it. This is a general problem with Pascal on the Mac: Pascal functions and procedures do not save exactly the same registers as C expects, or as the ToolBox does in many cases. I believe the problem with QuickFolder was that it had a Pascal procedure in it which was patching itself into SFxxxFile somewhere, and the Pascal compiler was not saving the same regs as the Package routine was. This is not the fault of the Pascal compiler, either, since how can it possibly know that it is generating code which will be put in a patch? Another possibility (Heaven forbid!) is that the INIT was written in assembly, and the author simply didn't save the correct registers. I don't think this is a problem with MPW C, I really think you have a defective INIT. I call SFGetFile() all the time from MPW C functions which have scads of auto variables, and never had any problem except for the QuickFolder thing. ********************************************************************* *Earle R. Horton, H.B. 8000, Dartmouth College, Hanover, NH 03755 * *********************************************************************
freeman@spar.SPAR.SLB.COM (Jay Freeman) (06/16/88)
I am Jay Freeman, the original poster of the bug report. In article <8886@dartvax.Dartmouth.EDU> earleh@eleazar.dartmouth.edu (Earle R. Horton) writes: >This is a wild guess, but do you perchance have an INIT named >"QuickFolder" or something in your system folder? > > [technical discussion follows] > >********************************************************************* >*Earle R. Horton, H.B. 8000, Dartmouth College, Hanover, NH 03755 * >********************************************************************* Thanks, Earle, you were right. I was using "QuickFolder". Removing it made the suspicious code run correctly in its original, un-work-arounded form. I take back all those nasty thoughts I was beginning to have about MPW C. (Who knows, perhaps I will have need of them in the future ..) Sheesh -- with bugs like this around, why are people worrying about viruses? -- Jay Freeman <canonical disclaimer: these words are my personal opinions>