Skip to content

Commit ef92f5b

Browse files
committed
Fix ec lookup on 3.2.
1 parent cb5e08b commit ef92f5b

1 file changed

Lines changed: 40 additions & 28 deletions

File tree

data/toolbox/stack.py

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,43 @@ def usage(self):
571571
print(" rb-stack-trace # Show backtrace for current fiber/thread")
572572
print(" rb-stack-trace --values # Show backtrace with stack VALUEs")
573573

574+
def _get_current_execution_context(self):
575+
"""Get the current execution context from the running thread.
576+
577+
Tries multiple approaches in order of preference:
578+
1. ruby_current_ec - TLS variable (works in GDB, some LLDB)
579+
2. rb_current_ec_noinline() - function call (works in most cases)
580+
3. rb_current_ec() - macOS-specific function
581+
582+
Returns:
583+
Execution context value, or None if not available
584+
"""
585+
# Try ruby_current_ec variable first
586+
try:
587+
ec = debugger.parse_and_eval('ruby_current_ec')
588+
if ec is not None and int(ec) != 0:
589+
return ec
590+
except debugger.Error:
591+
pass
592+
593+
# Fallback to rb_current_ec_noinline() function
594+
try:
595+
ec = debugger.parse_and_eval('rb_current_ec_noinline()')
596+
if ec is not None and int(ec) != 0:
597+
return ec
598+
except debugger.Error:
599+
pass
600+
601+
# Last resort: rb_current_ec() (macOS-specific)
602+
try:
603+
ec = debugger.parse_and_eval('rb_current_ec()')
604+
if ec is not None and int(ec) != 0:
605+
return ec
606+
except debugger.Error:
607+
pass
608+
609+
return None
610+
574611
def invoke(self, arg, from_tty):
575612
"""Execute the stack trace command."""
576613
try:
@@ -602,38 +639,13 @@ def invoke(self, arg, from_tty):
602639
print()
603640

604641
try:
605-
# Get current execution context from the running thread
606-
# The approach depends on the debugger:
607-
# - GDB can access thread-local variable ruby_current_ec directly
608-
# - LLDB cannot access TLS variables, must use rb_current_ec_noinline()
609-
ec = None
610-
611-
if debugger.DEBUGGER_NAME == 'gdb':
612-
# GDB: Try direct TLS variable access first (faster)
613-
try:
614-
ec = debugger.parse_and_eval('ruby_current_ec')
615-
except debugger.Error:
616-
# Fallback to function call
617-
try:
618-
ec = debugger.parse_and_eval('rb_current_ec_noinline()')
619-
except debugger.Error:
620-
pass
621-
else:
622-
# LLDB: Must use function call (cannot access TLS variables)
623-
try:
624-
ec = debugger.parse_and_eval('rb_current_ec_noinline()')
625-
except debugger.Error:
626-
# Fallback attempts for macOS or other platforms
627-
try:
628-
ec = debugger.parse_and_eval('rb_current_ec()')
629-
except debugger.Error:
630-
pass
642+
ec = self._get_current_execution_context()
631643

632-
if ec is None or int(ec) == 0:
644+
if ec is None:
633645
print("Error: No execution context available")
634646
print("Either select a fiber with 'rb-fiber-switch' or ensure Ruby is running")
635647
print("\nTroubleshooting:")
636-
print(" - Check if Ruby symbols are loaded: image lookup -n rb_current_ec_noinline")
648+
print(" - Check if Ruby symbols are loaded")
637649
print(" - Ensure the process is stopped at a Ruby frame")
638650
return
639651

0 commit comments

Comments
 (0)