ruby: support EC offset extraction for statically-linked Ruby#1227
Merged
fabled merged 3 commits intoopen-telemetry:mainfrom Mar 19, 2026
Merged
ruby: support EC offset extraction for statically-linked Ruby#1227fabled merged 3 commits intoopen-telemetry:mainfrom
fabled merged 3 commits intoopen-telemetry:mainfrom
Conversation
This was referenced Mar 4, 2026
ruby: support EC offset extraction for statically-linked Ruby
Shopify/opentelemetry-ebpf-profiler#28
Closed
ianks
approved these changes
Mar 6, 2026
ianks
left a comment
There was a problem hiding this comment.
In principle the changes make sense to me. Would recommend a Gopher take a closer look though since my Go knowledge is limited
This was referenced Mar 17, 2026
For statically-linked Ruby binaries (bin/ruby rather than libruby.so), TLS descriptors are not available. Instead, rb_current_ec_noinline accesses the execution context directly via a TP-relative offset (FS:offset on x86_64, MRS tpidr_el0 + ADD on aarch64). This reuses the asm/amd.ExtractTLSOffset and asm/arm.ExtractTLSOffset infrastructure from the Python TLS PR (open-telemetry#1109) to disassemble rb_current_ec_noinline and extract the offset. Also changes current_ec_tpbase_tls_offset from u64 to s64 since static TLS offsets (local exec model) are negative on x86_64. Also adds RUBY_DISABLE_GC env var support to the loop.rb test script to allow capturing coredumps without GC interference.
Adds coredump tests for a statically-linked Ruby 3.4.7 binary on both arm64 and amd64, exercising the binRubyRegex match and extractEcTLSOffset() disassembly path for finding ruby_current_ec via direct TP-relative offset. Captured via gdb attach + breakpoint on rb_vm_exec to ensure a clean snapshot deep in the Ruby VM stack.
a2ccaf1 to
8c2edc7
Compare
florianl
approved these changes
Mar 18, 2026
This was referenced Apr 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Support profiling statically-linked Ruby binaries (
bin/rubywith nolibruby.so) by extracting the execution context (EC) TLS offset directly from therb_current_ec_noinlinefunction's disassembly.Fixes #884
Related to #883 (handles static case, at least for ruby)
Why
The existing Ruby profiler only matches
libruby*.sovia regex and finds the EC via TLSDESC relocations. Statically-linked Ruby has no TLSDESC — insteadrb_current_ec_noinlineaccesses EC directly viaFS:offset(x86_64) orMRS tpidr_el0(aarch64). Without this change, statically-linked Ruby processes produce no Ruby frames at all.How
binRubyRegexto matchbin/rubyin addition tolibruby*.soextractEcTLSOffset()ininterpreter/ruby/ec.gothat disassemblesrb_current_ec_noinlineusing the existingasm/amd.ExtractTLSOffsetandasm/arm.ExtractTLSOffsetinfrastructure from python: get the Thread State from a Thread-local #1109 (Python TLS)VisitSymbolswhen the symbol is LOCAL (not in.dynsym) — fixes a nil pointer panic in the GNU hash lookup pathcurrent_ec_tpbase_tls_offsetfromu64tos64since static TLS offsets are negative on x86_64 (e.g.FS:0xfffffffffffffff8= -8)RUBY_DISABLE_GCenv var support to the coredump test scriptloop.rbNOTE: This depends on coredump artifacts which need to be added to the CI modulestore, they've been uploaded to a shared drive that @florianl has access to. Please re-run CI after uploading these artifacts.