Skip to content
This repository has been archived by the owner on Dec 1, 2021. It is now read-only.

Wrong stacktrace lines #151

Open
Dirbaio opened this issue Feb 28, 2018 · 4 comments
Open

Wrong stacktrace lines #151

Dirbaio opened this issue Feb 28, 2018 · 4 comments

Comments

@Dirbaio
Copy link

Dirbaio commented Feb 28, 2018

go version go1.10 linux/amd64

The following snippet causes the stacktrace to point to the wrong source code line.

package main

import (
	"fmt"
	"runtime/debug"

	"github.com/pkg/errors"
)

type Bar struct {
	i int
}

type Foo struct {
	b *Bar
}

func main() {
	defer func() {
		if rvr := recover(); rvr != nil {
			fmt.Printf("pkg/errors stacktrace:\n %+v\n\n", errors.Errorf("panic: %+v", rvr))
			fmt.Printf("golang stacktrace:\n %s\n", debug.Stack())
		}
	}()

	slice := []*Foo{
		&Foo{},
		nil,
	}

	for i, f := range slice {
		fmt.Println("index", i)
		if f.b == nil {
			f.b = &Bar{}
		}
		fmt.Println(i, f.b.i)
	}
}

A nil pointer deref occurs on line if f.b == nil {.
The pkg/errors stacktrace points to the wrong line: for i, f := range slice { (2 lines above).
The golang stacktrace points to the correct line.

pkg/errors stacktrace:
 panic: runtime error: invalid memory address or nil pointer dereference
main.main.func1
	xxx/main.go:21
runtime.call32
	/usr/lib/go/src/runtime/asm_amd64.s:573
runtime.gopanic
	/usr/lib/go/src/runtime/panic.go:505
runtime.panicmem
	/usr/lib/go/src/runtime/panic.go:63
runtime.sigpanic
	/usr/lib/go/src/runtime/signal_unix.go:388
main.main
	xxx/main.go:31
runtime.main
	/usr/lib/go/src/runtime/proc.go:198
runtime.goexit
	/usr/lib/go/src/runtime/asm_amd64.s:2361

golang stacktrace:
 goroutine 1 [running]:
runtime/debug.Stack(0x4bba7f, 0x1d, 0xc420059d58)
	/usr/lib/go/src/runtime/debug/stack.go:24 +0xa7
main.main.func1()
	xxx/main.go:22 +0x105
panic(0x49f8c0, 0x52a380)
	/usr/lib/go/src/runtime/panic.go:505 +0x229
main.main()
	xxx/main.go:33 +0x1c8
@puellanivis
Copy link

The stack trace is generated at the line where the errors.Errorf is called.

So, this behavior is Working As Intended.

@Dirbaio
Copy link
Author

Dirbaio commented Feb 28, 2018

No, I'm referring to the stack frame where the nil pointer dereference is generated, not the one where I capture the stacktrace.

pkg/errors stacktrace:
[...]
main.main
	xxx/main.go:31  <========= INCORRECT LINE: for i, f := range slice {
[...]

golang stacktrace:
[...]
main.main()
	xxx/main.go:33 +0x1c8  <========= CORRECT LINE: if f.b == nil {
[...]

@puellanivis
Copy link

Ah, ok, I see what you’re saying now. Sorry. The 3 stack traces all kind of jammed together made this difficult to pull out right.

@puellanivis
Copy link

Yeah, this is definitely because of the change in the way the stack traces were supposed to be built introduced from https://github.com/golang/proposal/blob/master/design/19348-midstack-inlining.md

Specifically, turning off optimizations with go run -gclfags="-X" prints the correct lines.

$ go run -gcflags "-N"  test.go
index 0
0 0
index 1
pkg/errors stacktrace:
 panic: runtime error: invalid memory address or nil pointer dereference
main.main.func1
	/Users/snowgirl/Work/tmp/go/test.go:21
runtime.call32
	/usr/local/go/src/runtime/asm_amd64.s:573
runtime.gopanic
	/usr/local/go/src/runtime/panic.go:505
runtime.panicmem
	/usr/local/go/src/runtime/panic.go:63
runtime.sigpanic
	/usr/local/go/src/runtime/signal_unix.go:388
main.main
	/Users/snowgirl/Work/tmp/go/test.go:33
runtime.main
	/usr/local/go/src/runtime/proc.go:198
runtime.goexit
	/usr/local/go/src/runtime/asm_amd64.s:2361

golang stacktrace:
 goroutine 1 [running]:
runtime/debug.Stack(0x10c8e01, 0x1d, 0xc420047c40)
	/usr/local/go/src/runtime/debug/stack.go:24 +0xa7
main.main.func1()
	/Users/snowgirl/Work/tmp/go/test.go:22 +0x1e0
panic(0x10aba60, 0x113c3f0)
	/usr/local/go/src/runtime/panic.go:505 +0x229
main.main()
	/Users/snowgirl/Work/tmp/go/test.go:33 +0x273

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants