Skip to content

Instantly share code, notes, and snippets.

@bithavoc
Created November 17, 2014 16:31
Show Gist options
  • Save bithavoc/2213f9bf519b766160a8 to your computer and use it in GitHub Desktop.
Save bithavoc/2213f9bf519b766160a8 to your computer and use it in GitHub Desktop.
capturing stack traces in go
/opt/boxen/homebrew/Cellar/go/1.3.3/libexec/src/pkg/runtime/proc.c:1445 runtime - goexit
/opt/boxen/homebrew/Cellar/go/1.3.3/libexec/src/pkg/runtime/proc.c:247 runtime - main
/Users/ride/src/going/src/github.com/ride/teste/main.go:67 main - main
/Users/ride/src/going/src/github.com/ride/teste/main.go:72 main - level1
/Users/ride/src/going/src/github.com/ride/teste/main.go:76 main - level2
/Users/ride/src/going/src/github.com/ride/teste/main.go:80 main - level3
/opt/boxen/homebrew/Cellar/go/1.3.3/libexec/src/pkg/runtime/panic.c:248 runtime - panic
Error recovered: shit went wrong
package main
import (
"fmt"
"runtime"
"strings"
)
type StackFrame struct {
File string
Line int
Func string
Package string
}
func stack(startFrame int) []StackFrame {
stack := []StackFrame{}
for i := startFrame; ; i++ {
pc, file, line, ok := runtime.Caller(i)
if !ok {
break
}
packageName, funcName := packageFuncName(pc)
stack = append(stack, StackFrame{
File: file,
Line: line,
Func: funcName,
Package: packageName,
})
}
return stack
}
func packageFuncName(pc uintptr) (string, string) {
f := runtime.FuncForPC(pc)
if f == nil {
return "", ""
}
packageName := ""
funcName := f.Name()
if ind := strings.LastIndex(funcName, "/"); ind > 0 {
packageName += funcName[:ind+1]
funcName = funcName[ind+1:]
}
if ind := strings.Index(funcName, "."); ind > 0 {
packageName += funcName[:ind]
funcName = funcName[ind+1:]
}
return packageName, funcName
}
func main() {
defer func() {
if e := recover(); e != nil {
st := stack(2)
for x := len(st) - 1; x >= 0; x -= 1 {
s := st[x]
fmt.Printf("%s:%d %s - %s\n", s.File, s.Line, s.Package, s.Func)
}
fmt.Printf("Error recovered: %v\n", e)
}
}()
level1()
fmt.Printf("hello world")
}
func level1() {
level2()
}
func level2() {
level3()
}
func level3() {
panic(fmt.Errorf("shit went wrong"))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment