[futurebasic] Re: [FB] FB^3 Threading Puzzle (continuing saga)

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : October 1999 : Group Archive : Group : All Groups

From: Robert Purves <robert.purves@...>
Date: Fri, 1 Oct 1999 19:22:57 +1200
>>What happens if you remove the run-time-using statements from FN ThProc?

>>LOCAL FN ThProc(tmp&)
>> CALL DEBUGSTR("Hello from ThProc")
>>END FN

Somewhat edited, this is what Steve got when he tried. I've put in some
comments as to the cause of this crash.

Step (into)
 THPROC..
 +00004 * mflr r0            ; FN ThProc clearing its throat
 +00008 stw r0,0x0008(SP)    ;  ditto
 +0000C stmw r13,-0x0060(SP) ;  ditto
 +00010 stwu SP,-0x00A8(SP)  ;  ditto
 +00014 addi r13,SP,0x0020   ;  ditto
 +00018 stw r3,0x0020(r13)   ; save the value of parameter tmp&
 +0001C li r31,0x0584
 +00020 lwz r3,-0x0008(RTOC)
 +00024 add r3,r31,r3
 +00028 mr r31,r3
 +0002C mr r3,r31
 +00030 bl 'FCOD 03E9 2F60 FB^3.PPC'+200B8 ;
 'FCOD 03E9 2F60 FB^3.PPC'   ; <--- the DEBUGSTR part of the FB^3 runtime
 +200B8 lwz r12,0x0064(RTOC) ; <--- bad value from 512(RTOC) to r12
 +200BC stw RTOC,0x0014(SP)
 +200C0 lwz r0,0x0000(r12)   ; <--- bad value from 0(r12) to r0
 +200C4 lwz RTOC,0x0004(r12)
 +200C8 mtctr r0             ; <--- bad value from r0 to ctr
 +200CC bctr                 ; <--- branch to bad place
PowerPC illegal instruction at FFC10000 _AA6A+00DFE

By now, people are starting to suspect that my inept ideas spring not just
from ignorance but from malice too. But no!  I forgot that in PPC, CALL
DEBUGSTR and CALL DEBUGGER actually use the FB^3 RunTime (there are no A
traps in PPC). Since we believe the machine state to be wrong on arriving
at FN ThProc, the above crash would have been predicted by someone less
forgetful. Such a lot to unlearn when you move to the native PPC world.

What can we salvage from the debacle? Well, by reading _backwards_ in the
disassembly log, we can deduce that the Thread Manager (which called this
FB^3 function) didn't set up the value of RTOC (that's a fancy name for
register r2) in the way that FB^3's runtime needs, so that the runtime
ended by doing a branch (bctr) to a crazy place. Expect a gruesome
discussion of "cross-RTOC glue" code --- that's what may have fallen over
in this whole problem.

In the meantime, Steve, try:-

"THREADENTRY"
LOCAL FN ThProc(tmp&)
` dc.l 0x7C00012A ' illegal instruction gives reliable access to MacsBug
END FN

WINDOW 1
FN ThProc(9999) ' call ThProc to see deliberate crash, and read RTOC value
fn StartThread ' let the Thread Manager call ThProc;  read RTOC value
...
do
until fn button
END

Here I've removed all the content of FN ThProc, inserting a cheapskate but
safe and comprehensible way of getting into MacsBug. When you crash here
the first and second times, write down the value of RTOC. To continue
execution, tell MacsBug  pc=pc+4 (to step over the illegal), then command-G
to go. Maybe, just maybe, this will work (using "work" in the programmer's
sense of "crash only where its supposed to").

The first value of RTOC from the above exercise will be the one that the FB
runtime expects. The second value will be what the Threasd Manager
supplied. Place your bets, laze and gemmun, rien ne va plus,  will they be
the same or will they be different?

>68K works _with_ the ENTERPROC statements and ThreadEntryProc& =
>LINE("THREADENTRY"). I didn't try it with LINE("THREADENTRY")+ 6 and
>without ENTERPROC. Should I?

With ENTERPROC, LINE seems to returns a pointer to the correct place, i.e.
past the mysterious prefatory branch instructions. We only got into that +4
business to allow the ENTERPROC to be removed in PPC. I fear confusion from
tinkering with what already works in 68K.

Robert