@@ -86,7 +86,8 @@ const (
8686
8787var (
8888 // regex to identify the Ruby interpreter executable
89- rubyRegex = regexp .MustCompile (`^(?:.*/)?libruby(?:-.*)?\.so\.(\d)\.(\d)\.(\d)$` )
89+ libRubyRegex = regexp .MustCompile (`^(?:.*/)?libruby(?:-.*)?\.so\.(\d)\.(\d)\.(\d)$` )
90+ binRubyRegex = regexp .MustCompile (`^(?:.*/)?(?:bin/)?ruby$` )
9091 // regex to extract a version from a string
9192 rubyVersionRegex = regexp .MustCompile (`^(\d)\.(\d)\.(\d)$` )
9293
@@ -114,6 +115,9 @@ type rubyData struct {
114115 // Address to the ruby_current_ec variable in TLS, as an offset from tpbase
115116 currentEcTpBaseTlsOffset libpf.Address
116117
118+ // In local exec / static mode, the EC is an absolute offset from tpbase
119+ absoluteTpBaseOffset int64
120+
117121 // Address to global symbols, for id to string mappings
118122 globalSymbolsAddr libpf.Address
119123
@@ -291,10 +295,14 @@ func (r *rubyData) String() string {
291295func (r * rubyData ) Attach (ebpf interpreter.EbpfHandler , pid libpf.PID , bias libpf.Address ,
292296 rm remotememory.RemoteMemory ,
293297) (interpreter.Instance , error ) {
294- var tlsOffset uint64
295- if r .currentEcTpBaseTlsOffset != 0 {
298+ var tlsOffset int64
299+ if r .absoluteTpBaseOffset == 0 && r . currentEcTpBaseTlsOffset != 0 {
296300 // Read TLS offset from the TLS descriptor.
297- tlsOffset = rm .Uint64 (bias + r .currentEcTpBaseTlsOffset + 8 )
301+ tlsOffset = int64 (rm .Uint64 (bias + r .currentEcTpBaseTlsOffset + 8 ))
302+ }
303+
304+ if r .absoluteTpBaseOffset != 0 {
305+ tlsOffset = r .absoluteTpBaseOffset
298306 }
299307
300308 var modId uint64
@@ -1371,7 +1379,8 @@ func determineRubyVersion(ef *pfelf.File) (uint32, error) {
13711379}
13721380
13731381func Loader (ebpf interpreter.EbpfHandler , info * interpreter.LoaderInfo ) (interpreter.Data , error ) {
1374- if ! rubyRegex .MatchString (info .FileName ()) {
1382+ var isBinRuby = binRubyRegex .MatchString (info .FileName ())
1383+ if ! libRubyRegex .MatchString (info .FileName ()) && ! isBinRuby {
13751384 return nil , nil
13761385 }
13771386
@@ -1414,6 +1423,7 @@ func Loader(ebpf interpreter.EbpfHandler, info *interpreter.LoaderInfo) (interpr
14141423
14151424 var globalSymbols libpf.SymbolValue
14161425 var currentEcTpBaseTlsOffset libpf.Address
1426+ var absoluteTpBaseOffset int64
14171427 var interpRanges []util.Range
14181428
14191429 globalSymbolsName := libpf .SymbolName ("ruby_global_symbols" )
@@ -1512,12 +1522,21 @@ func Loader(ebpf interpreter.EbpfHandler, info *interpreter.LoaderInfo) (interpr
15121522 log .Warnf ("failed to mod offset: %v" , err )
15131523 }
15141524
1525+ if isBinRuby {
1526+ offset , err := extractEcOffset (ef )
1527+ if err != nil {
1528+ return nil , fmt .Errorf ("unable to extract ec offset for static ruby %v" , err )
1529+ }
1530+ absoluteTpBaseOffset = offset
1531+ }
1532+
15151533 log .Debugf ("Discovered EC tls tpbase offset %x, fallback ctx %x, interp ranges: %v, global symbols: %x" , currentEcTpBaseTlsOffset , currentCtxPtr , interpRanges , globalSymbols )
15161534
15171535 rid := & rubyData {
15181536 version : version ,
15191537 currentEcTpBaseTlsOffset : libpf .Address (currentEcTpBaseTlsOffset ),
15201538 tlsModuleIdOffset : tlsModuleIdOffset ,
1539+ absoluteTpBaseOffset : absoluteTpBaseOffset ,
15211540 currentEcTlsOffset : libpf .Address (currentEcSymbolAddress ),
15221541 currentCtxPtr : libpf .Address (currentCtxPtr ),
15231542 hasGlobalSymbols : globalSymbols != 0 ,
0 commit comments