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
2 changes: 1 addition & 1 deletion interpreter/beam/beam.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ func (d *beamData) Attach(ebpf interpreter.EbpfHandler, pid libpf.PID, bias libp
func (d *beamData) Unload(_ interpreter.EbpfHandler) {
}

func (i *beamInstance) SynchronizeMappings(ebpf interpreter.EbpfHandler, _ reporter.ExecutableReporter, pr process.Process, mappings []process.Mapping) error {
func (i *beamInstance) SynchronizeMappings(ebpf interpreter.EbpfHandler, _ reporter.ExecutableReporter, pr process.Process, mappings []process.RawMapping) error {
pid := pr.PID()
i.mappingGeneration++
for idx := range mappings {
Expand Down
6 changes: 3 additions & 3 deletions interpreter/dotnet/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ type dotnetInstance struct {
virtualCallStubManagerManagerPtr libpf.Address

// mappings contains the PE mappings to process memory space. Multiple individual
// consecutive process.Mappings may be merged to one mapping per PE file.
// consecutive process.RawMappings may be merged to one mapping per PE file.
mappings []dotnetMapping

ranges map[libpf.Address]dotnetRangeSection
Expand Down Expand Up @@ -552,7 +552,7 @@ func (i *dotnetInstance) getDacSlotPtr(slot uint) libpf.Address {

func (i *dotnetInstance) SynchronizeMappings(ebpf interpreter.EbpfHandler,
exeReporter reporter.ExecutableReporter, pr process.Process,
mappings []process.Mapping,
mappings []process.RawMapping,
) error {
// get introspection data
cdac, err := i.d.GetOrInit(func() (dotnetCdac, error) { return i.d.newVMData(i.rm, i.bias) })
Expand Down Expand Up @@ -599,7 +599,7 @@ func (i *dotnetInstance) SynchronizeMappings(ebpf interpreter.EbpfHandler,
if m.IsAnonymous() {
continue
}
if !strings.HasSuffix(m.Path.String(), ".dll") {
if !strings.HasSuffix(m.Path, ".dll") {
continue
}

Expand Down
4 changes: 2 additions & 2 deletions interpreter/dotnet/pe.go
Original file line number Diff line number Diff line change
Expand Up @@ -1209,7 +1209,7 @@ func (pc *peCache) init() {
pc.peInfoCache = peInfoCache
}

func (pc *peCache) Get(pr process.Process, mapping *process.Mapping) *peInfo {
func (pc *peCache) Get(pr process.Process, mapping *process.RawMapping) *peInfo {
key := mapping.GetOnDiskFileIdentifier()
lastModified := pr.GetMappingFileLastModified(mapping)
if info, ok := pc.peInfoCache.Get(key); ok && info.lastModified == lastModified {
Expand Down Expand Up @@ -1243,7 +1243,7 @@ func (pc *peCache) Get(pr process.Process, mapping *process.Mapping) *peInfo {
if info.err == nil {
mf := libpf.NewFrameMappingFile(libpf.FrameMappingFileData{
FileID: fileID,
FileName: libpf.Intern(path.Base(mapping.Path.String())),
FileName: libpf.Intern(path.Base(mapping.Path)),
GnuBuildID: info.guid,
})
info.mapping = libpf.NewFrameMapping(libpf.FrameMappingData{
Expand Down
2 changes: 1 addition & 1 deletion interpreter/hotspot/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -854,7 +854,7 @@ func (d *hotspotInstance) updateStubMappings(vmd *hotspotVMData,
}

func (d *hotspotInstance) SynchronizeMappings(ebpf interpreter.EbpfHandler,
_ reporter.ExecutableReporter, pr process.Process, _ []process.Mapping,
_ reporter.ExecutableReporter, pr process.Process, _ []process.RawMapping,
) error {
vmd, err := d.d.GetOrInit(func() (hotspotVMData, error) { return d.d.newVMData(d.rm, d.bias) })
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion interpreter/instancestubs.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type InstanceStubs struct {
}

func (is *InstanceStubs) SynchronizeMappings(EbpfHandler, reporter.ExecutableReporter,
process.Process, []process.Mapping) error {
process.Process, []process.RawMapping) error {
return nil
}

Expand Down
2 changes: 1 addition & 1 deletion interpreter/multi.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func (m *MultiInstance) Detach(ebpf EbpfHandler, pid libpf.PID) error {

// SynchronizeMappings synchronizes mappings for all interpreter instances.
func (m *MultiInstance) SynchronizeMappings(ebpf EbpfHandler,
exeReporter reporter.ExecutableReporter, pr process.Process, mappings []process.Mapping,
exeReporter reporter.ExecutableReporter, pr process.Process, mappings []process.RawMapping,
) error {
var errs []error
for _, instance := range m.instances {
Expand Down
8 changes: 4 additions & 4 deletions interpreter/nodev8/v8.go
Original file line number Diff line number Diff line change
Expand Up @@ -500,8 +500,8 @@ type v8Instance struct {
addrToSource *freelru.LRU[libpf.Address, *v8Source]
addrToType *freelru.LRU[libpf.Address, uint16]

// mappings is indexed by the Mapping to its generation
mappings map[process.Mapping]*uint32
// mappings is indexed by the RawMapping to its generation
mappings map[process.RawMapping]*uint32
// prefixes is indexed by the prefix added to ebpf maps (to be cleaned up) to its generation
prefixes map[lpm.Prefix]*uint32
// mappingGeneration is the current generation (so old entries can be pruned)
Expand Down Expand Up @@ -555,7 +555,7 @@ func (i *v8Instance) Detach(ebpf interpreter.EbpfHandler, pid libpf.PID) error {
}

func (i *v8Instance) SynchronizeMappings(ebpf interpreter.EbpfHandler,
_ reporter.ExecutableReporter, pr process.Process, mappings []process.Mapping,
_ reporter.ExecutableReporter, pr process.Process, mappings []process.RawMapping,
) error {
pid := pr.PID()
i.mappingGeneration++
Expand Down Expand Up @@ -1841,7 +1841,7 @@ func (d *v8Data) Attach(ebpf interpreter.EbpfHandler, pid libpf.PID, _ libpf.Add
return &v8Instance{
d: d,
rm: rm,
mappings: make(map[process.Mapping]*uint32),
mappings: make(map[process.RawMapping]*uint32),
prefixes: make(map[lpm.Prefix]*uint32),
addrToString: addrToString,
addrToCode: addrToCode,
Expand Down
2 changes: 1 addition & 1 deletion interpreter/php/opcache.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ func (i *opcacheInstance) Detach(ebpf interpreter.EbpfHandler, pid libpf.PID) er
}

func (i *opcacheInstance) SynchronizeMappings(ebpf interpreter.EbpfHandler,
_ reporter.ExecutableReporter, pr process.Process, _ []process.Mapping,
_ reporter.ExecutableReporter, pr process.Process, _ []process.RawMapping,
) error {
if i.prefixes != nil {
// Already attached
Expand Down
18 changes: 14 additions & 4 deletions interpreter/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,21 @@ type Instance interface {
// simple interpreters can use the global Data also as the Instance implementation.
Detach(ebpf EbpfHandler, pid libpf.PID) error

// SynchronizeMappings is called when the processmanager has reread process memory
// mappings. Interpreters not needing to process these events can simply ignore them
// by just returning a nil.
// SynchronizeMappings is called when the processmanager has reread process
// memory mappings. The mappings slice contains only the subset of mappings
// that are relevant to interpreters: executable anonymous mappings (for JIT
// engines like HotSpot, V8, BEAM) and DLL file-backed mappings (for .NET
// PE assemblies). The processmanager decides which mappings are included;
// this can be made more dynamic in the future if needed.
//
// The mappings are in /proc/PID/maps order (ascending by virtual address)
// but are NOT sorted by any other criteria. Interpreters that need a
// specific ordering must sort locally.
//
// Interpreters not needing to process these events can simply ignore them
// by returning nil.
SynchronizeMappings(ebpf EbpfHandler, exeReporter reporter.ExecutableReporter,
pr process.Process, mappings []process.Mapping) error
pr process.Process, mappings []process.RawMapping) error

// UpdateLibcInfo is called when the process C-library related
// introspection data has been updated.
Expand Down
33 changes: 19 additions & 14 deletions process/coredump.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ type CoredumpProcess struct {
machineData MachineData

// mappings contains the parsed mappings.
mappings []Mapping
mappings []RawMapping

// threadInfo contains the parsed thread info.
threadInfo []ThreadInfo
Expand Down Expand Up @@ -145,7 +145,7 @@ func OpenCoredumpFile(f *pfelf.File) (*CoredumpProcess, error) {
cd := &CoredumpProcess{
File: f,
files: make(map[string]*CoredumpFile),
mappings: make([]Mapping, 0, len(f.Progs)),
mappings: make([]RawMapping, 0, len(f.Progs)),
threadInfo: make([]ThreadInfo, 0, 8),
}
cd.machineData.Machine = cd.Machine
Expand All @@ -157,7 +157,7 @@ func OpenCoredumpFile(f *pfelf.File) (*CoredumpProcess, error) {
for i := range f.Progs {
p := &f.Progs[i]
if p.Type == elf.PT_LOAD && p.Flags != 0 {
m := Mapping{
m := RawMapping{
Vaddr: p.Vaddr,
Length: p.Memsz,
Flags: p.Flags,
Expand Down Expand Up @@ -269,9 +269,14 @@ func (cd *CoredumpProcess) GetExe() (libpf.String, error) {
return cd.fname, nil
}

// GetMappings implements the Process interface.
func (cd *CoredumpProcess) GetMappings() ([]Mapping, uint32, error) {
return cd.mappings, 0, nil
// IterateMappings implements the Process interface.
func (cd *CoredumpProcess) IterateMappings(callback func(m RawMapping) bool) (uint32, error) {
for _, m := range cd.mappings {
if !callback(m) {
return 0, ErrCallbackStopped
}
}
return 0, nil
}

// GetThreadInfo implements the Process interface.
Expand All @@ -280,26 +285,26 @@ func (cd *CoredumpProcess) GetThreads() ([]ThreadInfo, error) {
}

// OpenMappingFile implements the Process interface.
func (cd *CoredumpProcess) OpenMappingFile(_ *Mapping) (ReadAtCloser, error) {
func (cd *CoredumpProcess) OpenMappingFile(_ *RawMapping) (ReadAtCloser, error) {
// Coredumps do not contain the original backing files.
return nil, errors.New("coredump does not support opening backing file")
}

// GetMappingFileLastModified implements the Process interface.
func (cd *CoredumpProcess) GetMappingFileLastModified(_ *Mapping) int64 {
func (cd *CoredumpProcess) GetMappingFileLastModified(_ *RawMapping) int64 {
return 0
}

// CalculateMappingFileID implements the Process interface.
func (cd *CoredumpProcess) CalculateMappingFileID(m *Mapping) (libpf.FileID, error) {
func (cd *CoredumpProcess) CalculateMappingFileID(m *RawMapping) (libpf.FileID, error) {
// It is not possible to calculate the real FileID as the section headers
// are likely missing. So just return a synthesized FileID.
vaddr := make([]byte, 8)
binary.LittleEndian.PutUint64(vaddr, m.Vaddr)

h := fnv.New128a()
_, _ = h.Write(vaddr)
_, _ = h.Write([]byte(m.Path.String()))
_, _ = h.Write([]byte(m.Path))
return libpf.FileIDFromBytes(h.Sum(nil))
}

Expand Down Expand Up @@ -399,7 +404,7 @@ func (cd *CoredumpProcess) parseMappings(desc []byte,
cf.Mappings = append(cf.Mappings, cm)

mapping := &cd.mappings[m.mappingIndex]
mapping.Path = cf.Name
mapping.Path = cf.Name.String()
mapping.FileOffset = entry.FileOffset * hdr.PageSize
// Synthesize non-zero device and inode indicating this is a filebacked mapping.
mapping.Device = 1
Expand All @@ -408,14 +413,14 @@ func (cd *CoredumpProcess) parseMappings(desc []byte,
// This file backed mapping is not in the coredump LOAD tables
// Likely a executable mapping excluded by core_filter. Construct
// the mappings assuming R+X.
cd.mappings = append(cd.mappings, Mapping{
cd.mappings = append(cd.mappings, RawMapping{
Vaddr: entry.Start,
Length: entry.End - entry.Start,
Flags: elf.PF_R + elf.PF_X,
FileOffset: entry.FileOffset * hdr.PageSize,
Device: 1,
Inode: cf.inode,
Path: cf.Name,
Path: cf.Name.String(),
})
}
strs = strs[fnlen+1:]
Expand All @@ -438,7 +443,7 @@ func (cd *CoredumpProcess) parseAuxVector(desc []byte, vaddrToMappings map[uint6
vm.Inode = vdsoInode
vm.Path = VdsoPathName

cf := cd.getFile(vm.Path.String())
cf := cd.getFile(vm.Path)
cm := CoredumpMapping{
Prog: m.prog,
File: cf,
Expand Down
Loading
Loading