class RubyInternal
Constants
- FL_USER1
- FL_USHIFT
- RSTRING_NOEMBED
- VM_FRAME_MAGIC_CFUNC
- VM_FRAME_MAGIC_MASK
- VM_FRAME_MAGIC_MASK_BITS
Public Class Methods
new(gdb)
click to toggle source
# File bin/gdbruby.rb, line 207 def initialize(gdb) @gdb = gdb end
Public Instance Methods
do_hash(key, table)
click to toggle source
# File bin/gdbruby.rb, line 300 def do_hash(key, table) # NOTE: table->type->hash is always st_numhash key end
find_entry(table, key, hash_val, bin_pos)
click to toggle source
# File bin/gdbruby.rb, line 334 def find_entry(table, key, hash_val, bin_pos) ptr = @gdb.cmd_get_value("p (#{table})->as.big.bins[#{bin_pos}]") if ptr_not_equal(table, ptr, hash_val, key) next_ptr = @gdb.cmd_get_value("p (#{ptr})->next") while ptr_not_equal(table, next_ptr, hash_val, key) ptr = next_ptr next_ptr = @gdb.cmd_get_value("p (#{ptr})->next") end ptr = next_ptr end ptr =~ /(0x[0-9a-f]+)\z/ $1 end
ptr_not_equal(table, ptr, hash_val, key)
click to toggle source
# File bin/gdbruby.rb, line 325 def ptr_not_equal(table, ptr, hash_val, key) ptr =~ /(0x[0-9a-f]+)\z/ ptr_num = $1.hex t_hash = @gdb.cmd_get_value("p (#{ptr})->hash") t_key = @gdb.cmd_get_value("p (#{ptr})->key") # NOTE: table->type->compare is always st_numcmp ptr_num != 0 and (t_hash != hash_val or t_key != key) end
rb_id2str(id)
click to toggle source
# File bin/gdbruby.rb, line 348 def rb_id2str(id) rstring_ptr(st_lookup('global_symbols.id_str', id)) end
rb_type(value)
click to toggle source
NOTE: This logic is slow because many commands are sent to gdb.
Fetch consts with 'ptype enum ruby_value_type' first and check types in Ruby.
# File bin/gdbruby.rb, line 251 def rb_type(value) type_str = nil # IMMEDIATE_P if @gdb.cmd_get_value("p (int)(#{value}) & RUBY_IMMEDIATE_MASK") != '0' # FIXNUM_P if @gdb.cmd_get_value("p (int)(#{value}) & RUBY_FIXNUM_FLAG") != '0' type_str = 'RUBY_T_FIXNUM' # FLONUM_P elsif @gdb.cmd_get_value("p ((int)(#{value}) & RUBY_FLONUM_MASK) == RUBY_FLONUM_FLAG") != '0' type_str = 'RUBY_T_FLONUM' elsif @gdb.cmd_get_value("p (#{value}) == RUBY_Qtrue") != '0' type_str = 'RUBY_T_TRUE' # SYMBOL_P elsif @gdb.cmd_get_value("p (VALUE)(#{value}) & ~(~(VALUE)0 << RUBY_SPECIAL_SHIFT) == RUBY_SYMBOL_FLAG") != '0' type_str = 'RUBY_T_SYMBOL' elsif @gdb.cmd_get_value("p (#{value}) == RUBY_Qundef") != '0' type_str = 'RUBY_T_UNDEF' end elsif @gdb.cmd_get_value("p (int)(#{value}) & RUBY_FIXNUM_FLAG") != '0' # special consts const = @gdb.cmd_get_value("p (enum ruby_special_consts)(#{value})") # TODO: change to map case const when 'RUBY_Qnil' type_str = 'RUBY_T_NIL' when 'RUBY_Qfalse' type_str = 'RUBY_T_FALSE' end else # builtin type type_str = @gdb.cmd_get_value("p (enum ruby_value_type)(((struct RBasic*)(#{value}))->flags & RUBY_T_MASK)") end end
rb_vm_get_sourceline(cfp, iseq)
click to toggle source
# File bin/gdbruby.rb, line 220 def rb_vm_get_sourceline(cfp, iseq) if ruby_vm_normal_iseq_p(iseq) # calc_lineno()@vm_backtrace.c current_position = @gdb.cmd_get_value("p #{cfp}->pc - #{iseq}->iseq_encoded").to_i # rb_iseq_line_no()@iseq.c current_position -= 1 unless current_position == 0 # find_line_no@iseq.c and get_line_info@iseq.c line_info_size = @gdb.cmd_get_value("p #{iseq}->line_info_size").to_i line_info_table = "#{iseq}->line_info_table" case line_info_size when 0 return 0 when 1 return @gdb.cmd_get_value("p #{line_info_table}[0].line_no").to_i else (1..line_info_size).each do |i| position = @gdb.cmd_get_value("p #{line_info_table}[#{i}].position").to_i if position == current_position return @gdb.cmd_get_value("p #{line_info_table}[#{i}].line_no").to_i elsif position > current_position return @gdb.cmd_get_value("p #{line_info_table}[#{i - 1}].line_no").to_i end end end end 0 end
rstring_ptr(value_pointer)
click to toggle source
# File bin/gdbruby.rb, line 285 def rstring_ptr(value_pointer) no_embed = @gdb.cmd_get_value("p ((struct RBasic *)(#{value_pointer}))->flags & #{RSTRING_NOEMBED}") if no_embed == '0' # embedded in struct @gdb.cmd_get_value("p (char *)((struct RString *)(#{value_pointer}))->as.ary") else # heap pointer @gdb.cmd_get_value("p (char *)((struct RString *)(#{value_pointer}))->as.heap.ptr") end end
ruby_vm_ifunc_p(pointer)
click to toggle source
# File bin/gdbruby.rb, line 211 def ruby_vm_ifunc_p(pointer) # pointer is string like 0xaabbccdd @gdb.cmd_get_value("p (enum ruby_value_type)(((struct RBasic *)(#{pointer}))->flags & RUBY_T_MASK) == RUBY_T_NODE") != '0' end
ruby_vm_normal_iseq_p(pointer)
click to toggle source
# File bin/gdbruby.rb, line 216 def ruby_vm_normal_iseq_p(pointer) @gdb.cmd_get_value("p #{pointer} && #{pointer} != 0") != '0' and not ruby_vm_ifunc_p(pointer) end
rubyvm_cfunc_frame_p(cfp)
click to toggle source
# File bin/gdbruby.rb, line 296 def rubyvm_cfunc_frame_p(cfp) @gdb.cmd_get_value("p (#{cfp}->flag & #{VM_FRAME_MAGIC_MASK}) == #{VM_FRAME_MAGIC_CFUNC}") != '0' end
st_lookup(table, key)
click to toggle source
# File bin/gdbruby.rb, line 305 def st_lookup(table, key) hash_val = do_hash(key, table) raise if @gdb.cmd_get_value("p (#{table})->entries_packed") != '0' raise if @gdb.cmd_get_value("p (#{table})->type->hash == st_numhash") == '0' raise if @gdb.cmd_get_value("p (#{table})->type->compare == st_numcmp") == '0' # TODO: check table->entries_packed bin_pos = @gdb.cmd_get_value("p (#{hash_val}) % (#{table})->num_bins") ptr = find_entry(table, key, hash_val, bin_pos) if ptr.hex == 0 nil else value = @gdb.cmd_get_value("p ((struct st_table_entry *)(#{ptr}))->record") value end end