mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00

This works like: ``` (gdb) cfp CFP (count=3, addr=0x7ffff73fef50): $1 = {pc = 0x555556bf7818, sp = 0x7ffff72ff078, iseq = 0x7ffff2603270, self = 140737344619296, ep = 0x7ffff72ff058, block_code = 0x0, __bp__ = 0x7ffff72ff060, jit_return = 0x555558c2b000} Stack (size=3): [0] FIXNUM: 1 [1] T_STRING: "" bytesize:0 (embed) encoding:1 coderange:7bit $2 = (struct RString *) 0x7ffff249ea80 [2] [PROMOTED] T_OBJECT: $3 = {flags = 21474844769, klass = 140737344040416} $4 = {0x24, 0x24, 0x24} (gdb) cfp + 1 CFP (count=3, addr=0x7ffff73fef90): $5 = {pc = 0x5555567a78f8, sp = 0x7ffff72ff040, iseq = 0x7ffff26032d0, self = 140737344619296, ep = 0x7ffff72ff038, block_code = 0x0, __bp__ = 0x7ffff72ff040, jit_return = 0x555558c2b000} Stack (size=0): ```
33 lines
1.1 KiB
Python
33 lines
1.1 KiB
Python
# Usage:
|
|
# cfp: Dump the current cfp
|
|
# cfp + 1: Dump the caller cfp
|
|
class CFP(gdb.Command):
|
|
def __init__(self):
|
|
super(CFP, self).__init__('cfp', gdb.COMMAND_USER)
|
|
|
|
def invoke(self, offset, from_tty):
|
|
if not offset:
|
|
offset = '0'
|
|
cfp = f'(ruby_current_ec->cfp + ({offset}))'
|
|
|
|
end_cfp = self.get_int('ruby_current_ec->vm_stack + ruby_current_ec->vm_stack_size')
|
|
cfp_count = int((end_cfp - self.get_int('ruby_current_ec->cfp')) / self.get_int('sizeof(rb_control_frame_t)'))
|
|
|
|
print('CFP (count={}, addr=0x{:x}):'.format(cfp_count, self.get_int(cfp)))
|
|
gdb.execute(f'p *({cfp})')
|
|
print()
|
|
|
|
stack_size = int((self.get_int(f'{cfp}->sp') - self.get_int(f'{cfp}->__bp__')) / 8)
|
|
print(f'Stack (size={stack_size}):')
|
|
for i in range(0, stack_size):
|
|
obj = self.get_int(f'{cfp}->__bp__[{i}]')
|
|
rp = self.get_string(f'rp {obj}')
|
|
print(f'[{i}] {rp}', end='')
|
|
|
|
def get_int(self, expr):
|
|
return int(self.get_string(f'printf "%ld", ({expr})'))
|
|
|
|
def get_string(self, expr):
|
|
return gdb.execute(expr, to_string=True)
|
|
|
|
CFP()
|