rouaix@inria.inria.fr (Francois Rouaix) (07/03/89)
Hello dear techies, I have a doubt on the possibility that UnLoadSeg() might Wait() somewhere. Does anybody knows for sure ? The reason I ask this is the following: A program detaches itself from CLI (ya know, hacking the SegList), runs, and at the end, unloads itself with UnLoadSeg(). The very end of the code (ASM) looks like callsys Forbid * setup UnLoadSeg callsys UnLoadSeg moveq.l 0,d0 rts And occasionally, I get a Guru (4)... The only explanation I have yet is thatUnLoadSeg() waits, memory freed is reallocated, the last two lines get trashed, and boom. Am I wrong ? I could think of replacing the JSR to UnLoadSeg by a JMP, therefore using the RTS of the routine, but since this bug appears quite randomly, I'd like to be certain of its reason. Thanx for any help --Francois -- *- Francois Rouaix // We are all prisonners here * *- rouaix@inria.inria.fr \X/ of our own device * *- SYSOP of Sgt. Flam's Lonely Amigas Club. (33) (1) 39-55-84-59 (Videotext) * Disclaimer: Opinions expressed are my own, not those of my employer.
451061@UOTTAWA.BITNET (Valentin Pepelea) (07/04/89)
Francois Rouaix <rouaix@inria.inria.fr> in message <1364@inria.inria.fr> writes > I have a doubt on the possibility that UnLoadSeg() might > Wait() somewhere. Does anybody knows for sure ? There is no reason why UnLoadSeg would want to call Wait(). > A program detaches itself from CLI (ya know, hacking the > SegList), runs, and at the end, unloads itself with UnLoadSeg(). > The very end of the code (ASM) looks like > > callsys Forbid > * setup UnLoadSeg > callsys UnLoadSeg > moveq.l 0,d0 > rts What happened to "callsys Permit"? Jette dans l'oubliette? > And occasionally, I get a Guru (4)... No wonder. "Merde alors!" Eh? > The only explanation I have yet is that UnLoadSeg() waits, > memory freed is reallocated, the last two lines get trashed, and boom. > Am I wrong ? I think there is a logic mistake here. Does UnLoadSeg() also remove the task associated with it? If so, then the Forbid() is immediately obsoleted, the memory associated with the task gets freed, but somehow you still insist running code within a task that does not exist anymore. I am surprised your code runs some of the time, it should fail instantly every time. > I could think of replacing the JSR to UnLoadSeg by a JMP, therefore > using the RTS of the routine, but since this bug appears quite randomly, > I'd like to be certain of its reason. Perhaps you should UnLoadSeg only other segments, never your-self. > Thanx for any help > --Francois For what it's worth... Valentin _________________________________________________________________________ "An operating system without Name: Valentin Pepelea virtual memory is an operating Phonet: (613) 231-7476 (New!) system without virtue." Bitnet: 451061@Uottawa.bitnet Usenet: Use cunyvm.cuny.edu gate - Ancient Inca Proverb Planet: 451061@acadvm1.UOttawa.CA
jesup@cbmvax.UUCP (Randell Jesup) (07/04/89)
In article <1364@inria.inria.fr> rouaix@inria.inria.fr (Francois Rouaix) writes: >I have a doubt on the possibility that UnLoadSeg() might >Wait() somewhere. Does anybody knows for sure ? >The reason I ask this is the following: >A program detaches itself from CLI (ya know, hacking the >SegList), runs, and at the end, unloads itself with UnLoadSeg(). >The very end of the code (ASM) looks like >callsys Forbid >* setup UnLoadSeg >callsys UnLoadSeg >moveq.l 0,d0 >rts > >And occasionally, I get a Guru (4)... UnLoadSeg() will not Wait() UNLESS the seglist is overlaid, in which case it must Close() the program file. I would look for something trashing a seglist pointer, some reference in a system structure to memory in your seglist (interrupt structures, nodes on a public list, whatever), writing past the end of some data area (unlikely), or passing the wrong seglist pointer to UnLoadSeg (must be a BPTR to the first segment's next segment BPTR - the value returned by LoadSeg()). -- Randell Jesup, Keeper of AmigaDos, Commodore Engineering. {uunet|rutgers}!cbmvax!jesup, jesup@cbmvax.cbm.commodore.com BIX: rjesup Common phrase heard at Amiga Devcon '89: "It's in there!"
jesup@cbmvax.UUCP (Randell Jesup) (07/07/89)
In article <8907032258.AA16367@jade.berkeley.edu> 451061@UOTTAWA.BITNET (Valentin Pepelea) writes: >Francois Rouaix <rouaix@inria.inria.fr> in message <1364@inria.inria.fr> writes > >> I have a doubt on the possibility that UnLoadSeg() might >> Wait() somewhere. Does anybody knows for sure ? > >There is no reason why UnLoadSeg would want to call Wait(). For overlaid modules it will Wait(). >> callsys Forbid >> * setup UnLoadSeg >> callsys UnLoadSeg >> moveq.l 0,d0 >> rts > >What happened to "callsys Permit"? Jette dans l'oubliette? Not needed: he's exiting his task with that rts, so his task will go away, and the Forbid() dies at that time also. >I think there is a logic mistake here. Does UnLoadSeg() also remove the task >associated with it? If so, then the Forbid() is immediately obsoleted, the >memory associated with the task gets freed, but somehow you still insist >running code within a task that does not exist anymore. I am surprised your >code runs some of the time, it should fail instantly every time. UnLoadSeg() has no knowlege of tasks (think about it). However, it is safe to reference memory that has been freed under a Forbid() so long as it isn't the first N (where N=8) bytes of the freed hunk. For seglists, the first 8 bytes are the segment size and next segment BPTR, so the code/ data isn't touched. Once you explicitly or implicitly break the Forbid (via Permit or Wait()), the memory can be trashed. -- Randell Jesup, Keeper of AmigaDos, Commodore Engineering. {uunet|rutgers}!cbmvax!jesup, jesup@cbmvax.cbm.commodore.com BIX: rjesup Common phrase heard at Amiga Devcon '89: "It's in there!"
rouaix@inria.inria.fr (Francois Rouaix) (07/10/89)
In article <7225@cbmvax.UUCP>, jesup@cbmvax.UUCP (Randell Jesup) writes: > >Francois Rouaix <rouaix@inria.inria.fr> in message <1364@inria.inria.fr> writes > >> I have a doubt on the possibility that UnLoadSeg() might > >> Wait() somewhere. Does anybody knows for sure ? > For overlaid modules it will Wait(). > >> callsys Forbid > >> * setup UnLoadSeg > >> callsys UnLoadSeg > >> moveq.l 0,d0 > >> rts > UnLoadSeg() has no knowlege of tasks (think about it). However, it > is safe to reference memory that has been freed under a Forbid() so long > as it isn't the first N (where N=8) bytes of the freed hunk. For seglists, > the first 8 bytes are the segment size and next segment BPTR, so the code/ > data isn't touched. Once you explicitly or implicitly break the Forbid > (via Permit or Wait()), the memory can be trashed. We (Jean-Michel Forgeas and I) think we finally found the reason of this guru. It has to do with nested Forbid()/Permit(). Forbid() and Permit() work by incrementing and decrementing a counter (TDNestCount (sp?)) which tells the scheduler if the task may be switched or not. Now if you write too much Permit() (ie more than Forbid()) in the code, then the value in the counter might get negative. A later Forbid() will then have NO effect. This is what happen in the code above (there is one superfluous Permit() in the init code of the task). Therefore, the callsys Forbid() does not prevent the process from being switched, although UnLoadSeg() does not Wait(). In some cases, the memory where the code resides is reallocated and trashed, invoking a 4 guru. Since this was so much pain to debug, I'll make a wish for 1.4 ! I want that Permit() checks the counter so that it can never get negative (one MOVE is enough...). (Note how it is similar to some Lisps that allow superfluous closing parenthesis) Much thanx to all people who helped in this battle against the guru, especially to Randell Jesup and Peter da Silva --Francois-- *- Francois Rouaix // We are all prisoners here, * *- rouaix@inria.inria.fr \X/ of our own device * *- SYSOP of Sgt. Flam's Lonely Amigas Club. (33) (1) 39-55-84-59 (Videotext) * Disclaimer: Opinions expressed are my own, not those of my employer.
janhen@kunivv1.sci.kun.nl (Jan Hendrikx) (07/14/89)
In article <7225@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes: | UnLoadSeg() has no knowlege of tasks (think about it). However, it |is safe to reference memory that has been freed under a Forbid() so long |as it isn't the first N (where N=8) bytes of the freed hunk. For seglists, |the first 8 bytes are the segment size and next segment BPTR, so the code/ |data isn't touched. Once you explicitly or implicitly break the Forbid |(via Permit or Wait()), the memory can be trashed. This is, of course, very handy for those programs that UnLoadSeg() themselves. And I have written at least two of those. |Randell Jesup, Keeper of AmigaDos, Commodore Engineering. |{uunet|rutgers}!cbmvax!jesup, jesup@cbmvax.cbm.commodore.com BIX: rjesup |Common phrase heard at Amiga Devcon '89: "It's in there!" -Olaf Seibert