Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ $(error Unsupported architecture: $(TARGET_ARCH))
endif

export TARGET_ARCH
export CGO_ENABLED = 1
export CGO_ENABLED = 0
export GOARCH = $(TARGET_ARCH)
export CC = $(ARCH_PREFIX)-linux-gnu-gcc
export OBJCOPY = $(ARCH_PREFIX)-linux-gnu-objcopy
Expand Down Expand Up @@ -103,7 +103,7 @@ vanity-import-fix: $(PORTO)
@porto --include-internal -w .

test: generate ebpf test-deps
go test $(GO_FLAGS) -tags $(GO_TAGS) ./...
CGO_ENABLED=1 go test $(GO_FLAGS) -tags $(GO_TAGS) ./...
Comment thread
fabled marked this conversation as resolved.

# This target isn't called from CI, it doesn't work for cross compile (ie TARGET_ARCH=arm64 on
# amd64) and the CI kernel tests run them already. Useful for local testing.
Expand All @@ -130,7 +130,7 @@ support/golbls_1_24.test: ./interpreter/golabels/test/main.go
CGO_ENABLED=0 GOTOOLCHAIN=go1.24.1 go build -tags $(GO_TAGS),nocgo -o $@ $<

support/golbls_cgo.test: ./interpreter/golabels/test/main-cgo.go
GOTOOLCHAIN=go1.24.1 go build -ldflags '-extldflags "-static"' -tags $(GO_TAGS),usecgo -o $@ $<
CGO_ENABLED=1 GOTOOLCHAIN=go1.24.1 go build -ldflags '-extldflags "-static"' -tags $(GO_TAGS),usecgo -o $@ $<

integration-test-binaries: generate ebpf rust-components support/golbls_1_23.test support/golbls_1_24.test support/golbls_cgo.test
$(foreach test_name, $(TEST_INTEGRATION_BINARY_DIRS), \
Expand Down
8 changes: 3 additions & 5 deletions interpreter/golabels/golabels.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,12 @@ import (
"go.opentelemetry.io/ebpf-profiler/interpreter"
"go.opentelemetry.io/ebpf-profiler/libpf"
"go.opentelemetry.io/ebpf-profiler/remotememory"
"go.opentelemetry.io/ebpf-profiler/support"
)

// #include "../../support/ebpf/types.h"
import "C"

type data struct {
goVersion string
offsets C.GoLabelsOffsets
offsets support.GoLabelsOffsets
interpreter.InstanceStubs
}

Expand Down Expand Up @@ -64,7 +62,7 @@ func Loader(_ interpreter.EbpfHandler, info *interpreter.LoaderInfo) (interprete
if err != nil {
return nil, fmt.Errorf("failed to extract TLS offset: %w", err)
}
offsets.tls_offset = C.s32(tlsOffset)
offsets.Tls_offset = tlsOffset

return &data{
goVersion: goVersion,
Expand Down
34 changes: 17 additions & 17 deletions interpreter/golabels/runtime_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,49 +3,49 @@

package golabels // import "go.opentelemetry.io/ebpf-profiler/interpreter/golabels"

// #include "../../support/ebpf/types.h"
import "C"
import (
"go/version"

"go.opentelemetry.io/ebpf-profiler/support"
)

// Offsets come from DWARF debug information, use tools/gooffsets to extract them.
// However since DWARF information can be stripped we record them here.
// TODO: Should we look for DWARF information to support new versions
// automatically when available?
func getOffsets(vers string) C.GoLabelsOffsets {
offsets := C.GoLabelsOffsets{
func getOffsets(vers string) support.GoLabelsOffsets {
offsets := support.GoLabelsOffsets{
// https://github.com/golang/go/blob/80e2e474b8d9124d03b744f/src/runtime/runtime2.go#L410
m_offset: 48,
M_offset: 48,
// https://github.com/golang/go/blob/80e2e474b8d9124d03b744f/src/runtime/runtime2.go#L541
curg: 192,
Curg: 192,
// https://github.com/golang/go/blob/80e2e474b8d9124d03b744f/src/runtime/runtime2.go#L483
labels: 0,
Labels: 0,
// https://github.com/golang/go/blob/6885bad7dd86880be6929c0/src/runtime/map.go#L112
hmap_count: 0,
Hmap_count: 0,
// https://github.com/golang/go/blob/6885bad7dd86880be6929c0/src/runtime/map.go#L114
hmap_log2_bucket_count: 0,
Hmap_log2_bucket_count: 0,
// https://github.com/golang/go/blob/6885bad7dd86880be6929c0/src/runtime/map.go#L118
hmap_buckets: 0,
Hmap_buckets: 0,
}

// Version enforcement takes place in the Loader function.
if version.Compare(vers, "go1.24") >= 0 {
offsets.labels = 352
offsets.Labels = 352
return offsets
}

// These are the same for all versions but we have to leave them zero for 1.24+ detection.
offsets.hmap_log2_bucket_count = 9
offsets.hmap_buckets = 16
offsets.Hmap_log2_bucket_count = 9
offsets.Hmap_buckets = 16
if version.Compare(vers, "go1.23") >= 0 {
offsets.labels = 352
offsets.Labels = 352
} else if version.Compare(vers, "go1.21") >= 0 {
offsets.labels = 344
offsets.Labels = 344
} else if version.Compare(vers, "go1.17") >= 0 {
offsets.labels = 360
offsets.Labels = 360
} else {
offsets.labels = 344
offsets.Labels = 344
}
return offsets
}
61 changes: 27 additions & 34 deletions interpreter/hotspot/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ import (
"go.opentelemetry.io/ebpf-profiler/util"
)

// #include "../../support/ebpf/types.h"
// #include "../../support/ebpf/frametypes.h"
import "C"

// heapRange contains info for an individual heap.
type heapRange struct {
codeStart, codeEnd libpf.Address
Expand Down Expand Up @@ -237,9 +233,9 @@ func (d *hotspotInstance) getPoolSymbol(addr libpf.Address, ndx uint16) libpf.St

// getStubNameID read the stub name from the code blob at given address and generates a ID.
func (d *hotspotInstance) getStubNameID(symbolReporter reporter.SymbolReporter, ripOrBci uint32,
addr libpf.Address, _ uint32) (libpf.AddressOrLineno, error) {
addr libpf.Address, _ uint32) libpf.AddressOrLineno {
if value, ok := d.addrToStubNameID.Get(addr); ok {
return value, nil
return value
}
vms := &d.d.Get().vmStructs
constStubNameAddr := d.rm.Ptr(addr + libpf.Address(vms.CodeBlob.Name))
Expand All @@ -263,7 +259,7 @@ func (d *hotspotInstance) getStubNameID(symbolReporter reporter.SymbolReporter,
})
d.addrToStubNameID.Add(addr, stubID)

return stubID, nil
return stubID
}

// getMethod reads and returns the interesting data from "class Method" at given address
Expand Down Expand Up @@ -745,31 +741,31 @@ func (d *hotspotInstance) populateMainMappings(vmd *hotspotVMData,

// Set up the main eBPF info structure.
vms := &vmd.vmStructs
procInfo := C.HotspotProcInfo{
nmethod_deopt_offset: C.u16(vms.Nmethod.DeoptimizeOffset),
nmethod_compileid: C.u16(vms.Nmethod.CompileID),
nmethod_orig_pc_offset: C.u16(vms.Nmethod.OrigPcOffset),
codeblob_name: C.u8(vms.CodeBlob.Name),
codeblob_codestart: C.u8(vms.CodeBlob.CodeBegin),
codeblob_codeend: C.u8(vms.CodeBlob.CodeEnd),
codeblob_framecomplete: C.u8(vms.CodeBlob.FrameCompleteOffset),
codeblob_framesize: C.u8(vms.CodeBlob.FrameSize),
cmethod_size: C.u8(vms.ConstMethod.Sizeof),
heapblock_size: C.u8(vms.HeapBlock.Sizeof),
method_constmethod: C.u8(vms.Method.ConstMethod),
jvm_version: C.u8(vmd.version >> 24),
segment_shift: C.u8(heap.segmentShift),
nmethod_uses_offsets: C.u8(vmd.nmethodUsesOffsets),
procInfo := support.HotspotProcInfo{
Nmethod_deopt_offset: uint16(vms.Nmethod.DeoptimizeOffset),
Nmethod_compileid: uint16(vms.Nmethod.CompileID),
Nmethod_orig_pc_offset: uint16(vms.Nmethod.OrigPcOffset),
Codeblob_name: uint8(vms.CodeBlob.Name),
Codeblob_codestart: uint8(vms.CodeBlob.CodeBegin),
Codeblob_codeend: uint8(vms.CodeBlob.CodeEnd),
Codeblob_framecomplete: uint8(vms.CodeBlob.FrameCompleteOffset),
Codeblob_framesize: uint8(vms.CodeBlob.FrameSize),
Cmethod_size: uint8(vms.ConstMethod.Sizeof),
Heapblock_size: uint8(vms.HeapBlock.Sizeof),
Method_constmethod: uint8(vms.Method.ConstMethod),
Jvm_version: uint8(vmd.version >> 24),
Segment_shift: uint8(heap.segmentShift),
Nmethod_uses_offsets: vmd.nmethodUsesOffsets,
}

if vms.CodeCache.LowBound == 0 {
// JDK-8 has only one heap, use its bounds
procInfo.codecache_start = C.u64(heap.ranges[0].codeStart)
procInfo.codecache_end = C.u64(heap.ranges[0].codeEnd)
procInfo.Codecache_start = uint64(heap.ranges[0].codeStart)
procInfo.Codecache_end = uint64(heap.ranges[0].codeEnd)
} else {
// JDK9+ the VM tracks it separately
procInfo.codecache_start = C.u64(d.rm.Ptr(vms.CodeCache.LowBound + d.bias))
procInfo.codecache_end = C.u64(d.rm.Ptr(vms.CodeCache.HighBound + d.bias))
procInfo.Codecache_start = uint64(d.rm.Ptr(vms.CodeCache.LowBound + d.bias))
procInfo.Codecache_end = uint64(d.rm.Ptr(vms.CodeCache.HighBound + d.bias))
}

if err = ebpf.UpdateProcData(libpf.HotSpot, pid, unsafe.Pointer(&procInfo)); err != nil {
Expand Down Expand Up @@ -875,22 +871,19 @@ func (d *hotspotInstance) Symbolize(symbolReporter reporter.SymbolReporter,
sfCounter := successfailurecounter.New(&d.successCount, &d.failCount)
defer sfCounter.DefaultToFailure()

switch subtype {
case C.FRAME_HOTSPOT_STUB, C.FRAME_HOTSPOT_VTABLE:
switch uint8(subtype) {
case support.FrameHotspotStub, support.FrameHotspotVtable:
// These are stub frames that may or may not be interesting
// to be seen in the trace.
stubID, err1 := d.getStubNameID(symbolReporter, ripOrBci, ptr, ptrCheck)
if err1 != nil {
return err
}
stubID := d.getStubNameID(symbolReporter, ripOrBci, ptr, ptrCheck)
trace.AppendFrame(libpf.HotSpotFrame, hotspotStubsFileID, stubID)
case C.FRAME_HOTSPOT_INTERPRETER:
case support.FrameHotspotInterpreter:
method, err1 := d.getMethod(ptr, ptrCheck)
if err1 != nil {
return err1
}
method.symbolize(symbolReporter, ripOrBci, d, trace)
case C.FRAME_HOTSPOT_NATIVE:
case support.FrameHotspotNative:
jitinfo, err1 := d.getJITInfo(ptr, ptrCheck)
if err1 != nil {
return err1
Expand Down
Loading