ksitze@nmsu.edu (360) (08/17/89)
In article: <alex@rata.vuw.ac.nz's message of 14 Aug 89 22:03:12 GMT> Alex Heatly is complaining about random crashes during LSP compilation or execution of a project. In answer, there are several possible causes behind the mentioned problems. Most probable cause: You are allocating a handle (pointer) in one section of your program, maybe use it for a bit and put it in storage. Some other piece of your program takes that stored handle, uses it for a while and after finished with it, deallocates the handle. If the handle is not overwritten with a nil after being deallocated, it still points to the released master pointer. Now, if your program tries to use this handle elsewhere (and even checks for nil handles) it will use an invalid handle and write out into memory Apple-knows-where. Enough times and you could shot code or data out from just about anything, including your LSP environment. Other (related) problems that you may have and not know of... Take the program below: program SampleCode; type myTmpHdl = ^myTmpPtr; myTmpPtr = ^myTmpRec; myTmpRec = record TEHdl : TEHandle; data : Handle; dLen : longint; { notice I'm being 32-bit clean? } end; procedure ReleaseTmp( myTmp : myTmpHdl ); begin with myTmp^^ do begin TEDispose( TEHdl ); DisposHandle( data ); end; DisposHandle( Handle(myTmp) ); myTmp = nil; end; function AllocateTmp : myTmpHdl; var dst, view : Rect; myTmp : myTmpHdl; port : GrafPtr; begin myTmp = myTmpHdl(NewHandle(sizeof(myTmpRec))); if myTmp <> nil then begin GetPort(port); dst = port^.portRect; view = port^.portRect; myTmp^^.TEHdl = TENew(dst, view); { Proper code should even check } myTmp^^.data = NewHandle(0); { these values here. } myTmp^^.dLen = 0; end; end; var myTHdl : myTmpHdl; begin {....initialization....} myTHdl = AllocateTmp; {....Do some stuff with myTHdl here....} if (some condition) then ReleaseTmp(myTHdl); {....Do something else for a while....} if myTHdl<>nil then begin {....use the data in myTHdl here....} end; end. Now, nothing seems to be wrong here does it (besides some syntax)? Sure, everything will work just fine if the if statement evaluates to 'FALSE'. But what happens when it is 'TRUE'? 'myTHdl' is deallocated in ReleaseTmp, ReleaseTmp sets it to nil and everything is hunky-dory right? Wrong. ReleaseTmp sets the local myTmp to nil but since myTmp is not a variable parameter, myTHdl is left with the old value. Easily fixed by inserting the word 'var' before myTmp in ReleaseTmp. This trick is especially bad when ReleaseTmp is declared in the interface part of a unit as you tend to not check the original procedure declaration. This one has caught me several times, it seems so simple that no one would ever do it, but it happens. With a program that had a similar problem to the one above, I had problems that sounded much like those described in the article by Alex. Other possible problems: Assuming that calls such as 'NewHandle', 'NewPtr', 'GetResource' etc always return valid handles/pointers. Leaving the original values in just deallocated handles/pointers as this makes it difficult to track down handle/pointer illegal references. Always writing nil into these variables makes life so much easier. Leaving values on the stack (this is hard to do in LSP but possible if you directly manipulate the stack) Not checking potential nil handles/pointers when they're used. Not necessary usually if you check the return values from NewHandle and such but should be done if the handle/pointer could possibly be deallocated before your code uses it. Any of those listed in TN212 (The joy of being 32-bit clean). Hope that something in here is useful to someone out there... -Kelesi -- +--------------------------------------------------------------------+ | From the Macintosh of: Kevin L. Sitze. This is ME: ksitze@NMSU.edu | +------------------------------------------------------+-------------+ | The difference between intelligence and stupidity is | Is this | | that intelligence has a limit. -- anonymous | better? | +------------------------------------------------------+-------------+