Skip to content

Commit 1d6833a

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

1 file changed

Lines changed: 50 additions & 28 deletions

File tree

data/toolbox/stack.py

Lines changed: 50 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,53 @@ 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+
print(f"DEBUG: Got execution context from ruby_current_ec: {ec}", file=sys.stderr)
590+
return ec
591+
else:
592+
print(f"DEBUG: ruby_current_ec returned null/zero: {ec}", file=sys.stderr)
593+
except debugger.Error as e:
594+
print(f"DEBUG: ruby_current_ec failed: {e}", file=sys.stderr)
595+
596+
# Fallback to rb_current_ec_noinline() function
597+
try:
598+
ec = debugger.parse_and_eval('rb_current_ec_noinline()')
599+
if ec is not None and int(ec) != 0:
600+
print(f"DEBUG: Got execution context from rb_current_ec_noinline(): {ec}", file=sys.stderr)
601+
return ec
602+
else:
603+
print(f"DEBUG: rb_current_ec_noinline() returned null/zero: {ec}", file=sys.stderr)
604+
except debugger.Error as e:
605+
print(f"DEBUG: rb_current_ec_noinline() failed: {e}", file=sys.stderr)
606+
607+
# Last resort: rb_current_ec() (macOS-specific)
608+
try:
609+
ec = debugger.parse_and_eval('rb_current_ec()')
610+
if ec is not None and int(ec) != 0:
611+
print(f"DEBUG: Got execution context from rb_current_ec(): {ec}", file=sys.stderr)
612+
return ec
613+
else:
614+
print(f"DEBUG: rb_current_ec() returned null/zero: {ec}", file=sys.stderr)
615+
except debugger.Error as e:
616+
print(f"DEBUG: rb_current_ec() failed: {e}", file=sys.stderr)
617+
618+
print("DEBUG: All methods to get execution context failed", file=sys.stderr)
619+
return None
620+
574621
def invoke(self, arg, from_tty):
575622
"""Execute the stack trace command."""
576623
try:
@@ -602,38 +649,13 @@ def invoke(self, arg, from_tty):
602649
print()
603650

604651
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
652+
ec = self._get_current_execution_context()
631653

632-
if ec is None or int(ec) == 0:
654+
if ec is None:
633655
print("Error: No execution context available")
634656
print("Either select a fiber with 'rb-fiber-switch' or ensure Ruby is running")
635657
print("\nTroubleshooting:")
636-
print(" - Check if Ruby symbols are loaded: image lookup -n rb_current_ec_noinline")
658+
print(" - Check if Ruby symbols are loaded")
637659
print(" - Ensure the process is stopped at a Ruby frame")
638660
return
639661

0 commit comments

Comments
 (0)