Skip to content
Draft
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
6 changes: 3 additions & 3 deletions asm/amd/tls.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ func ExtractTLSOffset(code []byte, codeAddress uint64, file *pfelf.File) (int32,
if file != nil {
addr := e.NewImmediateCapture("addr")
if actual.Match(e.Mem8(addr)) {
valueBytes, err := file.VirtualMemory(int64(addr.CapturedValue()), 8, 8)
if err != nil {
b := make([]byte, 8)
if _, err := file.ReadAt(b, int64(addr.CapturedValue())); err != nil {
continue
}
// Read the 8-byte value as int64 (little-endian)
value := int64(npsr.Uint64(valueBytes, 0))
value := int64(npsr.Uint64(b, 0))
return validateTLSOffset(int32(value))
}
}
Expand Down
14 changes: 5 additions & 9 deletions interpreter/go/go.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ func (g *goInstance) Symbolize(ef libpf.EbpfFrame, frames *libpf.Frames, mapping
defer sfCounter.DefaultToFailure()

address := ef.Data()
sourceFile, lineNo, fn := g.d.pclntab.Symbolize(uintptr(address))
if fn == "" {
sourceFile, lineNo, fn := g.d.pclntab.Symbolize(uint64(address))
if fn == libpf.NullString {
return fmt.Errorf("failed to symbolize 0x%x", address)
}
// See comment about return address handling in ProcessManager.convertFrame
Expand All @@ -121,15 +121,11 @@ func (g *goInstance) Symbolize(ef libpf.EbpfFrame, frames *libpf.Frames, mapping
frames.Append(&libpf.Frame{
Type: libpf.GoFrame,
AddressOrLineno: libpf.AddressOrLineno(address),
Mapping: mapping,
FunctionName: libpf.Intern(fn),
SourceFile: libpf.Intern(sourceFile),
FunctionName: fn,
SourceFile: sourceFile,
SourceLine: libpf.SourceLineno(lineNo),
Mapping: mapping,
})
sfCounter.ReportSuccess()
return nil
}

func (g *goInstance) ReleaseResources() error {
return g.d.pclntab.SetDontNeed()
}
4 changes: 2 additions & 2 deletions interpreter/golabels/tls_amd64.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ func extractTLSGOffset(f *pfelf.File) (int32, error) {
}

sz := int(min(sym.Size, 128))
code, err := f.VirtualMemory(int64(sym.Address), sz, sz)
if err != nil {
code := make([]byte, sz)
if _, err = f.ReadAt(code, int64(sym.Address)); err != nil {
return 0, err
}

Expand Down
5 changes: 3 additions & 2 deletions interpreter/golabels/tls_arm64.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@ func extractTLSGOffset(f *pfelf.File) (int32, error) {
return 0, err
}
}
b, err := f.VirtualMemory(int64(sym.Address), 32, 32)
if err != nil {
sz := int(min(sym.Size, 32))
b := make([]byte, sz)
if _, err := f.ReadAt(b, int64(sym.Address)); err != nil {
return 0, err
}
for ; len(b) > 0; b = b[4:] {
Expand Down
31 changes: 9 additions & 22 deletions interpreter/hotspot/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
package hotspot // import "go.opentelemetry.io/ebpf-profiler/interpreter/hotspot"

import (
"bytes"
"encoding/binary"
"errors"
"fmt"
Expand All @@ -18,6 +17,7 @@ import (

"go.opentelemetry.io/ebpf-profiler/interpreter"
"go.opentelemetry.io/ebpf-profiler/libpf"
"go.opentelemetry.io/ebpf-profiler/libpf/pfatbuf"
"go.opentelemetry.io/ebpf-profiler/libpf/pfelf"
"go.opentelemetry.io/ebpf-profiler/libpf/xsync"
"go.opentelemetry.io/ebpf-profiler/lpm"
Expand Down Expand Up @@ -395,48 +395,35 @@ func (d *hotspotData) Unload(_ interpreter.EbpfHandler) {
//
//nolint:lll
func locateJvmciVMStructs(ef *pfelf.File) (libpf.Address, error) {
const maxDataReadSize = 1 * 1024 * 1024 // seen in practice: 192 KiB
const maxRodataReadSize = 4 * 1024 * 1024 // seen in practice: 753 KiB

rodataSec := ef.Section(".rodata")
if rodataSec == nil {
rodata := ef.Section(".rodata")
if rodata == nil {
return 0, errors.New("unable to find `.rodata` section")
}

rodata, err := rodataSec.Data(maxRodataReadSize)
offs, err := pfatbuf.Search(rodata, []byte("Klass_vtable_start_offset"), nil)
if err != nil {
return 0, err
}

offs := bytes.Index(rodata, []byte("Klass_vtable_start_offset"))
if offs == -1 {
return 0, errors.New("unable to find string for heuristic")
}

ptr := rodataSec.Addr + uint64(offs)
ptr := rodata.Addr + uint64(offs)
ptrEncoded := make([]byte, 8)
binary.LittleEndian.PutUint64(ptrEncoded, ptr)

dataSec := ef.Section(".data")
if dataSec == nil {
data := ef.Section(".data")
if data == nil {
return 0, errors.New("unable to find `.data` section")
}

data, err := dataSec.Data(maxDataReadSize)
offs, err = pfatbuf.Search(data, ptrEncoded, nil)
if err != nil {
return 0, err
}

offs = bytes.Index(data, ptrEncoded)
if offs == -1 {
return 0, errors.New("unable to find string pointer")
}

// 8 in the expression below is what we'd usually read from
// gHotSpotVMStructEntryFieldNameOffset. This value unfortunately lives in
// BSS, so we have no choice but to hard-code it. Fortunately enough this
// offset hasn't changed since at least JDK 9.
return libpf.Address(dataSec.Addr + uint64(offs) - 8), nil
return libpf.Address(data.Addr + uint64(offs) - 8), nil
}

// forEachItem walks the given struct reflection fields recursively, and calls the visitor
Expand Down
4 changes: 0 additions & 4 deletions interpreter/instancestubs.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,3 @@ func (is *InstanceStubs) Symbolize(libpf.EbpfFrame, *libpf.Frames, libpf.FrameMa
func (is *InstanceStubs) GetAndResetMetrics() ([]metrics.Metric, error) {
return []metrics.Metric{}, nil
}

func (is *InstanceStubs) ReleaseResources() error {
return nil
}
11 changes: 0 additions & 11 deletions interpreter/multi.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,14 +142,3 @@ func (m *MultiInstance) GetAndResetMetrics() ([]metrics.Metric, error) {

return allMetrics, errors.Join(errs...)
}

func (m *MultiInstance) ReleaseResources() error {
var errs []error
for _, instance := range m.instances {
err := instance.ReleaseResources()
if err != nil {
errs = append(errs, err)
}
}
return errors.Join(errs...)
}
2 changes: 1 addition & 1 deletion interpreter/nodev8/v8.go
Original file line number Diff line number Diff line change
Expand Up @@ -2122,7 +2122,7 @@ func locateSnapshotArea(ef *pfelf.File, syms relevantSymbols) util.Range {
return util.Range{}
}

for prevEnd := uintptr(addr); prevEnd-uintptr(addr) < 1024; ndx++ {
for prevEnd := uint64(addr); prevEnd-uint64(addr) < 1024; ndx++ {
fde, err := eft.DecodeIndex(ndx)
if err != nil {
return util.Range{}
Expand Down
24 changes: 5 additions & 19 deletions interpreter/php/php.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
package php // import "go.opentelemetry.io/ebpf-profiler/interpreter/php"

import (
"bytes"
"debug/elf"
"errors"
"fmt"
Expand All @@ -18,6 +17,7 @@ import (

"go.opentelemetry.io/ebpf-profiler/interpreter"
"go.opentelemetry.io/ebpf-profiler/libpf"
"go.opentelemetry.io/ebpf-profiler/libpf/pfatbuf"
"go.opentelemetry.io/ebpf-profiler/libpf/pfelf"
"go.opentelemetry.io/ebpf-profiler/libpf/pfunsafe"
"go.opentelemetry.io/ebpf-profiler/remotememory"
Expand All @@ -30,12 +30,6 @@ const (
ZEND_VM_KIND_HYBRID = (1 << 2)
)

const (
// maxPHPRODataSize is the maximum PHP RO Data segment size to scan
// (currently the largest seen is about 9M)
maxPHPRODataSize = 16 * 1024 * 1024
)

var (
// evalCodeFunctionName is a placeholder name to show that code has been evaluated
// using eval in PHP.
Expand Down Expand Up @@ -166,22 +160,14 @@ func determinePHPVersion(ef *pfelf.File) (uint32, error) {
}

needle := []byte("X-Powered-By: PHP/")
for _, segment := range ef.ROData {
rodata, err := segment.Data(maxPHPRODataSize)
value := make([]byte, 16)
for _, ph := range ef.ROData {
_, err := pfatbuf.Search(ph, needle, value)
if err != nil {
return 0, err
}
idx := bytes.Index(rodata, needle)
if idx < 0 {
continue
}

idx += len(needle)
zeroIdx := bytes.IndexByte(rodata[idx:], 0)
if zeroIdx < 0 {
continue
}
version, err := versionExtract(pfunsafe.ToString(rodata[idx : idx+zeroIdx]))
version, err := versionExtract(pfunsafe.ToString(value))
if err != nil {
continue
}
Expand Down
3 changes: 0 additions & 3 deletions interpreter/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,4 @@ type Instance interface {
// GetAndResetMetrics collects the metrics from the Instance and resets
// the counters to their initial value.
GetAndResetMetrics() ([]metrics.Metric, error)

// Release resources that are used to symbolize a stack.
ReleaseResources() error
}
Loading
Loading