|
Evaluation
|
The following is the problem. If you either add another
arg or move the trCopyTokens.getTrustThreshold() invocation
out of the sendCheckAuthorisation invocation, the bug dissappears.
Initially we use a temp (l3 below) as the pointer to byte array tknListHash.
then the JIT inlines the trCopyTokens.getTrustThreshold etal recursively.
In the process we spill a register (l3) and the value is overwritten.
However when we return to the 1st level of the JITPass2 code,
we have popped the stack back to the point where the code indicates
that the temp reg is still valid. So we pass the wrong data into
sendCheckAuthorisation.
at InstructionToDebit.sendCheckAuthorisation(JIT2t.java:72)
at InstructionToDebit.processMessage(Compiled Code)
at JIT2.main(Compiled Code)
36
37 sendCheckAuthorisation(myInt, tknListHash,
38 myLong,
39 myLong,
40 o1,
41 o2,
42 o3,
43 o4,
>>> 44 trCopyTokens.getTrustThreshold());
45
102 short getTrustThreshold() {
103 TokenWrapper tkn = get();
104 return(tkn.getTrustThreshold());
105 }
106 }
111 TokenWrapper() {
112 tkn = new TokenRec();
113 }
================================================================
---
< (fa03fd90) (e6062020) lduw [%i0 + 32], _%l3_
sets l3 as ptr for 54 getfield #33 <Field byte tknListHash[]>
(dbx6l) stopi at 0xfa03fd94
(dbx6l) x 0xfa03fd90/8i
dbx6l: warning: unknown language, 'ansic' assumed
0xfa03fd90: ld [%i0 + 0x20], %l3
0xfa03fd94: ldx [%i0 + 0x8], %g2
0xfa03fd98: srlx %g2, 32, %l5
0xfa03fd9c: or %g2, %g0, %l7
0xfa03fda0: ldx [%i0 + 0x8], %g2
0xfa03fda4: srlx %g2, 32, %i4
0xfa03fda8: or %g2, %g0, %i5
0xfa03fdac: ld [%i0 + 0x10], %l1
(dbx6l) print -f"%08x" $l3
$l3 = fb43d3d0
(dbx6l) x ($l3)/X
0xfb43d3d0: 0x00111800
< (fa03fe10) (80a04003) subcc %g1, %g3, %g0
< (fa03fe14) (32400016) bne,a,pn%icc,fa03fe6c
< (fa03fe18) (e627bfc0) stw _%l3_, [%fp - 64]
This is generated by spillParticularIntFromStack/stackUndo during inline of TokenWrapper.getTrustThreshold:
< (fa03fe1c) (e627bfc0) stw _%l3_, [%fp - 64]
< (fa03fe20) (e606e008) lduw [%i3 + 8], _%l3_
< (fa03fe24) (c404e000) lduw [ _%l3_ + 0], %g2
< (fa03fe28) (90100013) or %g0, _%l3_, %o0
BLAMO We have destroyed the value in l3...
xxxxx@xxxxx ( xxxxx@xxxxx ) stopped in (unknown) at 0xfa03fe2c
0xfa03fe2c: ld [%g2 + 0x68], %g3
(dbx6l) print -f"%08x" $l3
$l3 = fb440fd0
(dbx6l) print -f"%08x" *(int *)$l3
*((int *) $l3) = 002d2000
(dbx6l) x ($fp - 64)/X
0xffbee028: 0xfb43d3d0
(dbx6l) print -f"%08x" *(int *)($fp - 64)
*((int *) ($fp-64)) = fb43d3d0
(dbx6l) print -f"%08x" *(int *)(*(int *)($fp - 64))
*((int *) *((int *) ($fp-64))) = 00111800 <Field byte tknListHash[]>
< (fa03fe2c) (c600a068) lduw [%g2 + 104], %g3
< (fa03fe30) ( 3000000) sethi %hi(0x0), %g1
< (fa03fe34) (82006000) add %g1, 0, %g1
< (fa03fe38) (80a04003) subcc %g1, %g3, %g0
< (fa03fe3c) (32400007) bne,a,pn%icc,fa03fe58
< (fa03fe40) (c600a068) lduw [%g2 + 104], %g3
< (fa03fe44) (f627bfb0) stw %i3, [%fp - 80]
< (fa03fe48) (f627bfb4) stw %i3, [%fp - 76]
< (fa03fe4c) (f604e008) lduw [ _%l3_ + 8], %i3
(dbx6l) print -f"%08x" $l3
$l3 = fb440fd0
< (fa03fe98) (c4062000) lduw [%i0 + 0], %g2
< (fa03fe9c) (90100018) or %g0, %i0, %o0
< (fa03fea0) (f623a06c) stw %i3, [%sp + 108]
< (fa03fea4) (ec23a068) stw %l6, [%sp + 104]
< (fa03fea8) (e823a064) stw %l4, [%sp + 100]
< (fa03feac) (e423a060) stw %l2, [%sp + 96]
< (fa03feb0) (e223a05c) stw %l1, [%sp + 92]
< (fa03feb4) (9a174000) or %i5, %g0, %o5
< (fa03feb8) (98170000) or %i4, %g0, %o4
< (fa03febc) (9615c000) or %l7, %g0, %o3
< (fa03fec0) (94154000) or %l5, %g0, %o2
Here we load the pointer from the inline of
trCopyTokens.getTrustThreshold as our arg
ptr for getfield #33 <Field byte tknListHash[]> ooops..
< (fa03fec4) (9214c000) or _%l3_, %g0, %o1
And we're busted...
So why did we do it ?
xxxxx@xxxxx ( xxxxx@xxxxx ) stopped in JITInlineMethodMb at line 8157 in file "JITPass2.c"
8157 popUndo(&subjit, height);
_________________________
(dbx6l) print (int)(jit)->m->currentSparcStack[1].reg
(int ) jit->m->currentSparcStack[1].reg = -1
(dbx6l) next
xxxxx@xxxxx ( xxxxx@xxxxx ) stopped in JITInlineMethodMb at line 8158 in file "JITPass2.c"
8158 debugOnly(checkAndDestroySavedState(jit, *height, sav);)
(dbx6l) print (int)(jit)->m->currentSparcStack[1].reg
(int ) jit->m->currentSparcStack[1].reg = 19
xxxxx@xxxxx ( xxxxx@xxxxx ) stopped in stackUndo_work at line 724 in file "JIT_md.c"
724 DynArrayOf_nm(StateUndoRec,addhi)(jit->mu->undoStack, ur);
stackUndo_work:
ur.tag = UNDO_STACK
ur.index = 1
ur.u.stk = {
type = 'A'
is_constant = '\0'
constant_value = 0
vn = 80
reg = 19U
}
(dbx6l) where
current thread: xxxxx@xxxxx
=>[1] stackUndo_work(jit = 0xffbed1dc, n = 1), line 724 in "JIT_md.c"
[2] stackUndo(jit = 0xffbed1dc, n = 1), line 60 in "JIT_undo.h"
[3] spillParticularIntFromStack(jit = 0xffbed1dc, height = 10, reg = 19), line
388 in "JITSparcGenerate.c"
[4] spillSomeIntFromStack(jit = 0xffbed1dc, height = 10, low = 10), line 351 i
n "JITSparcGenerate.c"
[5] getOutRegIntWork(jit = 0xffbed1dc, height = 10, low = 10, useORegs = FALSE
), line 703 in "JITSparcGenerate.c"
[6] getOutRegInt(jit = 0xffbed1dc, height = 10, low = 10), line 559 in "JITSpa
rcGenerate.h"
[7] emitPushField(jit = 0xffbed1dc, sig = 0x2c53e8 "LTokenRec;", base_reg = 27
U, offset = 8, ind_reg = 0, align = FALSE, vn1 = 97, vn2 = -1, height = 10, dreg
1 = -1, dreg2 = -1), line 6361 in "JITPass2.c"
[8] emitGetField(jit = 0xffbed1dc, fieldIndex = 8U, height = 10, pc = 5, dreg1
= -1, dreg2 = -1), line 6188 in "JITPass2.c"
[9] JITSecondPass(jit = 0xffbed1dc, heightPtr = 0xffbed544), line 2578 in "JIT
Pass2.c"
[10] JITCompile_md(jit = 0xffbed1dc, height = 0xffbed544), line 427 in "JIT_md
.c"
[11] JITInlineMethodMb(jit = 0xffbed7d4, mb = 0x2d09e8, pc = 10, ck = CALL_VIR
TUAL, height = 0xffbed544, notUsed = (nil)), line 8137 in "JITPass2.c"
[12] JITInlineMethodNdx(jit = 0xffbed7d4, methodIndex = 12U, pc = 10, ck = CAL
L_VIRTUAL, height = 0xffbed544), line 153 in "JITInlineRegion.c"
[13] JITSecondPass(jit = 0xffbed7d4, heightPtr = 0xffbedb3c), line 2602 in "JI
TPass2.c"
[14] JITCompile_md(jit = 0xffbed7d4, height = 0xffbedb3c), line 427 in "JIT_md
.c"
[15] JITInlineMethodMb(jit = 0xffbede48, mb = 0x2c39a0, pc = 85, ck = CALL_VIR
TUAL, height = 0xffbedb3c, notUsed = (nil)), line 8137 in "JITPass2.c"
[16] JITInlineMethodNdx(jit = 0xffbede48, methodIndex = 24U, pc = 85, ck = CAL
L_VIRTUAL, height = 0xffbedb3c), line 153 in "JITInlineRegion.c"
[17] JITSecondPass(jit = 0xffbede48, heightPtr = 0xffbedc54), line 2602 in "JI
TPass2.c"
[18] JITCompile_md(jit = 0xffbede48, height = 0xffbedc54), line 427 in "JIT_md
.c"
[19] jitCompileMethod(mb = 0x2c0c08, jit = 0xffbede48), line 650 in "JIT.c"
[20] compileMethodLocked(mb = 0x2c0c08, recompile = FALSE), line 2134 in "comp
iler.c"
[21] compileOrStopCounting(mb = 0x2c0c08), line 153 in "classruntime.c"
[22] incInvocationCountConsistent(ee = 0x38258, mb = 0x2c0c08), line 251 in "c
lassruntime.c"
[23] incInvocationCountInconsistent(ee = 0x38258, mb = 0x2c0c08), line 260 in
"classruntime.c"
[24] countingInvoker(objectOrNull = 0xffbee240, mb = 0x2c0c08, ee = 0x38258),
line 266 in "classruntime.c"
[25] executeJava(initial_pc = 0xff23c9ac "\xb7", ee = 0x38258), line 1407 in "
executeJavaLoop.h"
[26] runJavaMethod(ee = 0x38258, current_frame = 0x3860c, transition_mb = 0xff
bee3b0, terseRetType = 0x24df1 "\n"), line 1927 in "interpreter.c"
[27] JITCallbackInterpreter(ee = 0x38258, mb = 0x2c0c08, args = 0xffbee568 "")
, line 1811 in "compiler.c"
[28] JITInterpreterStub(0xfb43d3a8, 0x2c5c00, 0xfb8, 0xfec5a398, 0x0, 0x0), at
0xfeec2264
[29] 0xfa0390a0(0x4, 0xfb43d3a8, 0xfb8, 0xfec5a398, 0x0, 0x0), at 0xfa03909f
[30] JITInvokeCompiledMethod(0x385f4, 0x2c3dc0, 0x38258, 0x11fdc0, 0xffbee698,
0x0), at 0xff24d448
[31] invokeCompiledMethod(objectOrNull = 0xffbee778, mb = 0x2c3dc0, ee = 0x382
58), line 474 in "classruntime.c"
[32] executeJava(initial_pc = 0xff23c9a4 "\xb8", ee = 0x38258), line 1407 in "
executeJavaLoop.h"
[33] runJavaMethod(ee = 0x38258, current_frame = 0x385e0, transition_mb = 0xff
bee920, terseRetType = 0xd180a "\n"), line 1927 in "interpreter.c"
[34] jni_Invoke(env = 0x38560, self = 0x385d4, methodID = 0x2c3dc0, pushArgume
nts = 0xfeb79878 = &`libjvm_g.so`jni.c`jni_PushArgumentsVararg(JNIEnv *env, stru
ct Method *mb, struct javaframe *current_frame, JNI_PushArgsType a), args = UNIO
N, isStatic = 1, isVirtual = 0, isJVMCall = 0), line 744 in "jni.c"
[35] jni_CallStaticVoidMethod(env = 0x38560, clazz = 0x385d4, methodID = 0x2c3
dc0, ...), line 1907 in "jni.c"
[36] main(argc = 0, argv = 0xffbeebcc), line 300 in "java.c"
(dbx6l)
xxxxx@xxxxx 2001-03-20
After lots of digging the problem is that the alteration of register state
in inner virtual inlined functions is not propagated to the outer state.
I tried various fixes that had repercussions, but Alex Garthwaite and
Dave Detlefs provided a simple fix. Its in the suggested fix field.
xxxxx@xxxxx 2001-11-01
|