From 1f4c6f0691e12f1b7bed3f859352cc62e61e01ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Geisend=C3=B6rfer?= Date: Tue, 30 Mar 2021 14:51:41 +0200 Subject: [PATCH] wip --- examples/pclnttab/darwin.go | 23 ++++++++++++++++ examples/pclnttab/go.mod | 3 +++ examples/pclnttab/linux.go | 23 ++++++++++++++++ examples/pclnttab/main.go | 54 +++++++++++++++++++++++++++++++++++++ 4 files changed, 103 insertions(+) create mode 100644 examples/pclnttab/darwin.go create mode 100644 examples/pclnttab/go.mod create mode 100644 examples/pclnttab/linux.go create mode 100644 examples/pclnttab/main.go diff --git a/examples/pclnttab/darwin.go b/examples/pclnttab/darwin.go new file mode 100644 index 0000000..b8896db --- /dev/null +++ b/examples/pclnttab/darwin.go @@ -0,0 +1,23 @@ +//+build darwin + +package main + +import ( + "debug/macho" + "errors" + "fmt" + "os" +) + +func gopclntab() ([]byte, error) { + file, err := macho.Open(os.Args[0]) + if err != nil { + return nil, fmt.Errorf("elf.Open: %w", err) + } + for _, s := range file.Sections { + if s.Name == "__gopclntab" { + return s.Data() + } + } + return nil, errors.New("could not find .gopclntab") +} diff --git a/examples/pclnttab/go.mod b/examples/pclnttab/go.mod new file mode 100644 index 0000000..0f9144f --- /dev/null +++ b/examples/pclnttab/go.mod @@ -0,0 +1,3 @@ +module github.com/felixge/go-profiler-notes/examples/pclnttab + +go 1.16 diff --git a/examples/pclnttab/linux.go b/examples/pclnttab/linux.go new file mode 100644 index 0000000..6fd16d0 --- /dev/null +++ b/examples/pclnttab/linux.go @@ -0,0 +1,23 @@ +//+build linux + +package main + +import ( + "debug/elf" + "errors" + "fmt" + "os" +) + +func gopclntab() ([]byte, error) { + file, err := elf.Open(os.Args[0]) + if err != nil { + return nil, fmt.Errorf("elf.Open: %w", err) + } + for _, s := range file.Sections { + if s.Name == ".gopclntab" { + return s.Data() + } + } + return nil, errors.New("could not find .gopclntab") +} diff --git a/examples/pclnttab/main.go b/examples/pclnttab/main.go new file mode 100644 index 0000000..60db0fe --- /dev/null +++ b/examples/pclnttab/main.go @@ -0,0 +1,54 @@ +package main + +import ( + "debug/gosym" + "fmt" + "os" + "runtime" +) + +func main() { + if err := run(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +func run() error { + data, err := gopclntab() + if err != nil { + return fmt.Errorf("gopclntab: %w", err) + } + return debugSymtab(data) +} + +type StackTrace struct { + Frames []StackFrame +} + +type StackFrame struct { + PC int + Function string + File string + Line int +} + +func callers() []uintptr { + pcs := make([]uintptr, 32) + n := runtime.Callers(2, pcs) + pcs = pcs[0:n] + return pcs +} + +func debugSymtab(gopclntab []byte) error { + table, err := gosym.NewTable(nil, gosym.NewLineTable(gopclntab, 0)) + if err != nil { + return fmt.Errorf("gosym.NewTable: %w", err) + } + + for _, pc := range callers() { + file, line, fn := table.PCToLine(uint64(pc)) + fmt.Printf("%s() %s:%d\n", fn.Name, file, line) + } + return nil +}