Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ test-deps:

TEST_INTEGRATION_BINARY_DIRS := tracer processmanager/ebpf support interpreter/golabels/integrationtests

pprof-execs: pprof_1_23 pprof_1_24 pprof_1_24_cgo
pprof-execs: pprof_1_23 pprof_1_24 pprof_1_24_cgo pprof_1_24_cgo_stripped

pprof_1_23:
CGO_ENABLED=0 GOTOOLCHAIN=go1.23.7 go test -C ./interpreter/golabels/integrationtests/pprof -c -trimpath -tags $(GO_TAGS),nocgo,integration -o ./../$@
Expand All @@ -133,6 +133,9 @@ pprof_1_24:
pprof_1_24_cgo:
CGO_ENABLED=1 GOTOOLCHAIN=go1.24.6 go test -C ./interpreter/golabels/integrationtests/pprof -c -ldflags '-extldflags "-static"' -trimpath -tags $(GO_TAGS),withcgo,integration -o ./../$@

pprof_1_24_cgo_stripped:
CGO_ENABLED=1 GOTOOLCHAIN=go1.24.6 go test -C ./interpreter/golabels/integrationtests/pprof -c -trimpath -ldflags='-s -w' -tags $(GO_TAGS),withcgo,integration -o ./../$@

integration-test-binaries: generate ebpf pprof-execs
$(foreach test_name, $(TEST_INTEGRATION_BINARY_DIRS), \
(go test -ldflags='-extldflags=-static' -trimpath -c \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ var (

//go:embed pprof_1_24_cgo
pprof_1_24_cgo []byte

//go:embed pprof_1_24_cgo_stripped
pprof_1_24_cgo_stripped []byte
)

type mockIntervals struct{}
Expand All @@ -58,9 +61,10 @@ func Test_Golabels(t *testing.T) {
tests := map[string]struct {
bin []byte
}{
"pprof_1_23": {bin: pprof_1_23},
"pprof_1_24": {bin: pprof_1_24},
"pprof_1_24_cgo": {bin: pprof_1_24_cgo},
"pprof_1_23": {bin: pprof_1_23},
"pprof_1_24": {bin: pprof_1_24},
"pprof_1_24_cgo": {bin: pprof_1_24_cgo},
"pprof_1_24_cgo_stripped": {bin: pprof_1_24_cgo_stripped},
}

for name, tc := range tests {
Expand Down
34 changes: 24 additions & 10 deletions interpreter/golabels/tls_amd64.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package golabels // import "go.opentelemetry.io/ebpf-profiler/interpreter/golabe
import (
log "github.com/sirupsen/logrus"
"go.opentelemetry.io/ebpf-profiler/libpf/pfelf"
"go.opentelemetry.io/ebpf-profiler/nativeunwind/elfunwindinfo"
"golang.org/x/arch/x86/x86asm"
)

Expand All @@ -16,19 +17,32 @@ import (
// may be dynamic relocating going on so just read it from a known
// symbol if possible.
func extractTLSGOffset(f *pfelf.File) (int32, error) {
syms, err := f.ReadSymbols()
if err != nil {
return 0, err
var funcAddr int64

if syms, err := f.ReadSymbols(); err != nil {
gopclntab, err := elfunwindinfo.NewGopclntab(f)
if err != nil {
return 0, err
}
defer gopclntab.Close()
funcPc, err := gopclntab.LookupFunction("runtime.stackcheck")
if err != nil {
return 0, err
}
funcAddr = int64(funcPc)
} else {
sym, err := syms.LookupSymbol("runtime.stackcheck.abi0")
if err != nil {
// Binary must be stripped, hope default is correct and warn.
log.Warnf("Failed to find stackcheck symbol, Go labels might not work: %v", err)
return -8, err
}
funcAddr = int64(sym.Address)
}

// Dump of assembler code for function runtime.stackcheck:
// 0x0000000000470080 <+0>: mov %fs:0xfffffffffffffff8,%rax
sym, err := syms.LookupSymbol("runtime.stackcheck.abi0")
if err != nil {
// Binary must be stripped, hope default is correct and warn.
log.Warnf("Failed to find stackcheck symbol, Go labels might not work: %v", err)
return -8, nil
}
b, err := f.VirtualMemory(int64(sym.Address), 10, 10)
b, err := f.VirtualMemory(funcAddr, 10, 10)
if err != nil {
return 0, err
}
Expand Down
35 changes: 24 additions & 11 deletions interpreter/golabels/tls_arm64.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package golabels // import "go.opentelemetry.io/ebpf-profiler/interpreter/golabe
import (
log "github.com/sirupsen/logrus"
"go.opentelemetry.io/ebpf-profiler/libpf/pfelf"
"go.opentelemetry.io/ebpf-profiler/nativeunwind/elfunwindinfo"
"golang.org/x/arch/arm64/arm64asm"
)

Expand All @@ -27,18 +28,30 @@ func extractTLSGOffset(f *pfelf.File) (int32, error) {
return 0, err
}

syms, err := f.ReadSymbols()
if err != nil {
return 0, err
}
sym, err := syms.LookupSymbol("runtime.load_g.abi0")
if err != nil {
// Binary must be stripped, just warn and return 0 and we'll rely on r28.
log.Warnf("Failed to find load_g symbol in cgo enabled Go binary "+
"label collection in CGO frames may not work: %v", err)
return 0, nil
var funcAddr int64
if syms, err := f.ReadSymbols(); err != nil {
gopclntab, err := elfunwindinfo.NewGopclntab(f)
if err != nil {
return 0, err
}
defer gopclntab.Close()
funcPc, err := gopclntab.LookupFunction("runtime.load_g")
if err != nil {
return 0, err
}
funcAddr = int64(funcPc)
} else {
sym, err := syms.LookupSymbol("runtime.load_g.abi0")
if err != nil {
// Binary must be stripped, just warn and return 0 and we'll rely on r28.
log.Warnf("Failed to find load_g symbol in cgo enabled Go binary "+
"label collection in CGO frames may not work: %v", err)
return 0, nil
}
funcAddr = int64(sym.Address)
}
b, err := f.VirtualMemory(int64(sym.Address), 32, 32)

b, err := f.VirtualMemory(funcAddr, 32, 32)
if err != nil {
return 0, err
}
Expand Down
12 changes: 12 additions & 0 deletions nativeunwind/elfunwindinfo/elfgopclntab.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ package elfunwindinfo // import "go.opentelemetry.io/ebpf-profiler/nativeunwind/
import (
"bytes"
"debug/elf"
"errors"
"fmt"
"go/version"
"io"
Expand Down Expand Up @@ -498,6 +499,17 @@ func (g *Gopclntab) mapPcval(offs int32, startPc, pc uint) (int32, bool) {
return p.val, true
}

func (g *Gopclntab) LookupFunction(funcName string) (uintptr, error) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a duplicate to PCForSymbol() in #728

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry about that, I did not see you already opened a PR for this. I will close this one...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no worry :) it was just pushed earlier this morning.

for i := 0; i < g.numFuncs; i++ {
mapPc, funcOff := g.getFuncMapEntry(i)
funcPc, fun := g.getFunc(funcOff)
if fun != nil && mapPc == funcPc && getString(g.funcnametab, int(fun.nameOff)) == funcName {
return funcPc, nil
}
}
return 0, errors.New("function not found")
}

// Symbolize returns the file, line and function information for given PC
func (g *Gopclntab) Symbolize(pc uintptr) (sourceFile string, line uint, funcName string) {
index := sort.Search(g.numFuncs, func(i int) bool {
Expand Down