Skip to content

Commit 797ce5f

Browse files
committed
Resolve file names
1 parent b5d3122 commit 797ce5f

File tree

1 file changed

+48
-10
lines changed

1 file changed

+48
-10
lines changed

interpreter/beam/beam.go

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -382,14 +382,18 @@ func (i *beamInstance) Symbolize(symbolReporter reporter.SymbolReporter, frame *
382382
mfaName = fmt.Sprintf("%s:%s/%d", moduleName, functionName, arity)
383383
}
384384

385-
lineNumber := i.findFileLocation(codeHeader, functionIndex, pc)
385+
fileName, lineNumber, err := i.findFileLocation(codeHeader, functionIndex, pc)
386+
if err != nil {
387+
return err
388+
}
386389

387-
log.Warnf("BEAM Found function %s at line %d", mfaName, lineNumber)
390+
log.Warnf("BEAM Found function %s at %s:%d", mfaName, fileName, lineNumber)
388391
frameID := libpf.NewFrameID(libpf.NewFileID(uint64(moduleID), 0x0), libpf.AddressOrLineno((uint64(functionID)<<32)+uint64(arity)))
389392

390393
symbolReporter.FrameMetadata(&reporter.FrameMetadataArgs{
391394
FrameID: frameID,
392395
FunctionName: mfaName,
396+
SourceFile: fileName,
393397
SourceLine: libpf.SourceLineno(lineNumber),
394398
})
395399
trace.AppendFrameID(libpf.BEAMFrame, frameID)
@@ -427,7 +431,7 @@ func (i *beamInstance) findCodeHeader(pc libpf.Address) (codeHeader libpf.Addres
427431
lowIdx = midIdx + 1
428432
} else {
429433
codeHeader = midStart
430-
log.Warnf("BEAM codeHeader[%d] range: 0x%x - 0x%x (%d)", midIdx, midStart, midEnd, midEnd-midStart)
434+
// log.Warnf("BEAM codeHeader[%d] range: 0x%x - 0x%x (%d)", midIdx, midStart, midEnd, midEnd-midStart)
431435
break
432436
}
433437
}
@@ -508,7 +512,7 @@ func (i *beamInstance) findMFA(pc libpf.Address, codeHeader libpf.Address) (func
508512
functionID := i.rm.Uint32(ertsCodeInfo + libpf.Address(16+8))
509513
arity := i.rm.Uint32(ertsCodeInfo + libpf.Address(16+16))
510514

511-
log.Warnf("BEAM MFA range: 0x%x - 0x%x (%d)", midStart, midEnd, midEnd-midStart)
515+
// log.Warnf("BEAM MFA range: 0x%x - 0x%x (%d)", midStart, midEnd, midEnd-midStart)
512516
return functionIndex, moduleID, functionID, arity, nil
513517
}
514518
}
@@ -517,7 +521,7 @@ func (i *beamInstance) findMFA(pc libpf.Address, codeHeader libpf.Address) (func
517521
return 0, 0, 0, 0, fmt.Errorf("BEAM unable to find the MFA for PC 0x%x in expected code range (0x%x - 0x%x)", pc, lowStart, highEnd)
518522
}
519523

520-
func (i *beamInstance) findFileLocation(codeHeader libpf.Address, functionIndex uint64, pc libpf.Address) uint64 {
524+
func (i *beamInstance) findFileLocation(codeHeader libpf.Address, functionIndex uint64, pc libpf.Address) (fileName string, lineNumber uint64, err error) {
521525
lineTable := i.rm.Ptr(codeHeader + libpf.Address(72))
522526

523527
// `lineTable` points to a table of `BeamCodeLineTab_` structs:
@@ -539,7 +543,7 @@ func (i *beamInstance) findFileLocation(codeHeader libpf.Address, functionIndex
539543
lineLow := i.rm.Ptr(lineTable + libpf.Address(8*functionIndex+24))
540544
lineHigh := i.rm.Ptr(lineTable + libpf.Address(8*(functionIndex+1)+24))
541545

542-
log.Warnf("BEAM line range for functionIndex %d: (0x%x - 0x%x)", functionIndex, lineLow, lineHigh)
546+
// log.Warnf("BEAM line range for functionIndex %d: (0x%x - 0x%x)", functionIndex, lineLow, lineHigh)
543547

544548
// We need to align the lineMid values on 8-byte address boundaries
545549
bitmask := libpf.Address(^(uint64(0xf)))
@@ -555,18 +559,24 @@ func (i *beamInstance) findFileLocation(codeHeader libpf.Address, functionIndex
555559
locSize := i.rm.Uint32(lineTable + libpf.Address(8))
556560
locTab := i.rm.Ptr(lineTable + libpf.Address(16))
557561
locAddr := locTab + libpf.Address(locSize*locIndex)
558-
log.Warnf("BEAM locIndex: %d, locSize: %d, locAddr: %x", locIndex, locSize, locAddr)
562+
// log.Warnf("BEAM locIndex: %d, locSize: %d, locAddr: %x", locIndex, locSize, locAddr)
563+
loc := uint64(0)
559564
if locSize == 2 {
560-
return uint64(i.rm.Uint16(locAddr))
565+
loc = uint64(i.rm.Uint16(locAddr))
561566
} else {
562-
return uint64(i.rm.Uint32(locAddr))
567+
loc = uint64(i.rm.Uint32(locAddr))
563568
}
569+
fnameIndex := loc >> 24
570+
fileNamePtr := libpf.Address(i.rm.Uint64(lineTable) + 8*fnameIndex)
571+
fileName = i.readErlangString(libpf.Address(i.rm.Uint64(fileNamePtr)), 256)
572+
573+
return fileName, loc & ((1 << 24) - 1), nil
564574
} else {
565575
lineLow = lineMid + 8
566576
}
567577
}
568578

569-
return 0
579+
return "", 0, fmt.Errorf("BEAM unable to find file and line number")
570580
}
571581

572582
func (i *beamInstance) lookupAtom(index uint32) (string, error) {
@@ -607,3 +617,31 @@ func (i *beamInstance) lookupAtom(index uint32) (string, error) {
607617

608618
return string(name), nil
609619
}
620+
621+
// TODO: read these values from the symbol table
622+
const (
623+
ETP_NIL = libpf.Address(0x3B)
624+
ETP_PTR_MASK = ^libpf.Address(0x3)
625+
)
626+
627+
func (i *beamInstance) readErlangString(eterm libpf.Address, maxLength uint64) string {
628+
result := strings.Builder{}
629+
length := uint64(0)
630+
631+
for eterm != ETP_NIL && length < maxLength {
632+
charAddr := eterm & ETP_PTR_MASK
633+
charValue := i.rm.Uint64(charAddr)
634+
char := uint8(charValue >> 4)
635+
result.WriteByte(char)
636+
length++
637+
nextAddr := libpf.Address((eterm & ETP_PTR_MASK) + 8)
638+
eterm = libpf.Address(i.rm.Uint64(nextAddr))
639+
// log.Warnf("BEAM charAddr: %x, charValue: %x, char: %c, nextAddr: %x", charAddr, charValue, char, nextAddr)
640+
}
641+
642+
if length > maxLength {
643+
return result.String() + "..."
644+
}
645+
646+
return result.String()
647+
}

0 commit comments

Comments
 (0)