.gdbinit: Read the frame iseq without calling rb_get_cfp_iseq

rb_get_cfp_iseq exists only in builds with YJIT or ZJIT, and gdb cannot call functions on a core file, so rb_ps stopped at the first Ruby frame. Follow CFP_ISEQ() and CFP_PC() with expressions instead, which also fixes the line numbers of ZJIT frames, whose cfp->pc is stale.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Hiroshi SHIBATAandClaude Opus 5.5 committed 2026-10-02 07:16:36 +09:00
1 parent a320eeff00
commit f3e3fb01ac
1 file changed
+26 -5
Notes: git 2026-10-01 22:17:22 +00:00
+26 -5
View File
@@ -972,10 +972,31 @@ document rb_ps_vm
Dump all threads in a (rb_vm_t*) and their callstacks
end
# CFP_ISEQ() and CFP_PC() in zjit.h, written without calling a function so
# that they work on a core file too. Sets $iseq and $cfp_pc.
define cfp_iseq_pc
set $iseq = $arg0->_iseq
set $cfp_pc = $arg0->pc
python gdb.set_convenience_variable('zjit_built', gdb.lookup_global_symbol('rb_zjit_entry') is not None)
if $zjit_built
if rb_zjit_entry && $arg0->jit_return
if (VALUE)$arg0->jit_return == 1
# ZJIT_JIT_RETURN_C_FRAME
set $iseq = 0
set $cfp_pc = 0
else
set $jit_frame = ((zjit_jit_frame_t **)$arg0->jit_return)[-1]
set $iseq = $jit_frame->iseq
set $cfp_pc = $jit_frame->pc
end
end
end
end
define print_lineno
set $cfp = $arg0
set $iseq = rb_get_cfp_iseq($cfp)
set $pos = $cfp->pc - $iseq->body->iseq_encoded
cfp_iseq_pc $cfp
set $pos = $cfp_pc - $iseq->body->iseq_encoded
if $pos != 0
set $pos = $pos - 1
end
@@ -1098,8 +1119,8 @@ define rb_ps_thread
set $cfp = $ps_thread_th->ec->cfp
set $cfpend = (rb_control_frame_t *)($ps_thread_th->ec->vm_stack + $ps_thread_th->ec->vm_stack_size)-1
while $cfp < $cfpend
if $cfp->_iseq
set $iseq = rb_get_cfp_iseq($cfp)
cfp_iseq_pc $cfp
if $iseq
if !((VALUE)$iseq & RUBY_IMMEDIATE_MASK) && (((imemo_ifunc << RUBY_FL_USHIFT) | RUBY_T_IMEMO)==$iseq->flags & (RUBY_IMEMO_MASK | RUBY_T_MASK))
printf "%d:ifunc ", $cfpend-$cfp
set print symbol-filename on
@@ -1107,7 +1128,7 @@ define rb_ps_thread
set print symbol-filename off
printf "\n"
else
if $cfp->pc
if $cfp_pc
set $location = $iseq->body->location
printf "%d:", $cfpend-$cfp
print_pathobj $location.pathobj