Skip to content
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: panic when calling runtime.Callers after div by zero on linux/arm #10486

Closed
inconshreveable opened this issue Apr 17, 2015 · 7 comments
Milestone

Comments

@inconshreveable
Copy link
Contributor

package main

import (
    "path/filepath"
    "runtime"
)

func divZero() int {
    defer func() {
        if p := recover(); p != nil {
            var pcs [512]uintptr
            runtime.Callers(2, pcs[:])
        }   
    }() 
    a, b := 1, 0
    return a / b
}

func main() {
    divZero()
    filepath.ToSlash(runtime.GOROOT())
}

Expected output: none, program should exit successfully

Observed output:

pi@raspberrypi ~ $ go run t.go
runtime: g1: leftover defer argp=0x1031b7a0 pc=0x10c3c
    defer 0x10336100 argp=0x1031b7a0 pc=0x10c3c
    defer 0x10336000 argp=0x1031b7c4 pc=0x1fde4
fatal error: traceback has leftover defers

runtime stack:
runtime.gothrow(0x87198, 0x1d)
    /usr/local/go/src/runtime/panic.go:503 +0x84
runtime.gentraceback(0x10cdc, 0x1031b734, 0x41cd4, 0x103000a0, 0x0, 0x0, 0x7fffffff, 0x7ec1e7b0, 0x7ec1e7b8, 0x0, ...)
    /usr/local/go/src/runtime/traceback.go:445 +0x6bc
copystack(0x103000a0, 0x1000)
    /usr/local/go/src/runtime/stack.c:623 +0xfc
runtime.newstack()
    /usr/local/go/src/runtime/stack.c:789 +0x444
runtime.morestack()
    /usr/local/go/src/runtime/asm_arm.s:319 +0x4c

goroutine 1 [stack growth]:
main.func·001()
    /Users/aes/t.go:9 fp=0x1031b734 sp=0x1031b734
runtime.call16(0x8bc64, 0x1033611c, 0x0, 0x0)
    /usr/local/go/src/runtime/asm_arm.s:406 +0x70 fp=0x1031b748 sp=0x1031b734
runtime.gopanic(0x74290, 0x1030a020)
    /usr/local/go/src/runtime/panic.go:387 +0x3b4 fp=0x1031b780 sp=0x1031b748
runtime.panicdivide()
    /usr/local/go/src/runtime/panic.go:24 +0x54 fp=0x1031b794 sp=0x1031b780
main.divZero(0x0)
    /Users/aes/t.go:16 +0x74 fp=0x1031b7a4 sp=0x1031b794
main.main()
    /Users/aes/t.go:20 +0x1c fp=0x1031b7c0 sp=0x1031b7a4
runtime.main()
    /usr/local/go/src/runtime/proc.go:63 +0x108 fp=0x1031b7e4 sp=0x1031b7c0
runtime.goexit()
    /usr/local/go/src/runtime/asm_arm.s:1322 +0x4 fp=0x1031b7e4 sp=0x1031b7e4

goroutine 2 [runnable]:
runtime.forcegchelper()
    /usr/local/go/src/runtime/proc.go:90
runtime.goexit()
    /usr/local/go/src/runtime/asm_arm.s:1322 +0x4

goroutine 3 [runnable]:
runtime.bgsweep()
    /usr/local/go/src/runtime/mgc0.go:82
runtime.goexit()
    /usr/local/go/src/runtime/asm_arm.s:1322 +0x4

goroutine 4 [runnable]:
runtime.runfinq()
    /usr/local/go/src/runtime/malloc.go:712
runtime.goexit()
    /usr/local/go/src/runtime/asm_arm.s:1322 +0x4

This is a minimal test case whittled down from a larger application.

Note the following:

  • I have only tested on Linux/ARM GOARM=6. The actual hardware platform tested on was a Raspberry Pi 2 Model B.
  • This problem manifests both from native compilation on linux/arm and darwin/amd64 -> linux/arm cross compilation.
  • Changing var pcs [512]uintptr to var pcs [256]uintptr results in successful execution.
  • Removing the call to filepath.ToSlash(runtime.GOROOT()) results in successful execution.
@inconshreveable inconshreveable changed the title Runtime panic on Linux ARM Linux/arm runtime panic when calling runtime.Callers after div by zero Apr 17, 2015
@randall77
Copy link
Contributor

Looks like somehow _div is not leaving the stack in a good state when cleaning up and calling panicdivide. I don't understand the arm assembly enough to understand how this is supposed to work. ARM guys?

@davecheney @minux

@randall77
Copy link
Contributor

BTW this is 1.4.2, not tip.

Just a thought, it looks like the _div callsite pushes 2 words before calling _div. I don't understand why it needs to do that. I made a change in 1.4 that removed a lot of these 2 (or for arm, 3) word pushes/pops for defers and go statements. Maybe traceback doesn't understand this 2-word pad? Maybe the pcsp map no longer contains the sp delta for this _div callsite?

Maybe we can just get rid of the 2-word push/pop? I don't see what its purpose is.

@minux
Copy link
Member

minux commented Apr 17, 2015 via email

@mikioh mikioh changed the title Linux/arm runtime panic when calling runtime.Callers after div by zero runtime: panic when calling runtime.Callers after div by zero on linux/arm Apr 17, 2015
@josharian
Copy link
Contributor

Related:

#6681

Here's a fix that Russ implemented and then rolled back:

b0db472

And the issue to revive that fix:

#6699

@ianlancetaylor ianlancetaylor added this to the Go1.5Maybe milestone Jun 3, 2015
@rsc
Copy link
Contributor

rsc commented Jul 21, 2015

I think we can bring back CL https://golang.org/cl/19810043.
They are not used from NOSPLIT code, and there is no longer C code,
and the Go compiler does the magic multiply on all systems.

Anyone want to try?

@rsc rsc self-assigned this Jul 30, 2015
@rsc
Copy link
Contributor

rsc commented Jul 30, 2015

I have this working. Will send out once current arm build breakage is gone.

rsc added a commit that referenced this issue Jul 30, 2015
We want to adjust the DIV calling convention to use m,
and usleep can be called without an m, so switch to a
multiplication by the reciprocal (and test).

Step toward a fix for #6699 and #10486.

Change-Id: Iccf76a18432d835e48ec64a2fa34a0e4d6d4b955
Reviewed-on: https://go-review.googlesource.com/12898
Reviewed-by: Ian Lance Taylor <iant@golang.org>
@gopherbot
Copy link
Contributor

CL https://golang.org/cl/12899 mentions this issue.

@rsc rsc closed this as completed in b2dfacf Jul 30, 2015
@mikioh mikioh modified the milestones: Go1.5, Go1.5Maybe Jul 31, 2015
@golang golang locked and limited conversation to collaborators Aug 5, 2016
@rsc rsc removed their assignment Jun 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

8 participants