Skip to content

Commit

Permalink
Add GSYM support.
Browse files Browse the repository at this point in the history
  • Loading branch information
sfc-gh-sgiesecke committed May 12, 2021
1 parent 070c956 commit 4d86455
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 16 deletions.
66 changes: 50 additions & 16 deletions internal/binutils/binutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,12 @@ type binrep struct {
objdump string
objdumpFound bool
isLLVMObjdump bool
llvmGsymUtil string
llvmGsymUtilFound bool

// if fast, perform symbolization using nm (symbol names only),
// instead of file-line detail from the slower addr2line.
// TODO update the comment and handling depending on whether llvm-gsymutil is as fast as nm
fast bool
}

Expand Down Expand Up @@ -98,7 +101,7 @@ func (bu *Binutils) update(fn func(r *binrep)) {
// String returns string representation of the binutils state for debug logging.
func (bu *Binutils) String() string {
r := bu.get()
var llvmSymbolizer, addr2line, nm, objdump string
var llvmSymbolizer, addr2line, nm, objdump, llvmGsymUtil string
if r.llvmSymbolizerFound {
llvmSymbolizer = r.llvmSymbolizer
}
Expand All @@ -111,13 +114,17 @@ func (bu *Binutils) String() string {
if r.objdumpFound {
objdump = r.objdump
}
return fmt.Sprintf("llvm-symbolizer=%q addr2line=%q nm=%q objdump=%q fast=%t",
llvmSymbolizer, addr2line, nm, objdump, r.fast)
if r.llvmGsymUtilFound {
llvmGsymUtil = r.llvmGsymUtil
}
return fmt.Sprintf("llvm-symbolizer=%q addr2line=%q nm=%q objdump=%q llvmGsymUtil=%q fast=%t",
llvmSymbolizer, addr2line, nm, objdump, llvmGsymUtil, r.fast)
}

// SetFastSymbolization sets a toggle that makes binutils use fast
// symbolization (using nm), which is much faster than addr2line but
// provides only symbol name information (no file/line).
// TODO update the comment and handling depending on whether llvm-gsymutil is as fast as nm
func (bu *Binutils) SetFastSymbolization(fast bool) {
bu.update(func(r *binrep) { r.fast = fast })
}
Expand Down Expand Up @@ -150,6 +157,13 @@ func initTools(b *binrep, config string) {
// not need to differentiate them.
b.nm, b.nmFound = chooseExe([]string{"llvm-nm", "nm"}, []string{"gnm"}, append(paths["nm"], defaultPath...))
b.objdump, b.objdumpFound, b.isLLVMObjdump = findObjdump(append(paths["objdump"], defaultPath...))
b.llvmGsymUtil, b.llvmGsymUtilFound = chooseExe([]string{"llvm-gsymutil"}, []string{}, append(paths["llvm-gsymutil"], defaultPath...))

if !b.llvmGsymUtilFound {
fmt.Println("llvm-gsymutil not found")

os.Exit(3)
}
}

// findObjdump finds and returns path to preferred objdump binary.
Expand Down Expand Up @@ -690,6 +704,7 @@ type fileAddr2Line struct {
file
addr2liner *addr2Liner
llvmSymbolizer *llvmSymbolizer
llvmGsymUtil *llvmGsymUtil
isData bool
}

Expand All @@ -699,6 +714,10 @@ func (f *fileAddr2Line) SourceLine(addr uint64) ([]plugin.Frame, error) {
return nil, f.baseErr
}
f.once.Do(f.init)
// TODO only use this if we have a matching gsym file!
if f.llvmGsymUtil != nil {
return f.llvmGsymUtil.addrInfo(addr)
}
if f.llvmSymbolizer != nil {
return f.llvmSymbolizer.addrInfo(addr)
}
Expand All @@ -709,26 +728,41 @@ func (f *fileAddr2Line) SourceLine(addr uint64) ([]plugin.Frame, error) {
}

func (f *fileAddr2Line) init() {
if llvmSymbolizer, err := newLLVMSymbolizer(f.b.llvmSymbolizer, f.name, f.base, f.isData); err == nil {
f.llvmSymbolizer = llvmSymbolizer
return
if llvmGsymUtil, err := newLLVMGsymUtil(f.b.llvmGsymUtil, f.name, f.base, f.isData); err == nil {
f.llvmGsymUtil = llvmGsymUtil
} else {

fmt.Println("newLLVMGsymUtil failed")

os.Exit(3)
}

if addr2liner, err := newAddr2Liner(f.b.addr2line, f.name, f.base); err == nil {
f.addr2liner = addr2liner
// TODO commented out for testing
/*
if llvmSymbolizer, err := newLLVMSymbolizer(f.b.llvmSymbolizer, f.name, f.base, f.isData); err == nil {
f.llvmSymbolizer = llvmSymbolizer
return
}
if addr2liner, err := newAddr2Liner(f.b.addr2line, f.name, f.base); err == nil {
f.addr2liner = addr2liner
// When addr2line encounters some gcc compiled binaries, it
// drops interesting parts of names in anonymous namespaces.
// Fallback to NM for better function names.
// This seems to have been fixed in binutils 2.26 though, see
// https://sourceware.org/bugzilla/show_bug.cgi?id=17541
if nm, err := newAddr2LinerNM(f.b.nm, f.name, f.base); err == nil {
f.addr2liner.nm = nm
// When addr2line encounters some gcc compiled binaries, it
// drops interesting parts of names in anonymous namespaces.
// Fallback to NM for better function names.
// This seems to have been fixed in binutils 2.26 though, see
// https://sourceware.org/bugzilla/show_bug.cgi?id=17541
if nm, err := newAddr2LinerNM(f.b.nm, f.name, f.base); err == nil {
f.addr2liner.nm = nm
}
}
}
*/
}

func (f *fileAddr2Line) Close() error {
if f.llvmGsymUtil != nil {
f.llvmGsymUtil = nil
}
if f.llvmSymbolizer != nil {
f.llvmSymbolizer.rw.close()
f.llvmSymbolizer = nil
Expand Down
5 changes: 5 additions & 0 deletions internal/symbolizer/symbolizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,11 @@ func doLocalSymbolize(prof *profile.Profile, fast, force bool, obj plugin.ObjToo

stack, err := segment.SourceLine(l.Address)
if err != nil || len(stack) == 0 {

if err != nil {
fmt.Println(err.Error())
}

// No answers from addr2line.
continue
}
Expand Down

0 comments on commit 4d86455

Please sign in to comment.