Skip to content

Commit afa5580

Browse files
committed
Clean up after rebase
1 parent 39d3d4a commit afa5580

File tree

2 files changed

+11
-164
lines changed

2 files changed

+11
-164
lines changed

interpreter/beam/beam.go

Lines changed: 9 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ package beam // import "go.opentelemetry.io/ebpf-profiler/interpreter/beam"
1010

1111
import (
1212
"fmt"
13-
"os"
1413
"regexp"
1514
"strconv"
1615
"strings"
@@ -35,10 +34,9 @@ import "C"
3534

3635
var (
3736
// regex for matching the process name
38-
beamRegex = regexp.MustCompile(`beam.smp`)
39-
_ interpreter.Data = &beamData{}
40-
_ interpreter.Instance = &beamInstance{}
41-
BogusFileID = libpf.NewFileID(0xf00d, 0x1001)
37+
beamRegex = regexp.MustCompile(`beam.smp`)
38+
_ interpreter.Data = &beamData{}
39+
_ interpreter.Instance = &beamInstance{}
4240
)
4341

4442
type beamData struct {
@@ -58,24 +56,6 @@ type beamInstance struct {
5856
rangesPtr libpf.Address
5957
codeIndexPtr libpf.Address
6058
atomTable libpf.Address
61-
// mappings is indexed by the Mapping to its generation
62-
mappings map[process.Mapping]*uint32
63-
// prefixes is indexed by the prefix added to ebpf maps (to be cleaned up) to its generation
64-
prefixes map[lpm.Prefix]*uint32
65-
// mappingGeneration is the current generation (so old entries can be pruned)
66-
mappingGeneration uint32
67-
}
68-
69-
type beamRange struct {
70-
start libpf.Address
71-
end libpf.Address
72-
}
73-
74-
type beamRanges struct {
75-
modules *beamRange
76-
n uint64
77-
allocated uint64
78-
mid libpf.Address
7959
}
8060

8161
func readSymbolValue(ef *pfelf.File, name libpf.SymbolName) ([]byte, error) {
@@ -118,7 +98,6 @@ func Loader(ebpf interpreter.EbpfHandler, info *interpreter.LoaderInfo) (interpr
11898
if matches == nil {
11999
return nil, nil
120100
}
121-
log.Infof("BEAM interpreter found: %v", matches)
122101

123102
ef, err := info.GetELF()
124103
if err != nil {
@@ -135,15 +114,6 @@ func Loader(ebpf interpreter.EbpfHandler, info *interpreter.LoaderInfo) (interpr
135114
return nil, err
136115
}
137116

138-
interpRanges, err := info.GetSymbolAsRanges(libpf.SymbolName("process_main"))
139-
if err != nil {
140-
return nil, err
141-
}
142-
143-
if err = ebpf.UpdateInterpreterOffsets(support.ProgUnwindBEAM, info.FileID(), interpRanges); err != nil {
144-
return nil, err
145-
}
146-
147117
// "the_active_code_index" and "r" symbols are from:
148118
// https://github.com/erlang/otp/blob/OTP-27.2.4/erts/emulator/beam/beam_ranges.c#L62
149119
the_active_code_index, err := ef.LookupSymbolAddress("the_active_code_index")
@@ -170,13 +140,13 @@ func Loader(ebpf interpreter.EbpfHandler, info *interpreter.LoaderInfo) (interpr
170140
erts_atom_table: uint64(erts_atom_table),
171141
}
172142

173-
log.Infof("BEAM loaded %v", d)
143+
log.Infof("BEAM loaded, OTP version %d", otpVersion)
174144

175145
return d, nil
176146
}
177147

178148
func (d *beamData) Attach(ebpf interpreter.EbpfHandler, pid libpf.PID, bias libpf.Address, rm remotememory.RemoteMemory) (interpreter.Instance, error) {
179-
log.Infof("BEAM interpreter attaching, bias: %x", bias)
149+
log.Infof("BEAM attaching, bias: 0x%x", bias)
180150

181151
data := C.BEAMProcInfo{
182152
version: C.u32(d.version),
@@ -194,16 +164,13 @@ func (d *beamData) Attach(ebpf interpreter.EbpfHandler, pid libpf.PID, bias libp
194164
rangesPtr: bias + libpf.Address(d.r),
195165
codeIndexPtr: bias + libpf.Address(d.the_active_code_index),
196166
atomTable: bias + libpf.Address(d.erts_atom_table),
197-
mappings: make(map[process.Mapping]*uint32),
198-
prefixes: make(map[lpm.Prefix]*uint32),
199167
}, nil
200168
}
201169

202170
func (d *beamData) Unload(_ interpreter.EbpfHandler) {
203171
}
204172

205-
func (i *beamInstance) SynchronizeMappingsFromBEAMRanges(ebpf interpreter.EbpfHandler,
206-
_ reporter.SymbolReporter, pr process.Process, mappings []process.Mapping) error {
173+
func (i *beamInstance) SynchronizeMappings(ebpf interpreter.EbpfHandler, _ reporter.SymbolReporter, pr process.Process, mappings []process.Mapping) error {
207174
pid := pr.PID()
208175

209176
codeIndex := i.rm.Uint64(i.codeIndexPtr)
@@ -215,6 +182,9 @@ func (i *beamInstance) SynchronizeMappingsFromBEAMRanges(ebpf interpreter.EbpfHa
215182
high := i.rm.Ptr(i.rm.Ptr(activeRanges) + libpf.Address(16*n) + 8)
216183

217184
log.Infof("Enabling BEAM for %#x - %#x", low, high)
185+
186+
// TODO: I think this is resulting in the following error (figure out why):
187+
// ERRO[0004] Failed to handle new anonymous mapping for PID 375011: update: key already exists
218188
prefixes, err := lpm.CalculatePrefixList(uint64(low), uint64(high))
219189
if err != nil {
220190
return fmt.Errorf("new anonymous mapping lpm failure %#x - %#x", low, high)
@@ -229,121 +199,6 @@ func (i *beamInstance) SynchronizeMappingsFromBEAMRanges(ebpf interpreter.EbpfHa
229199
return nil
230200
}
231201

232-
func (i *beamInstance) SynchronizeMappings(ebpf interpreter.EbpfHandler,
233-
_ reporter.SymbolReporter, pr process.Process, mappings []process.Mapping) error {
234-
pid := pr.PID()
235-
i.mappingGeneration++
236-
for idx := range mappings {
237-
m := &mappings[idx]
238-
239-
if !m.IsExecutable() {
240-
continue
241-
}
242-
243-
// log.Infof("Synchronizing executable Mapping %#x/%#x", m.Vaddr, m.Length)
244-
245-
if !m.IsAnonymous() {
246-
continue
247-
}
248-
249-
if _, exists := i.mappings[*m]; exists {
250-
*i.mappings[*m] = i.mappingGeneration
251-
continue
252-
}
253-
254-
// Generate a new uint32 pointer which is shared for mapping and the prefixes it owns
255-
// so updating the mapping above will reflect to prefixes also.
256-
mappingGeneration := i.mappingGeneration
257-
i.mappings[*m] = &mappingGeneration
258-
259-
log.Infof("Enabling BEAM for range %#x/%#x", m.Vaddr, m.Length)
260-
261-
prefixes, err := lpm.CalculatePrefixList(m.Vaddr, m.Vaddr+m.Length)
262-
if err != nil {
263-
return fmt.Errorf("new anonymous mapping lpm failure %#x/%#x", m.Vaddr, m.Length)
264-
}
265-
266-
for _, prefix := range prefixes {
267-
_, exists := i.prefixes[prefix]
268-
if !exists {
269-
err := ebpf.UpdatePidInterpreterMapping(pid, prefix, support.ProgUnwindBEAM, 0, 0)
270-
if err != nil {
271-
return err
272-
}
273-
}
274-
i.prefixes[prefix] = &mappingGeneration
275-
}
276-
}
277-
278-
// Remove prefixes not seen
279-
for prefix, generationPtr := range i.prefixes {
280-
if *generationPtr == i.mappingGeneration {
281-
continue
282-
}
283-
log.Infof("Delete prefix %#v", prefix)
284-
_ = ebpf.DeletePidInterpreterMapping(pid, prefix)
285-
delete(i.prefixes, prefix)
286-
}
287-
for m, generationPtr := range i.mappings {
288-
if *generationPtr == i.mappingGeneration {
289-
continue
290-
}
291-
log.Infof("Disabling mapping for %#x/%#x", m.Vaddr, m.Length)
292-
delete(i.mappings, m)
293-
}
294-
295-
return nil
296-
}
297-
298-
func (i *beamInstance) SynchronizeMappingsFromJITDump(ebpf interpreter.EbpfHandler,
299-
_ reporter.SymbolReporter, pr process.Process, mappings []process.Mapping) error {
300-
pid := pr.PID()
301-
file, err := os.Open(fmt.Sprintf("/tmp/jit-%d.dump", uint32(pid)))
302-
if err != nil {
303-
return err
304-
}
305-
defer file.Close()
306-
307-
header, err := ReadJITDumpHeader(file)
308-
if err != nil {
309-
return err
310-
}
311-
log.Infof("Parsed header: %v", *header)
312-
313-
for recordHeader, err := ReadJITDumpRecordHeader(file); err == nil; recordHeader, err = ReadJITDumpRecordHeader(file) {
314-
switch recordHeader.ID {
315-
case JITCodeLoad:
316-
record, name, err := ReadJITDumpRecordCodeLoad(file, recordHeader)
317-
if err != nil {
318-
return err
319-
}
320-
321-
log.Infof("JITDump Code Load %s @ 0x%x (%d bytes)", name, record.CodeAddr, record.CodeSize)
322-
323-
prefixes, err := lpm.CalculatePrefixList(record.CodeAddr, record.CodeAddr+record.CodeSize)
324-
if err != nil {
325-
return fmt.Errorf("lpm failure %#x/%#x", record.CodeAddr, record.CodeSize)
326-
}
327-
328-
for _, prefix := range prefixes {
329-
// TODO: Include FileID
330-
err := ebpf.UpdatePidInterpreterMapping(pid, prefix, support.ProgUnwindBEAM, 0, 0)
331-
if err != nil {
332-
return err
333-
}
334-
}
335-
336-
// TODO: remove mappings that have been moved/unloaded
337-
338-
default:
339-
log.Warnf("Ignoring JITDump record type %d", recordHeader.ID)
340-
SkipJITDumpRecord(file, recordHeader)
341-
}
342-
}
343-
344-
return nil
345-
}
346-
347202
func (i *beamInstance) Detach(interpreter.EbpfHandler, libpf.PID) error {
348203
log.Infof("BEAM interpreter detaching")
349204
return nil
@@ -434,7 +289,6 @@ func (i *beamInstance) findCodeHeader(pc libpf.Address) (codeHeader libpf.Addres
434289
lowIdx = midIdx + 1
435290
} else {
436291
codeHeader = midStart
437-
// log.Warnf("BEAM codeHeader[%d] range: 0x%x - 0x%x (%d)", midIdx, midStart, midEnd, midEnd-midStart)
438292
break
439293
}
440294
}
@@ -515,7 +369,6 @@ func (i *beamInstance) findMFA(pc libpf.Address, codeHeader libpf.Address) (func
515369
functionID := i.rm.Uint32(ertsCodeInfo + libpf.Address(16+8))
516370
arity := i.rm.Uint32(ertsCodeInfo + libpf.Address(16+16))
517371

518-
// log.Warnf("BEAM MFA range: 0x%x - 0x%x (%d)", midStart, midEnd, midEnd-midStart)
519372
return functionIndex, moduleID, functionID, arity, nil
520373
}
521374
}
@@ -546,13 +399,10 @@ func (i *beamInstance) findFileLocation(codeHeader libpf.Address, functionIndex
546399
lineLow := i.rm.Ptr(lineTable + libpf.Address(8*functionIndex+24))
547400
lineHigh := i.rm.Ptr(lineTable + libpf.Address(8*(functionIndex+1)+24))
548401

549-
// log.Warnf("BEAM line range for functionIndex %d: (0x%x - 0x%x)", functionIndex, lineLow, lineHigh)
550-
551402
// We need to align the lineMid values on 8-byte address boundaries
552403
bitmask := libpf.Address(^(uint64(0xf)))
553404
for lineHigh > lineLow {
554405
lineMid := lineLow + ((lineHigh-lineLow)/2)&bitmask
555-
// log.Warnf("BEAM lineMid: 0x%x, midRange: (0x%x - 0x%x)", lineMid, i.rm.Ptr(lineMid), i.rm.Ptr(lineMid+libpf.Address(8)))
556406

557407
if pc < i.rm.Ptr(lineMid) {
558408
lineHigh = lineMid
@@ -562,7 +412,6 @@ func (i *beamInstance) findFileLocation(codeHeader libpf.Address, functionIndex
562412
locSize := i.rm.Uint32(lineTable + libpf.Address(8))
563413
locTab := i.rm.Ptr(lineTable + libpf.Address(16))
564414
locAddr := locTab + libpf.Address(locSize*locIndex)
565-
// log.Warnf("BEAM locIndex: %d, locSize: %d, locAddr: %x", locIndex, locSize, locAddr)
566415
loc := uint64(0)
567416
if locSize == 2 {
568417
loc = uint64(i.rm.Uint16(locAddr))
@@ -639,7 +488,6 @@ func (i *beamInstance) readErlangString(eterm libpf.Address, maxLength uint64) s
639488
length++
640489
nextAddr := libpf.Address((eterm & ETP_PTR_MASK) + 8)
641490
eterm = libpf.Address(i.rm.Uint64(nextAddr))
642-
// log.Warnf("BEAM charAddr: %x, charValue: %x, char: %c, nextAddr: %x", charAddr, charValue, char, nextAddr)
643491
}
644492

645493
if length > maxLength {

support/ebpf/beam_tracer.ebpf.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ bpf_map_def SEC("maps") beam_procs = {
1212
.max_entries = 1024,
1313
};
1414

15-
static inline __attribute__((__always_inline__))
16-
ErrorCode unwind_one_beam_frame(PerCPURecord *record, BEAMProcInfo *info, bool top) {
15+
static EBPF_INLINE ErrorCode unwind_one_beam_frame(PerCPURecord *record, BEAMProcInfo *info, bool top) {
1716
UnwindState *state = &record->state;
1817
Trace *trace = &record->trace;
1918
u64 sp = state->sp, fp = state->fp, pc = state->pc;
@@ -57,7 +56,7 @@ ErrorCode unwind_one_beam_frame(PerCPURecord *record, BEAMProcInfo *info, bool t
5756
// unwind_beam is the entry point for tracing when invoked from the native tracer
5857
// or interpreter dispatcher. It does not reset the trace object and will append the
5958
// BEAM stack frames to the trace object for the current CPU.
60-
static inline __attribute__((__always_inline__)) int unwind_beam(struct pt_regs *ctx) {
59+
static EBPF_INLINE int unwind_beam(struct pt_regs *ctx) {
6160
DEBUG_PRINT(">>>>>>>>>>>>>>>>>Unwinding BEAM stack<<<<<<<<<<<<<<<<<");
6261

6362
PerCPURecord *record = get_per_cpu_record();

0 commit comments

Comments
 (0)