diff --git a/interpreter/instancestubs.go b/interpreter/instancestubs.go index 6b503280e..75af5fb35 100644 --- a/interpreter/instancestubs.go +++ b/interpreter/instancestubs.go @@ -5,11 +5,11 @@ package interpreter // import "go.opentelemetry.io/ebpf-profiler/interpreter" import ( "go.opentelemetry.io/ebpf-profiler/host" + "go.opentelemetry.io/ebpf-profiler/libc" "go.opentelemetry.io/ebpf-profiler/libpf" "go.opentelemetry.io/ebpf-profiler/metrics" "go.opentelemetry.io/ebpf-profiler/process" "go.opentelemetry.io/ebpf-profiler/reporter" - "go.opentelemetry.io/ebpf-profiler/tpbase" ) // InstanceStubs provides empty implementations of Instance hooks that are @@ -22,7 +22,7 @@ func (is *InstanceStubs) SynchronizeMappings(EbpfHandler, reporter.ExecutableRep return nil } -func (is *InstanceStubs) UpdateTSDInfo(EbpfHandler, libpf.PID, tpbase.TSDInfo) error { +func (is *InstanceStubs) UpdateLibcInfo(EbpfHandler, libpf.PID, libc.LibcInfo) error { return nil } diff --git a/interpreter/multi.go b/interpreter/multi.go index 34f426758..b6372fc1e 100644 --- a/interpreter/multi.go +++ b/interpreter/multi.go @@ -8,12 +8,12 @@ import ( "go.opentelemetry.io/ebpf-profiler/host" "go.opentelemetry.io/ebpf-profiler/internal/log" + "go.opentelemetry.io/ebpf-profiler/libc" "go.opentelemetry.io/ebpf-profiler/libpf" "go.opentelemetry.io/ebpf-profiler/metrics" "go.opentelemetry.io/ebpf-profiler/process" "go.opentelemetry.io/ebpf-profiler/remotememory" "go.opentelemetry.io/ebpf-profiler/reporter" - "go.opentelemetry.io/ebpf-profiler/tpbase" ) // MultiData implements the Data interface for multiple interpreters. @@ -104,11 +104,11 @@ func (m *MultiInstance) SynchronizeMappings(ebpf EbpfHandler, return errors.Join(errs...) } -// UpdateTSDInfo updates TSD info for all interpreter instances. -func (m *MultiInstance) UpdateTSDInfo(ebpf EbpfHandler, pid libpf.PID, info tpbase.TSDInfo) error { +// UpdateLibcInfo updates libc info for all interpreter instances. +func (m *MultiInstance) UpdateLibcInfo(ebpf EbpfHandler, pid libpf.PID, info libc.LibcInfo) error { var errs []error for _, instance := range m.instances { - if err := instance.UpdateTSDInfo(ebpf, pid, info); err != nil { + if err := instance.UpdateLibcInfo(ebpf, pid, info); err != nil { errs = append(errs, err) } } diff --git a/interpreter/perl/instance.go b/interpreter/perl/instance.go index 026d7dbfa..d3fda9fa0 100644 --- a/interpreter/perl/instance.go +++ b/interpreter/perl/instance.go @@ -15,6 +15,7 @@ import ( "go.opentelemetry.io/ebpf-profiler/host" "go.opentelemetry.io/ebpf-profiler/interpreter" + "go.opentelemetry.io/ebpf-profiler/libc" "go.opentelemetry.io/ebpf-profiler/libpf" "go.opentelemetry.io/ebpf-profiler/libpf/pfunsafe" "go.opentelemetry.io/ebpf-profiler/metrics" @@ -22,7 +23,6 @@ import ( "go.opentelemetry.io/ebpf-profiler/remotememory" "go.opentelemetry.io/ebpf-profiler/successfailurecounter" "go.opentelemetry.io/ebpf-profiler/support" - "go.opentelemetry.io/ebpf-profiler/tpbase" "go.opentelemetry.io/ebpf-profiler/util" ) @@ -73,9 +73,8 @@ func hashCOPKey(k copKey) uint32 { return uint32(h ^ xxh3.HashString128(k.funcName.String()).Lo) } -func (i *perlInstance) UpdateTSDInfo(ebpf interpreter.EbpfHandler, pid libpf.PID, - tsdInfo tpbase.TSDInfo, -) error { +func (i *perlInstance) UpdateLibcInfo(ebpf interpreter.EbpfHandler, pid libpf.PID, + libcInfo libc.LibcInfo) error { d := i.d stateInTSD := uint8(0) if d.stateInTSD { @@ -88,9 +87,9 @@ func (i *perlInstance) UpdateTSDInfo(ebpf interpreter.EbpfHandler, pid libpf.PID StateInTSD: stateInTSD, TsdInfo: support.TSDInfo{ - Offset: tsdInfo.Offset, - Multiplier: tsdInfo.Multiplier, - Indirect: tsdInfo.Indirect, + Offset: libcInfo.TSDInfo.Offset, + Multiplier: libcInfo.TSDInfo.Multiplier, + Indirect: libcInfo.TSDInfo.Indirect, }, Interpreter_curcop: uint16(vms.interpreter.curcop), diff --git a/interpreter/python/python.go b/interpreter/python/python.go index a440de2c4..23ca245c1 100644 --- a/interpreter/python/python.go +++ b/interpreter/python/python.go @@ -26,6 +26,7 @@ import ( "go.opentelemetry.io/ebpf-profiler/host" "go.opentelemetry.io/ebpf-profiler/interpreter" + "go.opentelemetry.io/ebpf-profiler/libc" "go.opentelemetry.io/ebpf-profiler/libpf" "go.opentelemetry.io/ebpf-profiler/libpf/pfelf" "go.opentelemetry.io/ebpf-profiler/metrics" @@ -33,7 +34,6 @@ import ( "go.opentelemetry.io/ebpf-profiler/remotememory" "go.opentelemetry.io/ebpf-profiler/successfailurecounter" "go.opentelemetry.io/ebpf-profiler/support" - "go.opentelemetry.io/ebpf-profiler/tpbase" "go.opentelemetry.io/ebpf-profiler/util" ) @@ -371,9 +371,8 @@ func (p *pythonInstance) GetAndResetMetrics() ([]metrics.Metric, error) { }, nil } -func (p *pythonInstance) UpdateTSDInfo(ebpf interpreter.EbpfHandler, pid libpf.PID, - tsdInfo tpbase.TSDInfo, -) error { +func (p *pythonInstance) UpdateLibcInfo(ebpf interpreter.EbpfHandler, pid libpf.PID, + libcInfo libc.LibcInfo) error { d := p.d vm := &d.vmStructs cdata := support.PyProcInfo{ @@ -381,9 +380,9 @@ func (p *pythonInstance) UpdateTSDInfo(ebpf interpreter.EbpfHandler, pid libpf.P Version: d.version, TsdInfo: support.TSDInfo{ - Offset: tsdInfo.Offset, - Multiplier: tsdInfo.Multiplier, - Indirect: tsdInfo.Indirect, + Offset: libcInfo.TSDInfo.Offset, + Multiplier: libcInfo.TSDInfo.Multiplier, + Indirect: libcInfo.TSDInfo.Indirect, }, PyThreadState_frame: uint8(vm.PyThreadState.Frame), diff --git a/interpreter/types.go b/interpreter/types.go index a619c865b..2577fa1f0 100644 --- a/interpreter/types.go +++ b/interpreter/types.go @@ -8,13 +8,13 @@ import ( "unsafe" "go.opentelemetry.io/ebpf-profiler/host" + "go.opentelemetry.io/ebpf-profiler/libc" "go.opentelemetry.io/ebpf-profiler/libpf" "go.opentelemetry.io/ebpf-profiler/lpm" "go.opentelemetry.io/ebpf-profiler/metrics" "go.opentelemetry.io/ebpf-profiler/process" "go.opentelemetry.io/ebpf-profiler/remotememory" "go.opentelemetry.io/ebpf-profiler/reporter" - "go.opentelemetry.io/ebpf-profiler/tpbase" "go.opentelemetry.io/ebpf-profiler/util" ) @@ -143,9 +143,9 @@ type Instance interface { SynchronizeMappings(ebpf EbpfHandler, exeReporter reporter.ExecutableReporter, pr process.Process, mappings []process.Mapping) error - // UpdateTSDInfo is called when the process C-library Thread Specific Data related + // UpdateLibcInfo is called when the process C-library related // introspection data has been updated. - UpdateTSDInfo(ebpf EbpfHandler, pid libpf.PID, info tpbase.TSDInfo) error + UpdateLibcInfo(ebpf EbpfHandler, pid libpf.PID, info libc.LibcInfo) error // Symbolize converts one ebpf frame to one or more (if inlining was expanded) libpf.Frame. // The resulting libpf.Frame values are appended to frames. diff --git a/tpbase/assembly_decode_aarch64.go b/libc/assembly_decode_aarch64.go similarity index 97% rename from tpbase/assembly_decode_aarch64.go rename to libc/assembly_decode_aarch64.go index 31de50e97..50bb706a6 100644 --- a/tpbase/assembly_decode_aarch64.go +++ b/libc/assembly_decode_aarch64.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package tpbase // import "go.opentelemetry.io/ebpf-profiler/tpbase" +package libc // import "go.opentelemetry.io/ebpf-profiler/libc" import ( "errors" diff --git a/tpbase/assembly_decode_test.go b/libc/assembly_decode_test.go similarity index 99% rename from tpbase/assembly_decode_test.go rename to libc/assembly_decode_test.go index 426bbada4..de62cf847 100644 --- a/tpbase/assembly_decode_test.go +++ b/libc/assembly_decode_test.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package tpbase +package libc import ( "debug/elf" diff --git a/tpbase/assembly_decode_x86.go b/libc/assembly_decode_x86.go similarity index 97% rename from tpbase/assembly_decode_x86.go rename to libc/assembly_decode_x86.go index 6742aa504..d2cca06fc 100644 --- a/tpbase/assembly_decode_x86.go +++ b/libc/assembly_decode_x86.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package tpbase // import "go.opentelemetry.io/ebpf-profiler/tpbase" +package libc // import "go.opentelemetry.io/ebpf-profiler/libc" import ( "bytes" diff --git a/tpbase/libc.go b/libc/libc.go similarity index 88% rename from tpbase/libc.go rename to libc/libc.go index 7e9b2a7a1..d979eb0bb 100644 --- a/tpbase/libc.go +++ b/libc/libc.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package tpbase // import "go.opentelemetry.io/ebpf-profiler/tpbase" +package libc // import "go.opentelemetry.io/ebpf-profiler/libc" import ( "debug/elf" @@ -11,6 +11,12 @@ import ( "go.opentelemetry.io/ebpf-profiler/libpf/pfelf" ) +// LibcInfo contains introspection information extracted from the C-library +type LibcInfo struct { + // TSDInfo is the TSDInfo extracted for this C-library + TSDInfo TSDInfo +} + // TSDInfo contains information to access C-library's Thread Specific Data from eBPF type TSDInfo struct { // Offset is the pointer difference from "tpbase" pointer to the C-library @@ -84,8 +90,19 @@ func IsPotentialTSDDSO(filename string) bool { return libcRegex.MatchString(filename) } +func ExtractLibcInfo(ef *pfelf.File) (*LibcInfo, error) { + tsdinfo, err := extractTSDInfo(ef) + if err != nil { + return nil, err + } + + return &LibcInfo{ + TSDInfo: *tsdinfo, + }, nil +} + // ExtractTSDInfo extracts the introspection data for pthread thread specific data. -func ExtractTSDInfo(ef *pfelf.File) (*TSDInfo, error) { +func extractTSDInfo(ef *pfelf.File) (*TSDInfo, error) { _, code, err := ef.SymbolData("__pthread_getspecific", 2048) if err != nil { _, code, err = ef.SymbolData("pthread_getspecific", 2048) diff --git a/tpbase/libc_aarch64.go b/libc/libc_aarch64.go similarity index 98% rename from tpbase/libc_aarch64.go rename to libc/libc_aarch64.go index 585879126..fc5ceb76f 100644 --- a/tpbase/libc_aarch64.go +++ b/libc/libc_aarch64.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package tpbase // import "go.opentelemetry.io/ebpf-profiler/tpbase" +package libc // import "go.opentelemetry.io/ebpf-profiler/libc" import ( "errors" diff --git a/tpbase/libc_test.go b/libc/libc_test.go similarity index 99% rename from tpbase/libc_test.go rename to libc/libc_test.go index 8f5f48be7..bc7f108d5 100644 --- a/tpbase/libc_test.go +++ b/libc/libc_test.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package tpbase +package libc // import "go.opentelemetry.io/ebpf-profiler/libc" import ( "debug/elf" diff --git a/tpbase/libc_x86.go b/libc/libc_x86.go similarity index 96% rename from tpbase/libc_x86.go rename to libc/libc_x86.go index 8d1c839f8..161deb8a9 100644 --- a/tpbase/libc_x86.go +++ b/libc/libc_x86.go @@ -1,7 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package tpbase // import "go.opentelemetry.io/ebpf-profiler/tpbase" +package libc // import "go.opentelemetry.io/ebpf-profiler/libc" + import ( "errors" diff --git a/tpbase/tpbase.go b/libc/tpbase.go similarity index 88% rename from tpbase/tpbase.go rename to libc/tpbase.go index 11aa1c035..8994c7dbe 100644 --- a/tpbase/tpbase.go +++ b/libc/tpbase.go @@ -7,14 +7,14 @@ // relative to the 'struct task_struct'. This is needed to support Thread Local // Storage access in eBPF. -package tpbase // import "go.opentelemetry.io/ebpf-profiler/tpbase" +package libc // import "go.opentelemetry.io/ebpf-profiler/libc" import ( "fmt" "runtime" ) -func GetAnalyzers() ([]Analyzer, error) { +func GetTpBaseAnalyzers() ([]Analyzer, error) { switch runtime.GOARCH { case "amd64": return getAnalyzersX86(), nil diff --git a/processmanager/execinfomanager/manager.go b/processmanager/execinfomanager/manager.go index e3952c238..2699c3878 100644 --- a/processmanager/execinfomanager/manager.go +++ b/processmanager/execinfomanager/manager.go @@ -24,6 +24,7 @@ import ( "go.opentelemetry.io/ebpf-profiler/interpreter/php" "go.opentelemetry.io/ebpf-profiler/interpreter/python" "go.opentelemetry.io/ebpf-profiler/interpreter/ruby" + "go.opentelemetry.io/ebpf-profiler/libc" "go.opentelemetry.io/ebpf-profiler/libpf" "go.opentelemetry.io/ebpf-profiler/libpf/pfelf" "go.opentelemetry.io/ebpf-profiler/libpf/xsync" @@ -32,7 +33,6 @@ import ( sdtypes "go.opentelemetry.io/ebpf-profiler/nativeunwind/stackdeltatypes" pmebpf "go.opentelemetry.io/ebpf-profiler/processmanager/ebpfapi" "go.opentelemetry.io/ebpf-profiler/support" - "go.opentelemetry.io/ebpf-profiler/tpbase" "go.opentelemetry.io/ebpf-profiler/tracer/types" "go.opentelemetry.io/ebpf-profiler/util" ) @@ -61,8 +61,8 @@ type ExecutableInfo struct { // instance belongs to was previously identified as an interpreter. Otherwise, // this field is nil. Data interpreter.Data - // TSDInfo stores TSD information if the executable is libc, otherwise nil. - TSDInfo *tpbase.TSDInfo + // LibcInfo stores libc information if the executable is libc, otherwise nil. + LibcInfo *libc.LibcInfo } // ExecutableInfoManager manages all per-executable (FileID) information that we require to @@ -164,7 +164,7 @@ func (mgr *ExecutableInfoManager) AddOrIncRef(fileID host.FileID, } var ( intervalData sdtypes.IntervalData - tsdInfo *tpbase.TSDInfo + libcInfo *libc.LibcInfo ref mapRef gaps []util.Range err error @@ -198,9 +198,9 @@ func (mgr *ExecutableInfoManager) AddOrIncRef(fileID host.FileID, } // Also gather TSD info if applicable. - if tpbase.IsPotentialTSDDSO(elfRef.FileName()) { + if libc.IsPotentialTSDDSO(elfRef.FileName()) { if ef, errx := elfRef.GetELF(); errx == nil { - tsdInfo, _ = tpbase.ExtractTSDInfo(ef) + libcInfo, _ = libc.ExtractLibcInfo(ef) } } @@ -226,8 +226,8 @@ func (mgr *ExecutableInfoManager) AddOrIncRef(fileID host.FileID, // Insert a corresponding record into our map. info = &entry{ ExecutableInfo: ExecutableInfo{ - Data: state.detectAndLoadInterpData(loaderInfo), - TSDInfo: tsdInfo, + Data: state.detectAndLoadInterpData(loaderInfo), + LibcInfo: libcInfo, }, mapRef: ref, rc: 1, diff --git a/processmanager/processinfo.go b/processmanager/processinfo.go index 836c4c9f5..792ca3ce0 100644 --- a/processmanager/processinfo.go +++ b/processmanager/processinfo.go @@ -24,6 +24,7 @@ import ( "go.opentelemetry.io/ebpf-profiler/host" "go.opentelemetry.io/ebpf-profiler/interpreter" + "go.opentelemetry.io/ebpf-profiler/libc" "go.opentelemetry.io/ebpf-profiler/libpf" "go.opentelemetry.io/ebpf-profiler/libpf/pfelf" "go.opentelemetry.io/ebpf-profiler/lpm" @@ -31,7 +32,6 @@ import ( eim "go.opentelemetry.io/ebpf-profiler/processmanager/execinfomanager" "go.opentelemetry.io/ebpf-profiler/reporter" "go.opentelemetry.io/ebpf-profiler/times" - "go.opentelemetry.io/ebpf-profiler/tpbase" "go.opentelemetry.io/ebpf-profiler/util" ) @@ -69,38 +69,38 @@ func isPIDLive(pid libpf.PID) (bool, error) { return true, err } -// assignTSDInfo updates the TSDInfo for the Interpreters on given PID. +// assignLibcInfo updates the LibcInfo for the Interpreters on given PID. // Caller must hold pm.mu write lock. -func (pm *ProcessManager) assignTSDInfo(pid libpf.PID, tsdInfo *tpbase.TSDInfo) { - if tsdInfo == nil { +func (pm *ProcessManager) assignLibcInfo(pid libpf.PID, libcInfo *libc.LibcInfo) { + if libcInfo == nil { return } info, ok := pm.pidToProcessInfo[pid] if !ok { - // This is guaranteed not to happen since assignTSDInfo is always called after + // This is guaranteed not to happen since assignLibcInfo is always called after // pm.updatePidInformation - but to avoid a possible panic we just return here. return - } else if info.tsdInfo != nil { + } else if info.libcInfo != nil { return } - info.tsdInfo = tsdInfo + info.libcInfo = libcInfo // Update the tsdInfo to interpreters that are already attached for _, instance := range pm.interpreters[pid] { - if err := instance.UpdateTSDInfo(pm.ebpf, pid, *tsdInfo); err != nil { - log.Errorf("Failed to update PID %v TSDInfo: %v", + if err := instance.UpdateLibcInfo(pm.ebpf, pid, *libcInfo); err != nil { + log.Errorf("Failed to update PID %v LibcInfo: %v", pid, err) } } } -// getTSDInfo retrieves the TSDInfo of given PID +// getLibcInfo retrieves the LibcInfo of given PID // Caller must hold pm.mu read lock. -func (pm *ProcessManager) getTSDInfo(pid libpf.PID) *tpbase.TSDInfo { +func (pm *ProcessManager) getLibcInfo(pid libpf.PID) *libc.LibcInfo { if info, ok := pm.pidToProcessInfo[pid]; ok { - return info.tsdInfo + return info.libcInfo } return nil } @@ -121,7 +121,7 @@ func (pm *ProcessManager) updatePidInformation(pr process.Process, m *Mapping) ( meta: pr.GetProcessMeta(process.MetaConfig{IncludeEnvVars: pm.includeEnvVars}), mappings: make(map[libpf.Address]*Mapping), mappingsByFileID: make(map[host.FileID]map[libpf.Address]*Mapping), - tsdInfo: nil, + libcInfo: nil, } pm.pidToProcessInfo[pid] = info @@ -238,10 +238,10 @@ func (pm *ProcessManager) handleNewInterpreter(pr process.Process, m *Mapping, log.Debugf("Attached to %v interpreter in PID %v", ei.Data, pid) pm.assignInterpreter(pid, key, instance) - if tsdInfo := pm.getTSDInfo(pid); tsdInfo != nil { - err = instance.UpdateTSDInfo(pm.ebpf, pid, *tsdInfo) + if libcInfo := pm.getLibcInfo(pid); libcInfo != nil { + err = instance.UpdateLibcInfo(pm.ebpf, pid, *libcInfo) if err != nil { - log.Errorf("Failed to update PID %v TSDInfo: %v", pid, err) + log.Errorf("Failed to update PID %v LibcInfo: %v", pid, err) } } @@ -270,7 +270,7 @@ func (pm *ProcessManager) handleNewMapping(pr process.Process, m *Mapping, return err } - pm.assignTSDInfo(pr.PID(), ei.TSDInfo) + pm.assignLibcInfo(pr.PID(), ei.LibcInfo) if ei.Data != nil { return pm.handleNewInterpreter(pr, m, &ei) diff --git a/processmanager/types.go b/processmanager/types.go index d445d02da..4a739e127 100644 --- a/processmanager/types.go +++ b/processmanager/types.go @@ -11,6 +11,7 @@ import ( "go.opentelemetry.io/ebpf-profiler/host" "go.opentelemetry.io/ebpf-profiler/interpreter" + "go.opentelemetry.io/ebpf-profiler/libc" "go.opentelemetry.io/ebpf-profiler/libpf" "go.opentelemetry.io/ebpf-profiler/libpf/pfelf" "go.opentelemetry.io/ebpf-profiler/metrics" @@ -19,7 +20,6 @@ import ( eim "go.opentelemetry.io/ebpf-profiler/processmanager/execinfomanager" "go.opentelemetry.io/ebpf-profiler/reporter" "go.opentelemetry.io/ebpf-profiler/times" - "go.opentelemetry.io/ebpf-profiler/tpbase" "go.opentelemetry.io/ebpf-profiler/util" ) @@ -168,7 +168,7 @@ type processInfo struct { // executable mappings keyed by host file ID. mappingsByFileID map[host.FileID]map[libpf.Address]*Mapping // C-library Thread Specific Data information - tsdInfo *tpbase.TSDInfo + libcInfo *libc.LibcInfo } // addMapping adds a mapping to the internal indices. diff --git a/tracer/tpbase.go b/tracer/tpbase.go index 45c652d0d..5c0897981 100644 --- a/tracer/tpbase.go +++ b/tracer/tpbase.go @@ -12,8 +12,8 @@ import ( "go.opentelemetry.io/ebpf-profiler/internal/log" "go.opentelemetry.io/ebpf-profiler/kallsyms" + "go.opentelemetry.io/ebpf-profiler/libc" "go.opentelemetry.io/ebpf-profiler/libpf" - "go.opentelemetry.io/ebpf-profiler/tpbase" ) // This file contains code to extract the offset of the thread pointer base variable in @@ -39,7 +39,7 @@ func loadTPBaseOffset(coll *cebpf.CollectionSpec, maps map[string]*cebpf.Map, kmod *kallsyms.Module, ) (uint64, error) { var tpbaseOffset uint32 - analyzers, err := tpbase.GetAnalyzers() + analyzers, err := libc.GetTpBaseAnalyzers() if err != nil { return 0, err }