New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runtime: TestAbort fails with "panic: BAD: recovered from abort" on windows/arm #29050

Closed
alexbrainman opened this Issue Dec 1, 2018 · 5 comments

Comments

Projects
None yet
4 participants
@alexbrainman
Copy link
Member

alexbrainman commented Dec 1, 2018

windows/arm builder fails

https://build.golang.org/log/dcf35b2e42a6d30ca1d7604ce79d5c50e8071b04

on runtime.TestAbort test with

--- FAIL: TestAbort (0.11s)
    crash_test.go:95: testprog Abort exit status: exit status 2
    crash_test.go:652: output contains BAD:
        panic: runtime error: invalid memory address or nil pointer dereference [recovered]
        	panic: BAD: recovered from abort
        [signal 0xc0000005 code=0x0 addr=0x0 pc=0x3322ac]

runtime.TestAbort runs Abort function

//go:linkname runtimeAbort runtime.abort
func runtimeAbort()
func Abort() {
defer func() {
recover()
panic("BAD: recovered from abort")
}()
runtimeAbort()
println("BAD: after abort")
}

As far as I can tell, process containing Abort is suppose to exit at line 18. But windows/arm seems to continue to line 19.

runtime.abort is just a INT $3 on amd64, but on arm it looks like this

go/src/runtime/asm_arm.s

Lines 799 to 801 in f70bd91

TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0
MOVW $0, R0
MOVW (R0), R1

Perhaps this code hits exception handler on Windows, where things recover. If that is so, what code should we put into runtime.abort, so it does not recover?

@jordanrh1 please help.

Thank you.

Alex

@cherrymui

This comment has been minimized.

Copy link
Contributor

cherrymui commented Dec 1, 2018

On UNIX systems, this just triggers SIGSEGV and the runtime's isAbort function checks the faulting PC.

func isAbortPC(pc uintptr) bool {
        return pc == funcPC(abort) || ((GOARCH == "arm" || GOARCH == "arm64") && pc == funcPC(abort)+sys.PCQuantum)
}

The assembly code seems ok to me, matching the runtime's check.

On Windows, function isgoexception in signal_windows.go:

        // In the case of an abort, the exception IP is one byte after
        // the INT3 (this differs from UNIX OSes).
        if isAbortPC(r.ip() - 1) {
                // Never turn abort into a panic.
                return false
        }

I'm not familiar with Windows, but I suspect the r.ip() - 1 may not work on ARM. Does r.ip() point to the next instruction after the faulting instruction? In this case it probably should be r.ip() - sys.PCQuantum.

@gopherbot

This comment has been minimized.

Copy link

gopherbot commented Dec 4, 2018

Change https://golang.org/cl/152357 mentions this issue: runtime: correct isAbortPC check in isgoexception

@alexbrainman

This comment has been minimized.

Copy link
Member

alexbrainman commented Dec 4, 2018

In this case it probably should be r.ip() - sys.PCQuantum

Thank you for finger pointing. Hopefully, I did not misinterpret your explanation https://go-review.googlesource.com/c/go/+/152357

Alex

@jordanrh1

This comment has been minimized.

Copy link
Contributor

jordanrh1 commented Dec 5, 2018

Looks like the fix worked:

testprog.exe Abort
Exception 0xc0000005 0x0 0x0 0x26238c
PC=0x26238c

runtime.abort()
/home/jordanrh/go/src/runtime/asm_arm.s:801 +0x4 fp=0x11461f48 sp=0x11461f48 pc=
0x26238c
main.Abort()
/home/jordanrh/go/src/runtime/testdata/testprog/abort.go:21 +0x30 fp=0x11461f54
sp=0x11461f48 pc=0x2c4f6c
main.main()
/home/jordanrh/go/src/runtime/testdata/testprog/main.go:34 +0x158 fp=0x11461fc4
sp=0x11461f54 pc=0x2c886c
runtime.main()
/home/jordanrh/go/src/runtime/proc.go:200 +0x1d4 fp=0x11461fe4 sp=0x11461fc4 pc=
0x23ce3c
runtime.goexit()
/home/jordanrh/go/src/runtime/asm_arm.s:868 +0x4 fp=0x11461fe4 sp=0x11461fe4 pc=
0x2623ec
r0   0x0
r1   0x0
r2   0x11417380
r3   0x300c40
r4   0x114080e0
r5   0x0
r6   0x1141733c
r7   0x1141733c
r8   0x3
r9   0x8
r10  0x114080e0
r11  0x3ba100
r12  0x1
sp   0x11461f48
lr   0x2c4f6c
pc   0x26238c
cpsr 0x600f0010

Before the fix:

testprog.exe Abort
panic: runtime error: invalid memory address or nil pointer dereference [recover
ed]
panic: BAD: recovered from abort
[signal 0xc0000005 code=0x0 addr=0x0 pc=0xd3236c]

goroutine 1 [running]:
main.Abort.func1()
/home/jordanrh/go/src/runtime/testdata/testprog/abort.go:19 +0x30
panic(0xdb3690, 0xe77cd0)
/home/jordanrh/go/src/runtime/panic.go:513 +0x194
main.Abort()
/home/jordanrh/go/src/runtime/testdata/testprog/abort.go:21 +0x30
main.main()
/home/jordanrh/go/src/runtime/testdata/testprog/main.go:34 +0x158
@alexbrainman

This comment has been minimized.

Copy link
Member

alexbrainman commented Dec 5, 2018

Looks like the fix worked:

Thanks for checking. I will wait for codereview on https://go-review.googlesource.com/c/go/+/152357 now.

Alex

@gopherbot gopherbot closed this in 9be01c2 Dec 5, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment