liblink: in newproc1, fn is in the wrong place on the stack
4ad opened this issue · 1 comments
4ad commented
Very strange, programs crash with:
: xgene:1; 7.out
fatal error: go of nil func value
runtime stack:
runtime.throw(0x7, 0x8)
/home/aram/go/src/runtime/panic.go:508 +0xf0
: xgene:1;
So we attach gdb:
runtime.newproc1 (fn=0xb5d50 <runtime.g0>, argp=0x7ffffff488 "", narg=-3233,
nret=127, callerpc=10, ~r5=0x86ae0)
at /home/aram/go/src/runtime/proc1.go:1943
1943 if fn == nil {
(gdb) disas
Dump of assembler code for function runtime.newproc1:
0x0000000000042b70 <+0>: str x30, [sp,#-160]!
0x0000000000042b74 <+4>: mov x7, #0x0 // #0
0x0000000000042b78 <+8>: bl 0x663b0 <runtime.getg>
0x0000000000042b7c <+12>: ldr x7, [sp,#8]
0x0000000000042b80 <+16>: str x7, [sp,#104]
0x0000000000042b84 <+20>: ldr x7, [sp,#104]
0x0000000000042b88 <+24>: str x7, [sp,#120]
=> 0x0000000000042b8c <+28>: ldr x7, [sp,#168]
0x0000000000042b90 <+32>: mov x8, #0x0 // #0
0x0000000000042b94 <+36>: cmp x7, x8
0x0000000000042b98 <+40>: b.ne 0x42bcc <runtime.newproc1+92>
0x0000000000042b9c <+44>: ldr x7, 0x43160 <runtime.newproc1+1520>
0x0000000000042ba0 <+48>: mov x7, x7
0x0000000000042ba4 <+52>: mov x8, x7
0x0000000000042ba8 <+56>: add x7, sp, #0x8
0x0000000000042bac <+60>: mov x7, x7
0x0000000000042bb0 <+64>: sub x8, x8, #0x8
0x0000000000042bb4 <+68>: sub x7, x7, #0x8
0x0000000000042bb8 <+72>: ldr x9, [x8,#8]!
0x0000000000042bbc <+76>: str x9, [x7,#8]!
0x0000000000042bc0 <+80>: ldr x9, [x8,#8]!
0x0000000000042bc4 <+84>: str x9, [x7,#8]!
0x0000000000042bc8 <+88>: bl 0x38850 <runtime.throw>
(gdb) si
0x0000000000042b90 1943 if fn == nil {
(gdb) p $x7
$3 = 0
(gdb) x/xg $sp+168
0x7ffffff598: 0x0000000000000000
(gdb) x/xg $sp+8
0x7ffffff4f8: 0x00000000000b5d50
(gdb) p fn
$4 = (struct runtime.funcval *) 0xb5d50 <runtime.g0>
(gdb)
Very strange, gdb says fn is not nil. If we look at the code closely, we see fn is at 168(R31); the code looks correct. But there's nothing there, instead, fn is at 8(R31). How did it get there, and more importantly, hoes does gdb know it's there?
(gdb) p &fn
$5 = (struct runtime.funcval **) 0x7ffffff4f8
Yep, gdb knows fn is at 8(R31).
I have no idea what is going on, but I observe that the delta between expected stack offset and real stack offset is exactly equal with the frame size (160 bytes).
4ad commented
Michael did all the job, thanks.