FAQ
Though strange, I just determined that this change is responsible for a
test failure of Go on Darwin/ARM.

Without this change, fixedbugs/bug348.go could get this traceback (I
just printed out pc, file, line from bug348.go):
8488 /var/mobile/go/src/bug348.go 28
59468 /var/mobile/go/src/pkg/runtime/panic.c 134
61048 /var/mobile/go/src/pkg/runtime/panic.c 384
87056 /var/mobile/go/src/pkg/runtime/thread_darwin.c 431
8428 /var/mobile/go/src/bug348.go 47
8232 /var/mobile/go/src/bug348.go 17

With this change, the traceback becomes:
8472 /var/mobile/go/src/bug348.go 28
59364 /var/mobile/go/src/pkg/runtime/panic.c 134
60944 /var/mobile/go/src/pkg/runtime/panic.c 384
86952 /var/mobile/go/src/pkg/runtime/thread_darwin.c 431
8412 /var/mobile/go/src/bug348.go 47
8224 /var/mobile/go/src/bug348.go 15
BUG: bug348: panic at /var/mobile/go/src/bug348.go:15 in main.f

Remy, do you have any ideas why this change could affect the pc->line
number mapping?
Thank you.

The weird thing is that it doesn't affect Linux/ARM, only Darwin/ARM.
(The port is here: http://bitbucket.org/minux/goios/, it doesn't make
changes to 5g)


https://codereview.appspot.com/6710043/

Search Discussions

  • Russ Cox at Dec 18, 2012 at 11:53 pm
  • Minux at Dec 19, 2012 at 12:04 am

    On Wednesday, December 19, 2012, Russ Cox wrote:

    Are you sync'ed past
    http://code.google.com/p/go/source/detail?r=0f491e663a44?
    yes. i just merged default branch of today, noticed the problem,
    and backtracked to this cl.

    5g -S shows the line number is correct with this cl, but the only factor
    changed is just 5g,
    so i'm pretty confused.
  • Russ Cox at Dec 19, 2012 at 12:16 am
    Can you post the 5g -S output? I don't have a working 5g here.
  • Minux at Dec 19, 2012 at 12:24 am

    On Wednesday, December 19, 2012, minux wrote:
    On Wednesday, December 19, 2012, Russ Cox wrote:

    Are you sync'ed past
    http://code.google.com/p/go/source/detail?r=0f491e663a44?
    yes. i just merged default branch of today, noticed the problem,
    and backtracked to this cl.

    5g -S shows the line number is correct with this cl, but the only factor
    changed is just 5g,
    so i'm pretty confused.
    the pc -> line number conversion code seems to have a off-by-one error
    only on darwin/arm.

    bad.s
    --- prog list "f" ---
    0000 (bug348.go:14) TEXT f+0(SB),$36-0
    0001 (bug348.go:15) MOVW $0,R0
    0002 (bug348.go:17) MOVW 0(R0),R1. // segfault happens here
    0003 (bug348.go:17) MOVW R1,autotmp_0000+-16(SP)
    0004 (bug348.go:17) MOVW 4(R0),R1
    0005 (bug348.go:17) MOVW R1,autotmp_0000+-12(SP)
    0006 (bug348.go:17) MOVW $0,R2
    0007 (bug348.go:17) MOVW R2,autotmp_0001+-8(SP)

    good.s:
    --- prog list "f" ---
    0000 (bug348.go:14) TEXT f+0(SB),$36-0
    0001 (bug348.go:15) MOVW $0,R2
    0002 (bug348.go:17) MOVW R2,R1
    0003 (bug348.go:17) MOVW $autotmp_0000+-16(SP),R0
    0004 (bug348.go:17) MOVW.P 4(R1),R2. // sigfault happens here
    0005 (bug348.go:17) MOVW.P R2,4(R0)
    0006 (bug348.go:17) MOVW.P 4(R1),R2
    0007 (bug348.go:17) MOVW.P R2,4(R0)

    i can confirm the code generated for linux/arm is the same, so this
    cl only exposes the error in runtime.
    however, i don't remember i touched pcln code.....
  • Russ Cox at Dec 19, 2012 at 12:40 am
    Normally the return PC for a call leads to the instruction after the
    call, so the traceback code moves backward one instruction, in order
    to print the line of the call instead of the line of the code that
    follows the call. A signal like this is made to look like a call
    returning to the signaling instruction, so that if it did get handled
    and the signal handler returned, the instruction would be given a
    second chance to execute. If the traceback code shows the line of the
    previous instruction instead of the line of the actual instruction,
    that would explain the behavior you are seeing.

    runtime/traceback_arm.c says

    if(runtime·showframe(f)) {
    // Print during crash.
    // main(0x1, 0x2, 0x3)
    //
    /home/rsc/go/src/runtime/x.go:23 +0xf
    tracepc = pc; // back up to CALL
    instruction for funcline.
    if(n > 0 && pc > f->entry && !waspanic)
    tracepc -= sizeof(uintptr);

    It sounds like maybe in your case waspanic is 0 here but should be 1.

    waspanic is set during the previous frame, as waspanic = f->entry ==
    (uintptr)runtime·sigpanic. That's the thread_darwin.c:431 frame have
    on your stack, but it is strange that there is a bug348.go:47 frame
    between thread_darwin.c:431 and bug348.go:15/17. Why does the panic
    appear to have happened in main.main called from main.f, instead of
    the other way around?

    That is:
    8488 /var/mobile/go/src/bug348.go 28
    59468 /var/mobile/go/src/pkg/runtime/panic.c 134
    61048 /var/mobile/go/src/pkg/runtime/panic.c 384
    87056 /var/mobile/go/src/pkg/runtime/thread_darwin.c 431
    8428 /var/mobile/go/src/bug348.go 47 <<<
    8232 /var/mobile/go/src/bug348.go 17 <<<

    The two <<< lines seem backward to me. If you can arrange for them to
    end up in the right order then I think everything will start working.
    I expect the bug is in runtime.sighandler in your signal_darwin_arm.c.

    Russ
  • Minux at Dec 19, 2012 at 1:18 am
    thank you for your detailed explanation.
    On Wednesday, December 19, 2012, Russ Cox wrote:

    Normally the return PC for a call leads to the instruction after the
    call, so the traceback code moves backward one instruction, in order
    to print the line of the call instead of the line of the code that
    follows the call. A signal like this is made to look like a call
    returning to the signaling instruction, so that if it did get handled
    and the signal handler returned, the instruction would be given a
    second chance to execute. If the traceback code shows the line of the
    previous instruction instead of the line of the actual instruction,
    that would explain the behavior you are seeing.

    runtime/traceback_arm.c says

    if(runtime·showframe(f)) {
    // Print during crash.
    // main(0x1, 0x2, 0x3)
    //
    /home/rsc/go/src/runtime/x.go:23 +0xf
    tracepc = pc; // back up to CALL
    instruction for funcline.
    if(n > 0 && pc > f->entry && !waspanic)
    tracepc -= sizeof(uintptr);

    It sounds like maybe in your case waspanic is 0 here but should be 1.

    waspanic is set during the previous frame, as waspanic = f->entry ==
    (uintptr)runtime·sigpanic. That's the thread_darwin.c:431 frame have
    on your stack, but it is strange that there is a bug348.go:47 frame
    between thread_darwin.c:431 and bug348.go:15/17. Why does the panic
    appear to have happened in main.main called from main.f, instead of
    the other way around?

    That is:
    8488 /var/mobile/go/src/bug348.go 28
    59468 /var/mobile/go/src/pkg/runtime/panic.c 134
    61048 /var/mobile/go/src/pkg/runtime/panic.c 384
    87056 /var/mobile/go/src/pkg/runtime/thread_darwin.c 431
    8428 /var/mobile/go/src/bug348.go 47 <<<
    8232 /var/mobile/go/src/bug348.go 17 <<<

    The two <<< lines seem backward to me. If you can arrange for them to
    end up in the right order then I think everything will start working.
    I expect the bug is in runtime.sighandler in your signal_darwin_arm.c.
    i figure out the stupid error i made in the signal handler.
    thank you russ for pointing me directly to the error.
    thank you remy for exposing the error.

    i will make a test to catch this kind of error in the future.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-dev @
categoriesgo
postedDec 18, '12 at 11:32p
activeDec 19, '12 at 1:18a
posts7
users2
websitegolang.org

2 users in discussion

Minux: 4 posts Russ Cox: 3 posts

People

Translate

site design / logo © 2021 Grokbase