@@ -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
572582func (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