Skip to content
Merged
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
34 changes: 7 additions & 27 deletions processmanager/execinfomanager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,13 @@ func (mgr *ExecutableInfoManager) AddOrIncRef(fileID host.FileID,
}
return ExecutableInfo{}, fmt.Errorf("failed to extract interval data: %w", err)
}
if len(intervalData.Deltas) == 0 {
ef, errx := elfRef.GetELF()
if errx != nil {
return ExecutableInfo{}, errx
}
intervalData = synthesizeIntervalData(ef)
}

// Also gather TSD info if applicable.
if tpbase.IsPotentialTSDDSO(elfRef.FileName()) {
Expand Down Expand Up @@ -232,33 +239,6 @@ func (mgr *ExecutableInfoManager) AddOrIncRef(fileID host.FileID,
return info.ExecutableInfo, nil
}

// AddSynthIntervalData should only be called once for a given file ID. It will error if it or
// AddOrIncRef has been previously called for the same file ID. Interpreter detection is skipped.
func (mgr *ExecutableInfoManager) AddSynthIntervalData(
fileID host.FileID,
data sdtypes.IntervalData,
) error {
state := mgr.state.WLock()
defer mgr.state.WUnlock(&state)

if _, exists := state.executables[fileID]; exists {
return errors.New("AddSynthIntervalData: mapping already exists")
}

ref, _, err := state.loadDeltas(fileID, data.Deltas)
if err != nil {
return fmt.Errorf("failed to load deltas: %w", err)
}

state.executables[fileID] = &entry{
ExecutableInfo: ExecutableInfo{Data: nil},
mapRef: ref,
rc: 1,
}

return nil
}

// RemoveOrDecRef decrements the reference counter of the executable being tracked. Once the RC
// reaches zero, information about the file is removed from the manager and the corresponding
// BPF maps.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

package processmanager // import "go.opentelemetry.io/ebpf-profiler/processmanager"
package execinfomanager // import "go.opentelemetry.io/ebpf-profiler/processmanager/execinfomanager"

import (
"debug/elf"
"sort"

aa "golang.org/x/arch/arm64/arm64asm"
Expand All @@ -21,9 +22,15 @@ const regFP = 29
// regLR is the arm64 link register (x30) number
const regLR = 30

// createVDSOSyntheticRecordNone returns no synthetic deltas when the kernel vDSO
// is known to have valid unwind information.
func createVDSOSyntheticRecordNone(_ *pfelf.File) sdtypes.IntervalData {
// synthesizeIntervalData creates synthetic stack deltas if possible.
// Currently supported for ARM64 vDSO only.
func synthesizeIntervalData(ef *pfelf.File) sdtypes.IntervalData {
if ef.Machine == elf.EM_AARCH64 {
soname, err := ef.DynString(elf.DT_SONAME)
if err == nil && soname[0] == "linux-vdso.so.1" {
return createVDSOSyntheticRecordArm64(ef)
}
}
return sdtypes.IntervalData{}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

package processmanager // import "go.opentelemetry.io/ebpf-profiler/processmanager"
package execinfomanager // import "go.opentelemetry.io/ebpf-profiler/processmanager/execinfomanager"

import (
"testing"
Expand Down
11 changes: 0 additions & 11 deletions processmanager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import (
"go.opentelemetry.io/ebpf-profiler/lpm"
"go.opentelemetry.io/ebpf-profiler/metrics"
"go.opentelemetry.io/ebpf-profiler/nativeunwind"
sdtypes "go.opentelemetry.io/ebpf-profiler/nativeunwind/stackdeltatypes"
"go.opentelemetry.io/ebpf-profiler/periodiccaller"
pmebpf "go.opentelemetry.io/ebpf-profiler/processmanager/ebpf"
eim "go.opentelemetry.io/ebpf-profiler/processmanager/execinfomanager"
Expand Down Expand Up @@ -332,13 +331,3 @@ func (pm *ProcessManager) MaybeNotifyAPMAgent(

return serviceName
}

// AddSynthIntervalData adds synthetic stack deltas to the manager. This is useful for cases where
// populating the information via the stack delta provider isn't viable, for example because the
// `.eh_frame` section for a binary is broken. If `AddSynthIntervalData` was called for a given
// file ID, the stack delta provider will not be consulted and the manually added stack deltas take
// precedence.
func (pm *ProcessManager) AddSynthIntervalData(fileID host.FileID,
data sdtypes.IntervalData) error {
return pm.eim.AddSynthIntervalData(fileID, data)
}
14 changes: 1 addition & 13 deletions processmanager/processinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -352,19 +352,7 @@ func (pm *ProcessManager) getELFInfo(pr process.Process, mapping *process.Mappin
hostFileID := host.FileIDFromLibpf(fileID)
info.fileID = hostFileID
info.addressMapper = ef.GetAddressMapper()
if mapping.IsVDSO() {
intervals := createVDSOSyntheticRecord(ef)
if intervals.Deltas != nil {
if err := pm.AddSynthIntervalData(hostFileID, intervals); err != nil {
info.err = fmt.Errorf("failed to add synthetic deltas: %w", err)
}
}
}
// Do not cache the entry if synthetic stack delta loading failed,
// so next encounter of the VDSO will retry loading them.
if info.err == nil {
pm.elfInfoCache.Add(key, info)
}
pm.elfInfoCache.Add(key, info)
pm.FileIDMapper.Set(hostFileID, fileID)

if pm.reporter.ExecutableKnown(fileID) {
Expand Down
8 changes: 0 additions & 8 deletions processmanager/synthdeltas_arm64.go

This file was deleted.

8 changes: 0 additions & 8 deletions processmanager/synthdeltas_other.go

This file was deleted.