@@ -382,14 +382,18 @@ func (i *beamInstance) Symbolize(symbolReporter reporter.SymbolReporter, frame *
382
382
mfaName = fmt .Sprintf ("%s:%s/%d" , moduleName , functionName , arity )
383
383
}
384
384
385
- lineNumber := i .findFileLocation (codeHeader , functionIndex , pc )
385
+ fileName , lineNumber , err := i .findFileLocation (codeHeader , functionIndex , pc )
386
+ if err != nil {
387
+ return err
388
+ }
386
389
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 )
388
391
frameID := libpf .NewFrameID (libpf .NewFileID (uint64 (moduleID ), 0x0 ), libpf .AddressOrLineno ((uint64 (functionID )<< 32 )+ uint64 (arity )))
389
392
390
393
symbolReporter .FrameMetadata (& reporter.FrameMetadataArgs {
391
394
FrameID : frameID ,
392
395
FunctionName : mfaName ,
396
+ SourceFile : fileName ,
393
397
SourceLine : libpf .SourceLineno (lineNumber ),
394
398
})
395
399
trace .AppendFrameID (libpf .BEAMFrame , frameID )
@@ -427,7 +431,7 @@ func (i *beamInstance) findCodeHeader(pc libpf.Address) (codeHeader libpf.Addres
427
431
lowIdx = midIdx + 1
428
432
} else {
429
433
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)
431
435
break
432
436
}
433
437
}
@@ -508,7 +512,7 @@ func (i *beamInstance) findMFA(pc libpf.Address, codeHeader libpf.Address) (func
508
512
functionID := i .rm .Uint32 (ertsCodeInfo + libpf .Address (16 + 8 ))
509
513
arity := i .rm .Uint32 (ertsCodeInfo + libpf .Address (16 + 16 ))
510
514
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)
512
516
return functionIndex , moduleID , functionID , arity , nil
513
517
}
514
518
}
@@ -517,7 +521,7 @@ func (i *beamInstance) findMFA(pc libpf.Address, codeHeader libpf.Address) (func
517
521
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 )
518
522
}
519
523
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 ) {
521
525
lineTable := i .rm .Ptr (codeHeader + libpf .Address (72 ))
522
526
523
527
// `lineTable` points to a table of `BeamCodeLineTab_` structs:
@@ -539,7 +543,7 @@ func (i *beamInstance) findFileLocation(codeHeader libpf.Address, functionIndex
539
543
lineLow := i .rm .Ptr (lineTable + libpf .Address (8 * functionIndex + 24 ))
540
544
lineHigh := i .rm .Ptr (lineTable + libpf .Address (8 * (functionIndex + 1 )+ 24 ))
541
545
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)
543
547
544
548
// We need to align the lineMid values on 8-byte address boundaries
545
549
bitmask := libpf .Address (^ (uint64 (0xf )))
@@ -555,18 +559,24 @@ func (i *beamInstance) findFileLocation(codeHeader libpf.Address, functionIndex
555
559
locSize := i .rm .Uint32 (lineTable + libpf .Address (8 ))
556
560
locTab := i .rm .Ptr (lineTable + libpf .Address (16 ))
557
561
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 )
559
564
if locSize == 2 {
560
- return uint64 (i .rm .Uint16 (locAddr ))
565
+ loc = uint64 (i .rm .Uint16 (locAddr ))
561
566
} else {
562
- return uint64 (i .rm .Uint32 (locAddr ))
567
+ loc = uint64 (i .rm .Uint32 (locAddr ))
563
568
}
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
564
574
} else {
565
575
lineLow = lineMid + 8
566
576
}
567
577
}
568
578
569
- return 0
579
+ return "" , 0 , fmt . Errorf ( "BEAM unable to find file and line number" )
570
580
}
571
581
572
582
func (i * beamInstance ) lookupAtom (index uint32 ) (string , error ) {
@@ -607,3 +617,31 @@ func (i *beamInstance) lookupAtom(index uint32) (string, error) {
607
617
608
618
return string (name ), nil
609
619
}
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