gdbdump 0.1.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ea50c60dac2189b7cea3222ddcf45ef8a351d203
4
- data.tar.gz: df893c9a3c07006e1864358def10125388660f4d
3
+ metadata.gz: 806c8f4485ae5cfad83522a88e00ea3a625d7ed5
4
+ data.tar.gz: a125ef9b802bb4cece94f042a11340a3ca862296
5
5
  SHA512:
6
- metadata.gz: 209d5cd21074e35b9b02a14a29b6ba396b8dfb03f66aaf76f34bc1e556f3f31fb7ffce4df202cbfd5321c2e4ac0b913356a89a6b7d140ea23d47a56217758c89
7
- data.tar.gz: 4999fe00d9d43b77b4a330eeb57a7185a1dcb4b870d712ea8799ac9737da3dbf5cbff91addbcc5fdf6f7c2604a8e2d3a649705a545484d8646db408234476ea4
6
+ metadata.gz: 2e9373b1893dac6dad697b3eb95dca41e0f43d64b2400e136e9387850755152474e472e0c5038a1ee181e180dfb4e3e8d0bbb7d365bf263a8c2b973cc4e405e0
7
+ data.tar.gz: f2eb578d9859bbccd7149156bba3e1a35dcedb70dab66915597c6bbea807492c426e3da7b076d7588b8776f0c4c79c7bc9a51b01a3d77a6542ee5246c6031615
data/.gitignore CHANGED
@@ -7,3 +7,4 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
+ .ruby-version
@@ -0,0 +1,16 @@
1
+ # 0.9.0
2
+
3
+ Enhancements:
4
+
5
+ * Use rb_ps defined in ruby trunk .gdbinit to
6
+ * get backtrace of all treads
7
+ * print backtrace to STDOUT of gdbdump process, rather than STDERR of the attached process
8
+ * Use `sudo` to execute gdb command inside so that
9
+ * we can run as `$ gdbdump PID` rather than `$ sudo /path/to/ruby gdbdump PID`
10
+ * (previously, it was burdensome to use rbenv rubys and bundler via sudo)
11
+
12
+ # 0.1.0
13
+
14
+ First version
15
+
16
+ * Use rb_backtrace (for ruby level backtrace) and rb_print_backtrace (for C level backtrace)
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- # Specify your gem's dependencies in gdbdump.gemspec
4
3
  gemspec
4
+ gem 'pry-nav'
data/README.md CHANGED
@@ -1,64 +1,85 @@
1
- # Gdbdump
1
+ # gdbdump
2
2
 
3
- Print C level and Ruby level backtrace of living process using gdb
3
+ Print C level and Ruby level backtrace of living ruby process using gdb
4
4
 
5
5
  ## Installation
6
6
 
7
- $ gem install gdbdump
7
+ ```
8
+ $ gem install gdbdump
9
+ ```
8
10
 
9
11
  ## Requirements
10
12
 
11
- * run with sudo.
12
- * on Linux.
13
-
14
- I verified that this gem works with ruby executables built by [rbenv/ruby-build](https://github.com/rbenv/ruby-build).
13
+ * gdb
14
+ * linux
15
+ * `sudo gdb` must be allowed
15
16
 
16
- ## Example
17
+ It was verfied that gdbdump works with ruby executables built by [rbenv/ruby-build](https://github.com/rbenv/ruby-build).
17
18
 
18
- With living ruby process of pid 1897,
19
+ ## Usage
19
20
 
20
21
  ```
21
- $ sudo gdbdump 1897
22
+ Usage: gdbdump [options] [pid|prog pid]
23
+ -d, --[no-]debug print debug log (default: false)
24
+ -x, --gdbinit FILE path to ruby trunk's .gdbinit (default: some of ruby trunk's .gdbinit is bundle in this gem, and used})
25
+ --gdb PATH path to gdb command (default: gdb)
22
26
  ```
23
27
 
24
- You will see C and Ruby level backtrace on STDERR of **the target process** of pid 1897 as:
28
+ ### .gdbinit
25
29
 
26
- ```
27
- == c backtrace ==
28
- /home/ubuntu/.rbenv/versions/2.4.1/bin/ruby(rb_print_backtrace+0x15) [0x7fd23062c115] vm_dump.c:684
29
- [0x7ffc98c378af]
30
- == ruby backtrace ==
31
- from loop.rb:3:in `<main>'
32
- from loop.rb:3:in `loop'
33
- from loop.rb:5:in `block in <main>'
34
- from loop.rb:5:in `sleep'
35
- ```
30
+ Default supported ruby versions: 2.3.0 - 2.4.1
36
31
 
37
- ## Usage
32
+ Ruby trunk's [.gdbinit](https://github.com/ruby/ruby/blob/trunk/.gdbinit) file defines useful helper functions and it is maintained by ruby core team. `gdbdump` uses it.
33
+ Some versions of .gdbinit are bundled in this gem, but if you want to use `gdbdump` for older or newer ruby versions:
34
+
35
+ 1. Download .gdbinit from ruby repo like https://github.com/ruby/ruby/blob/v2_4_1/.gdbinit, and specify with `-x` option
36
+ 2. Or, send PR to bundle the .gdbinit in `gdbdump` gem.
37
+
38
+ ## Example
39
+
40
+ With living ruby 2.4.1 process of pid 1897,
38
41
 
39
42
  ```
40
- Usage: gdbdump [options] [pid|prog pid]
41
- -d, --[no-]debug print debug log (default: false)
43
+ $ gdbdump 1897
42
44
  ```
43
45
 
44
- ## How this work
46
+ You will see C and Ruby level backtrace on STDERR of **the target process** of pid 1897 as:
45
47
 
46
- Attach to the ruby process with gdb, and call `rb_print_backtrace()` (C level backtrace) and `rb_backtrace()` (Ruby level backtrace). That's it.
48
+ ```
49
+ $1 = (rb_vm_t *) 0x7f46bb071f20
50
+ * #<Thread:0x7f46bb0a5ee8 rb_thread_t:0x7f46bb0725d0 native_thread:0x7f46ba514740>
51
+ 0x7f46ba16d700 <thread_join_m at thread.c:980>:in `join'
52
+ loop.rb:17:in `<main>'
53
+ * #<Thread:0x7f46bb202750 rb_thread_t:0x7f46bb3e03d0 native_thread:0x7f46b89c0700>
54
+ 0x7f46ba0e4f30 <rb_f_sleep at process.c:4388>:in `sleep'
55
+ loop.rb:6:in `block (2 levels) in <main>'
56
+ 0x7f46ba1a72b0 <rb_f_loop at vm_eval.c:1137>:in `loop'
57
+ loop.rb:4:in `block in <main>'
58
+ * #<Thread:0x7f46bb202660 rb_thread_t:0x7f46bb3e47e0 native_thread:0x7f46b87be700>
59
+ 0x7f46ba0e4f30 <rb_f_sleep at process.c:4388>:in `sleep'
60
+ loop.rb:13:in `block (2 levels) in <main>'
61
+ 0x7f46ba1a72b0 <rb_f_loop at vm_eval.c:1137>:in `loop'
62
+ loop.rb:11:in `block in <main>'
63
+ ```
47
64
 
48
- The path of ruby executable is found by `/proc/[PID]/exe` as default.
65
+ ## FAQ
49
66
 
50
- ## ToDo
67
+ Q. How this work?
68
+ A. Attach to the ruby process with gdb, and call `rb_ps` defined in gdbinit. That's it.
51
69
 
52
- * Want to print backtrace on STDOUT of gdbdump process.
53
- * To do it, we need another version of `rb_print_backtrace` and `rb_backtrace` to print results into a file in CRuby itself.
54
- * If they are available, gdbdump can dump to a file and, then read and print into STDOUT of gdbdump process.
70
+ Q. Is this available for production process?
71
+ A. GDB stops the process during printing backtrace, would cause some issues
55
72
 
56
73
  ## Comparisons
57
74
 
58
75
  * gdb
59
- * You can get C level backtrace with raw gdb, of course.
76
+ * You can print C level backtrace with raw gdb, of course
60
77
  * [sigdump](https://github.com/frsyuki/sigdump)
61
- * You can get ruby level backtrace with sigdump gem, but your ruby application must pre-install sigdump and `require 'sigdump/setup'`. `gdbdump` does not require it.
78
+ * sigdump enables to print ruby level backtrace with sending CONT signal to living ruby process.
79
+ * The ruby process must pre-install `sigdump` gem and `require 'sigdump/setup'` unlike gdbdump.
80
+ * [gdbruby](https://github.com/gunyarakun/gdbruby)
81
+ * gdbruby enables to print C level and ruby level backtrace of living ruby process and core file.
82
+ * gdbruby must follow changes of C level interfaces of CRuby to get backtrace of the core file, it rises fragility that it will be broken on newer ruby versions.
62
83
 
63
84
  ## Development
64
85
 
@@ -0,0 +1,18 @@
1
+ puts Process.pid
2
+
3
+ th1 = Thread.new do
4
+ loop do
5
+ puts 'thread 1'
6
+ sleep 1
7
+ end
8
+ end
9
+
10
+ th2 = Thread.new do
11
+ loop do
12
+ puts 'thread 2'
13
+ sleep 1
14
+ end
15
+ end
16
+
17
+ th1.join
18
+ th2.join
@@ -1,3 +1,8 @@
1
1
  require_relative "gdbdump/version"
2
+
3
+ class Gdbdump
4
+ ROOT = File.dirname(File.dirname(__FILE__))
5
+ end
6
+
2
7
  require_relative "gdbdump/gdb"
3
8
  require_relative "gdbdump/procfs"
@@ -16,11 +16,19 @@ class Gdbdump
16
16
 
17
17
  opts = {
18
18
  debug: false,
19
+ gdbinit: nil,
20
+ gdb: nil,
19
21
  }
20
22
 
21
23
  op.on('-d', '--[no-]debug', "print debug log (default: #{opts[:debug]})") {|v|
22
24
  opts[:debug] = v
23
25
  }
26
+ op.on('-x', '--gdbinit FILE', "path to ruby trunk's .gdbinit (default: some of ruby trunk's .gdbinit is bundle in this gem, and used})") {|v|
27
+ opts[:gdbinit] = v
28
+ }
29
+ op.on('--gdb PATH', "path to gdb command (default: gdb)") {|v|
30
+ opts[:gdb] = v
31
+ }
24
32
 
25
33
  op.banner += ' [pid|prog pid]'
26
34
  begin
@@ -43,7 +51,7 @@ class Gdbdump
43
51
 
44
52
  def run
45
53
  parse_options
46
- GDB.new(pid: @pid, prog: @prog, debug: @opts[:debug]).print_backtrace
54
+ GDB.new(pid: @pid, prog: @prog, **(@opts)).print_backtrace
47
55
  end
48
56
  end
49
57
  end
@@ -1,3 +1,4 @@
1
+ # frozen-string-literal: true
1
2
  require 'open3'
2
3
 
3
4
  class Gdbdump
@@ -6,27 +7,36 @@ class Gdbdump
6
7
  # end
7
8
  class GDB
8
9
  COMMAND_READ_BUFFER_SIZE = 1024
10
+ STRINGS_CMD = 'strings'
11
+ SUDO_CMD = 'sudo'
9
12
 
10
- def initialize(pid:, prog:, debug: false)
11
- @prog = prog
13
+ def initialize(pid:, prog: nil, debug: false, gdbinit: nil, gdb: nil)
12
14
  @pid = pid.to_s
15
+ @prog = prog
13
16
  @debug = debug
14
- @exec_options = ['gdb', '-silent', '-nw', @prog, @pid]
17
+ @gdbinit = gdbinit || File.join(ROOT, 'vendor', 'ruby', ruby_version, 'gdbinit')
18
+ @gdb = gdb || 'gdb'
19
+ @exec_options = [SUDO_CMD, @gdb, '-silent', '-nw', '-x', @gdbinit, @prog, @pid]
15
20
  end
16
21
 
17
22
  def print_backtrace
18
23
  run do |gdb|
19
- gdb.cmd_exec('call write(2, "== c backtrace ==\n", 18)')
20
- gdb.cmd_exec('call rb_print_backtrace()')
21
- gdb.cmd_exec('call write(2, "== ruby backtrace ==\n", 21)')
22
- gdb.cmd_exec('call rb_backtrace()')
24
+ out, err = gdb.cmd_exec('rb_ps')
25
+ $stdout.puts out
26
+ $stderr.puts err unless err.empty?
23
27
  end
28
+ # run do |gdb|
29
+ # gdb.cmd_exec('call write(2, "== c backtrace ==\n", 18)')
30
+ # gdb.cmd_exec('call rb_print_backtrace()')
31
+ # gdb.cmd_exec('call write(2, "== ruby backtrace ==\n", 21)')
32
+ # gdb.cmd_exec('call rb_backtrace()')
33
+ # end
24
34
  end
25
35
 
26
36
  def run
27
37
  @stdin, @stdout, @stderr = Open3.popen3(*@exec_options)
28
- if get_response =~ /ptrace: Operation not permitted./
29
- raise 'Must run gdbdump with sudo'
38
+ if get_response =~ /ptrace: Operation not permitted/
39
+ raise 'root privilege is required'
30
40
  end
31
41
  prepare
32
42
  begin
@@ -40,6 +50,15 @@ class Gdbdump
40
50
  end
41
51
  end
42
52
 
53
+ # ToDo: Any faster way to get ruby_version from pid?
54
+ # NOTE: I want ruby_version before starting gdb
55
+ def ruby_version
56
+ return @ruby_version if @ruby_version
57
+ ret = `#{STRINGS_CMD} #{@prog}`
58
+ line = ret.lines.find {|_| _.start_with?('RUBY_VERSION "') }
59
+ @ruby_version = line[14..-3] if line
60
+ end
61
+
43
62
  def cmd_exec(cmd)
44
63
  log('C', cmd)
45
64
  if cmd
@@ -52,18 +71,19 @@ class Gdbdump
52
71
  end
53
72
 
54
73
  def get_response
55
- response = +''
56
-
74
+ out = +''
57
75
  loop do
58
76
  begin
59
77
  buf = @stdout.sysread(COMMAND_READ_BUFFER_SIZE)
60
78
  rescue EOFError
61
79
  break
62
80
  end
63
- response << buf
64
81
  break if buf =~ /\(gdb\) $/
82
+ out << buf
65
83
  end
84
+ log('O', out)
66
85
 
86
+ err = +''
67
87
  loop do
68
88
  begin
69
89
  buf = @stderr.read_nonblock(COMMAND_READ_BUFFER_SIZE)
@@ -72,17 +92,16 @@ class Gdbdump
72
92
  rescue EOFError
73
93
  break
74
94
  end
75
- response << buf if buf
95
+ err << buf if buf
76
96
  end
97
+ log('E', err)
77
98
 
78
- log('R', response)
79
- response
99
+ [out, err]
80
100
  end
81
101
 
82
102
  private
83
103
 
84
104
  def prepare
85
- cmd_exec('')
86
105
  cmd_exec('set pagination off')
87
106
  end
88
107
 
@@ -93,6 +112,7 @@ class Gdbdump
93
112
 
94
113
  def log(pre, message)
95
114
  return unless @debug
115
+ return if message.nil? or message.empty?
96
116
  message.each_line do |line|
97
117
  puts "#{pre}: #{line}"
98
118
  end
@@ -8,9 +8,9 @@ class Gdbdump
8
8
 
9
9
  def exe
10
10
  begin
11
- File.readlink("/proc/#{@pid}/exe")
11
+ @exe ||= File.readlink("/proc/#{@pid}/exe")
12
12
  rescue Errno::ENOENT
13
- raise "/proc/#{@pid}/exe does not exist, it seems pid #{@pid} does not exit"
13
+ raise "/proc/#{@pid}/exe does not exist, it seems no process of pid #{@pid} exists"
14
14
  end
15
15
  end
16
16
  end
@@ -1,3 +1,3 @@
1
1
  class Gdbdump
2
- VERSION = "0.1.0"
2
+ VERSION = "0.9.0"
3
3
  end
@@ -0,0 +1,966 @@
1
+ define hook-run
2
+ set $color_type = 0
3
+ set $color_highlite = 0
4
+ set $color_end = 0
5
+ end
6
+
7
+ define ruby_gdb_init
8
+ if !$color_type
9
+ set $color_type = "\033[31m"
10
+ end
11
+ if !$color_highlite
12
+ set $color_highlite = "\033[36m"
13
+ end
14
+ if !$color_end
15
+ set $color_end = "\033[m"
16
+ end
17
+ if ruby_dummy_gdb_enums.special_consts
18
+ end
19
+ end
20
+
21
+ # set prompt \033[36m(gdb)\033[m\040
22
+
23
+ define rp
24
+ ruby_gdb_init
25
+ if (VALUE)($arg0) & RUBY_FIXNUM_FLAG
26
+ printf "FIXNUM: %ld\n", (long)($arg0) >> 1
27
+ else
28
+ if ((VALUE)($arg0) & ~(~(VALUE)0<<RUBY_SPECIAL_SHIFT)) == RUBY_SYMBOL_FLAG
29
+ set $id = (($arg0) >> RUBY_SPECIAL_SHIFT)
30
+ printf "%sSYMBOL%s: ", $color_type, $color_end
31
+ rp_id $id
32
+ else
33
+ if ($arg0) == RUBY_Qfalse
34
+ echo false\n
35
+ else
36
+ if ($arg0) == RUBY_Qtrue
37
+ echo true\n
38
+ else
39
+ if ($arg0) == RUBY_Qnil
40
+ echo nil\n
41
+ else
42
+ if ($arg0) == RUBY_Qundef
43
+ echo undef\n
44
+ else
45
+ if (VALUE)($arg0) & RUBY_IMMEDIATE_MASK
46
+ if ((VALUE)($arg0) & RUBY_FLONUM_MASK) == RUBY_FLONUM_FLAG
47
+ printf "%sFLONUM%s: %g\n", $color_type, $color_end, (double)rb_float_value($arg0)
48
+ else
49
+ echo immediate\n
50
+ end
51
+ else
52
+ set $flags = ((struct RBasic*)($arg0))->flags
53
+ if ($flags & RUBY_FL_PROMOTED) == RUBY_FL_PROMOTED
54
+ printf "[PROMOTED] "
55
+ end
56
+ if ($flags & RUBY_T_MASK) == RUBY_T_NONE
57
+ printf "%sT_NONE%s: ", $color_type, $color_end
58
+ print (struct RBasic *)($arg0)
59
+ else
60
+ if ($flags & RUBY_T_MASK) == RUBY_T_NIL
61
+ printf "%sT_NIL%s: ", $color_type, $color_end
62
+ print (struct RBasic *)($arg0)
63
+ else
64
+ if ($flags & RUBY_T_MASK) == RUBY_T_OBJECT
65
+ printf "%sT_OBJECT%s: ", $color_type, $color_end
66
+ print (struct RObject *)($arg0)
67
+ else
68
+ if ($flags & RUBY_T_MASK) == RUBY_T_CLASS
69
+ printf "%sT_CLASS%s%s: ", $color_type, ($flags & RUBY_FL_SINGLETON) ? "*" : "", $color_end
70
+ rp_class $arg0
71
+ else
72
+ if ($flags & RUBY_T_MASK) == RUBY_T_ICLASS
73
+ printf "%sT_ICLASS%s: ", $color_type, $color_end
74
+ rp_class $arg0
75
+ else
76
+ if ($flags & RUBY_T_MASK) == RUBY_T_MODULE
77
+ printf "%sT_MODULE%s: ", $color_type, $color_end
78
+ rp_class $arg0
79
+ else
80
+ if ($flags & RUBY_T_MASK) == RUBY_T_FLOAT
81
+ printf "%sT_FLOAT%s: %.16g ", $color_type, $color_end, (((struct RFloat*)($arg0))->float_value)
82
+ print (struct RFloat *)($arg0)
83
+ else
84
+ if ($flags & RUBY_T_MASK) == RUBY_T_STRING
85
+ printf "%sT_STRING%s: ", $color_type, $color_end
86
+ rp_string $arg0 $flags
87
+ else
88
+ if ($flags & RUBY_T_MASK) == RUBY_T_REGEXP
89
+ set $regsrc = ((struct RRegexp*)($arg0))->src
90
+ set $rsflags = ((struct RBasic*)$regsrc)->flags
91
+ printf "%sT_REGEXP%s: ", $color_type, $color_end
92
+ set print address off
93
+ output (char *)(($rsflags & RUBY_FL_USER1) ? \
94
+ ((struct RString*)$regsrc)->as.heap.ptr : \
95
+ ((struct RString*)$regsrc)->as.ary)
96
+ set print address on
97
+ printf " len:%ld ", ($rsflags & RUBY_FL_USER1) ? \
98
+ ((struct RString*)$regsrc)->as.heap.len : \
99
+ (($rsflags & (RUBY_FL_USER2|RUBY_FL_USER3|RUBY_FL_USER4|RUBY_FL_USER5|RUBY_FL_USER6)) >> RUBY_FL_USHIFT+2)
100
+ if $flags & RUBY_FL_USER6
101
+ printf "(none) "
102
+ end
103
+ if $flags & RUBY_FL_USER5
104
+ printf "(literal) "
105
+ end
106
+ if $flags & RUBY_FL_USER4
107
+ printf "(fixed) "
108
+ end
109
+ printf "encoding:%d ", ($flags & RUBY_ENCODING_MASK) >> RUBY_ENCODING_SHIFT
110
+ print (struct RRegexp *)($arg0)
111
+ else
112
+ if ($flags & RUBY_T_MASK) == RUBY_T_ARRAY
113
+ if ($flags & RUBY_FL_USER1)
114
+ set $len = (($flags & (RUBY_FL_USER3|RUBY_FL_USER4)) >> (RUBY_FL_USHIFT+3))
115
+ printf "%sT_ARRAY%s: len=%ld ", $color_type, $color_end, $len
116
+ printf "(embed) "
117
+ if ($len == 0)
118
+ printf "{(empty)} "
119
+ else
120
+ output/x *((VALUE*)((struct RArray*)($arg0))->as.ary) @ $len
121
+ printf " "
122
+ end
123
+ else
124
+ set $len = ((struct RArray*)($arg0))->as.heap.len
125
+ printf "%sT_ARRAY%s: len=%ld ", $color_type, $color_end, $len
126
+ if ($flags & RUBY_FL_USER2)
127
+ printf "(shared) shared="
128
+ output/x ((struct RArray*)($arg0))->as.heap.aux.shared
129
+ printf " "
130
+ else
131
+ printf "(ownership) capa=%ld ", ((struct RArray*)($arg0))->as.heap.aux.capa
132
+ end
133
+ if ($len == 0)
134
+ printf "{(empty)} "
135
+ else
136
+ output/x *((VALUE*)((struct RArray*)($arg0))->as.heap.ptr) @ $len
137
+ printf " "
138
+ end
139
+ end
140
+ print (struct RArray *)($arg0)
141
+ else
142
+ if ($flags & RUBY_T_MASK) == RUBY_T_FIXNUM
143
+ printf "%sT_FIXNUM%s: ", $color_type, $color_end
144
+ print (struct RBasic *)($arg0)
145
+ else
146
+ if ($flags & RUBY_T_MASK) == RUBY_T_HASH
147
+ printf "%sT_HASH%s: ", $color_type, $color_end,
148
+ if ((struct RHash *)($arg0))->ntbl
149
+ printf "len=%ld ", ((struct RHash *)($arg0))->ntbl->num_entries
150
+ end
151
+ print (struct RHash *)($arg0)
152
+ else
153
+ if ($flags & RUBY_T_MASK) == RUBY_T_STRUCT
154
+ printf "%sT_STRUCT%s: len=%ld ", $color_type, $color_end, \
155
+ (($flags & (RUBY_FL_USER1|RUBY_FL_USER2)) ? \
156
+ ($flags & (RUBY_FL_USER1|RUBY_FL_USER2)) >> (RUBY_FL_USHIFT+1) : \
157
+ ((struct RStruct *)($arg0))->as.heap.len)
158
+ print (struct RStruct *)($arg0)
159
+ x/xw (($flags & (RUBY_FL_USER1|RUBY_FL_USER2)) ? \
160
+ ((struct RStruct *)($arg0))->as.ary : \
161
+ ((struct RStruct *)($arg0))->as.heap.ptr)
162
+ else
163
+ if ($flags & RUBY_T_MASK) == RUBY_T_BIGNUM
164
+ printf "%sT_BIGNUM%s: sign=%d len=%ld ", $color_type, $color_end, \
165
+ (($flags & RUBY_FL_USER1) != 0), \
166
+ (($flags & RUBY_FL_USER2) ? \
167
+ ($flags & (RUBY_FL_USER5|RUBY_FL_USER4|RUBY_FL_USER3)) >> (RUBY_FL_USHIFT+3) : \
168
+ ((struct RBignum*)($arg0))->as.heap.len)
169
+ if $flags & RUBY_FL_USER2
170
+ printf "(embed) "
171
+ end
172
+ print (struct RBignum *)($arg0)
173
+ x/xw (($flags & RUBY_FL_USER2) ? \
174
+ ((struct RBignum*)($arg0))->as.ary : \
175
+ ((struct RBignum*)($arg0))->as.heap.digits)
176
+ else
177
+ if ($flags & RUBY_T_MASK) == RUBY_T_RATIONAL
178
+ printf "%sT_RATIONAL%s: ", $color_type, $color_end
179
+ print (struct RRational *)($arg0)
180
+ else
181
+ if ($flags & RUBY_T_MASK) == RUBY_T_COMPLEX
182
+ printf "%sT_COMPLEX%s: ", $color_type, $color_end
183
+ print (struct RComplex *)($arg0)
184
+ else
185
+ if ($flags & RUBY_T_MASK) == RUBY_T_FILE
186
+ printf "%sT_FILE%s: ", $color_type, $color_end
187
+ print (struct RFile *)($arg0)
188
+ output *((struct RFile *)($arg0))->fptr
189
+ printf "\n"
190
+ else
191
+ if ($flags & RUBY_T_MASK) == RUBY_T_TRUE
192
+ printf "%sT_TRUE%s: ", $color_type, $color_end
193
+ print (struct RBasic *)($arg0)
194
+ else
195
+ if ($flags & RUBY_T_MASK) == RUBY_T_FALSE
196
+ printf "%sT_FALSE%s: ", $color_type, $color_end
197
+ print (struct RBasic *)($arg0)
198
+ else
199
+ if ($flags & RUBY_T_MASK) == RUBY_T_DATA
200
+ if ((struct RTypedData *)($arg0))->typed_flag == 1
201
+ printf "%sT_DATA%s(%s): ", $color_type, $color_end, ((struct RTypedData *)($arg0))->type->wrap_struct_name
202
+ print (struct RTypedData *)($arg0)
203
+ else
204
+ printf "%sT_DATA%s: ", $color_type, $color_end
205
+ print (struct RData *)($arg0)
206
+ end
207
+ else
208
+ if ($flags & RUBY_T_MASK) == RUBY_T_MATCH
209
+ printf "%sT_MATCH%s: ", $color_type, $color_end
210
+ print (struct RMatch *)($arg0)
211
+ else
212
+ if ($flags & RUBY_T_MASK) == RUBY_T_SYMBOL
213
+ printf "%sT_SYMBOL%s: ", $color_type, $color_end
214
+ print (struct RSymbol *)($arg0)
215
+ set $id_type = ((struct RSymbol *)($arg0))->id & RUBY_ID_SCOPE_MASK
216
+ if $id_type == RUBY_ID_LOCAL
217
+ printf "l"
218
+ else
219
+ if $id_type == RUBY_ID_INSTANCE
220
+ printf "i"
221
+ else
222
+ if $id_type == RUBY_ID_GLOBAL
223
+ printf "G"
224
+ else
225
+ if $id_type == RUBY_ID_ATTRSET
226
+ printf "a"
227
+ else
228
+ if $id_type == RUBY_ID_CONST
229
+ printf "C"
230
+ else
231
+ if $id_type == RUBY_ID_CLASS
232
+ printf "c"
233
+ else
234
+ printf "j"
235
+ end
236
+ end
237
+ end
238
+ end
239
+ end
240
+ end
241
+ set $id_fstr = ((struct RSymbol *)($arg0))->fstr
242
+ rp_string $id_fstr
243
+ else
244
+ if ($flags & RUBY_T_MASK) == RUBY_T_UNDEF
245
+ printf "%sT_UNDEF%s: ", $color_type, $color_end
246
+ print (struct RBasic *)($arg0)
247
+ else
248
+ if ($flags & RUBY_T_MASK) == RUBY_T_IMEMO
249
+ printf "%sT_IMEMO%s(", $color_type, $color_end
250
+ output (enum imemo_type)(($flags>>RUBY_FL_USHIFT)&imemo_mask)
251
+ printf "): "
252
+ rp_imemo $arg0
253
+ else
254
+ if ($flags & RUBY_T_MASK) == RUBY_T_NODE
255
+ printf "%sT_NODE%s(", $color_type, $color_end
256
+ output (enum node_type)(($flags&RUBY_NODE_TYPEMASK)>>RUBY_NODE_TYPESHIFT)
257
+ printf "): "
258
+ print *(NODE *)($arg0)
259
+ else
260
+ if ($flags & RUBY_T_MASK) == RUBY_T_ZOMBIE
261
+ printf "%sT_ZOMBIE%s: ", $color_type, $color_end
262
+ print (struct RData *)($arg0)
263
+ else
264
+ printf "%sunknown%s: ", $color_type, $color_end
265
+ print (struct RBasic *)($arg0)
266
+ end
267
+ end
268
+ end
269
+ end
270
+ end
271
+ end
272
+ end
273
+ end
274
+ end
275
+ end
276
+ end
277
+ end
278
+ end
279
+ end
280
+ end
281
+ end
282
+ end
283
+ end
284
+ end
285
+ end
286
+ end
287
+ end
288
+ end
289
+ end
290
+ end
291
+ end
292
+ end
293
+ end
294
+ end
295
+ end
296
+ end
297
+ end
298
+ end
299
+ end
300
+ document rp
301
+ Print a Ruby's VALUE.
302
+ end
303
+
304
+ define rp_id
305
+ set $id = (ID)$arg0
306
+ if $id == '!' || $id == '+' || $id == '-' || $id == '*' || $id == '/' || $id == '%' || $id == '<' || $id == '>' || $id == '`'
307
+ printf "(:%c)\n", $id
308
+ else
309
+ if $id == idDot2
310
+ printf "(:..)\n"
311
+ else
312
+ if $id == idDot3
313
+ printf "(:...)\n"
314
+ else
315
+ if $id == idUPlus
316
+ printf "(:+@)\n"
317
+ else
318
+ if $id == idUMinus
319
+ printf "(:-@)\n"
320
+ else
321
+ if $id == idPow
322
+ printf "(:**)\n"
323
+ else
324
+ if $id == idCmp
325
+ printf "(:<=>)\n"
326
+ else
327
+ if $id == idLTLT
328
+ printf "(:<<)\n"
329
+ else
330
+ if $id == idLE
331
+ printf "(:<=)\n"
332
+ else
333
+ if $id == idGE
334
+ printf "(:>=)\n"
335
+ else
336
+ if $id == idEq
337
+ printf "(:==)\n"
338
+ else
339
+ if $id == idEqq
340
+ printf "(:===)\n"
341
+ else
342
+ if $id == idNeq
343
+ printf "(:!=)\n"
344
+ else
345
+ if $id == idEqTilde
346
+ printf "(:=~)\n"
347
+ else
348
+ if $id == idNeqTilde
349
+ printf "(:!~)\n"
350
+ else
351
+ if $id == idAREF
352
+ printf "(:[])\n"
353
+ else
354
+ if $id == idASET
355
+ printf "(:[]=)\n"
356
+ else
357
+ if $id <= tLAST_OP_ID
358
+ printf "O"
359
+ else
360
+ set $id_type = $id & RUBY_ID_SCOPE_MASK
361
+ if $id_type == RUBY_ID_LOCAL
362
+ printf "l"
363
+ else
364
+ if $id_type == RUBY_ID_INSTANCE
365
+ printf "i"
366
+ else
367
+ if $id_type == RUBY_ID_GLOBAL
368
+ printf "G"
369
+ else
370
+ if $id_type == RUBY_ID_ATTRSET
371
+ printf "a"
372
+ else
373
+ if $id_type == RUBY_ID_CONST
374
+ printf "C"
375
+ else
376
+ if $id_type == RUBY_ID_CLASS
377
+ printf "c"
378
+ else
379
+ printf "j"
380
+ end
381
+ end
382
+ end
383
+ end
384
+ end
385
+ end
386
+ end
387
+ printf "(%ld): ", $id
388
+ set $str = lookup_id_str($id)
389
+ if $str
390
+ rp_string $str
391
+ else
392
+ echo undef\n
393
+ end
394
+ end
395
+ end
396
+ end
397
+ end
398
+ end
399
+ end
400
+ end
401
+ end
402
+ end
403
+ end
404
+ end
405
+ end
406
+ end
407
+ end
408
+ end
409
+ end
410
+ end
411
+ end
412
+ document rp_id
413
+ Print an ID.
414
+ end
415
+
416
+ define rp_string
417
+ set $flags = ((struct RBasic*)($arg0))->flags
418
+ set print address off
419
+ output (char *)(($flags & RUBY_FL_USER1) ? \
420
+ ((struct RString*)($arg0))->as.heap.ptr : \
421
+ ((struct RString*)($arg0))->as.ary)
422
+ set print address on
423
+ printf " bytesize:%ld ", ($flags & RUBY_FL_USER1) ? \
424
+ ((struct RString*)($arg0))->as.heap.len : \
425
+ (($flags & (RUBY_FL_USER2|RUBY_FL_USER3|RUBY_FL_USER4|RUBY_FL_USER5|RUBY_FL_USER6)) >> RUBY_FL_USHIFT+2)
426
+ if !($flags & RUBY_FL_USER1)
427
+ printf "(embed) "
428
+ else
429
+ if ($flags & RUBY_FL_USER2)
430
+ printf "(shared) "
431
+ end
432
+ if ($flags & RUBY_FL_USER3)
433
+ printf "(assoc) "
434
+ end
435
+ end
436
+ printf "encoding:%d ", ($flags & RUBY_ENCODING_MASK) >> RUBY_ENCODING_SHIFT
437
+ if ($flags & RUBY_ENC_CODERANGE_MASK) == 0
438
+ printf "coderange:unknown "
439
+ else
440
+ if ($flags & RUBY_ENC_CODERANGE_MASK) == RUBY_ENC_CODERANGE_7BIT
441
+ printf "coderange:7bit "
442
+ else
443
+ if ($flags & RUBY_ENC_CODERANGE_MASK) == RUBY_ENC_CODERANGE_VALID
444
+ printf "coderange:valid "
445
+ else
446
+ printf "coderange:broken "
447
+ end
448
+ end
449
+ end
450
+ print (struct RString *)($arg0)
451
+ end
452
+ document rp_string
453
+ Print the content of a String.
454
+ end
455
+
456
+ define rp_class
457
+ printf "(struct RClass *) %p", (void*)$arg0
458
+ if ((struct RClass *)($arg0))->ptr.origin_ != $arg0
459
+ printf " -> %p", ((struct RClass *)($arg0))->ptr.origin_
460
+ end
461
+ printf "\n"
462
+ rb_classname $arg0
463
+ print *(struct RClass *)($arg0)
464
+ print *((struct RClass *)($arg0))->ptr
465
+ end
466
+ document rp_class
467
+ Print the content of a Class/Module.
468
+ end
469
+
470
+ define rp_imemo
471
+ set $flags = (((struct RBasic *)($arg0))->flags >> RUBY_FL_USHIFT) & imemo_mask
472
+ if $flags == imemo_cref
473
+ printf "(rb_cref_t *) %p\n", (void*)$arg0
474
+ print *(rb_cref_t *)$arg0
475
+ else
476
+ if $flags == imemo_svar
477
+ printf "(struct vm_svar *) %p\n", (void*)$arg0
478
+ print *(struct vm_svar *)$arg0
479
+ else
480
+ if $flags == imemo_throw_data
481
+ printf "(struct vm_throw_data *) %p\n", (void*)$arg0
482
+ print *(struct vm_throw_data *)$arg0
483
+ else
484
+ if $flags == imemo_ifunc
485
+ printf "(struct vm_ifunc *) %p\n", (void*)$arg0
486
+ print *(struct vm_ifunc *)$arg0
487
+ else
488
+ if $flags == imemo_memo
489
+ printf "(struct MEMO *) %p\n", (void*)$arg0
490
+ print *(struct MEMO *)$arg0
491
+ else
492
+ printf "(struct RIMemo *) %p\n", (void*)$arg0
493
+ print *(struct RIMemo *)$arg0
494
+ end
495
+ end
496
+ end
497
+ end
498
+ end
499
+ end
500
+ document rp_imemo
501
+ Print the content of a memo
502
+ end
503
+
504
+ define nd_type
505
+ print (enum node_type)((((NODE*)($arg0))->flags&RUBY_NODE_TYPEMASK)>>RUBY_NODE_TYPESHIFT)
506
+ end
507
+ document nd_type
508
+ Print a Ruby' node type.
509
+ end
510
+
511
+ define nd_file
512
+ print ((NODE*)($arg0))->nd_file
513
+ end
514
+ document nd_file
515
+ Print the source file name of a node.
516
+ end
517
+
518
+ define nd_line
519
+ print ((unsigned int)((((NODE*)($arg0))->flags>>RUBY_NODE_LSHIFT)&RUBY_NODE_LMASK))
520
+ end
521
+ document nd_line
522
+ Print the source line number of a node.
523
+ end
524
+
525
+ # Print members of ruby node.
526
+
527
+ define nd_head
528
+ printf "%su1.node%s: ", $color_highlite, $color_end
529
+ rp ($arg0).u1.node
530
+ end
531
+
532
+ define nd_alen
533
+ printf "%su2.argc%s: ", $color_highlite, $color_end
534
+ p ($arg0).u2.argc
535
+ end
536
+
537
+ define nd_next
538
+ printf "%su3.node%s: ", $color_highlite, $color_end
539
+ rp ($arg0).u3.node
540
+ end
541
+
542
+
543
+ define nd_cond
544
+ printf "%su1.node%s: ", $color_highlite, $color_end
545
+ rp ($arg0).u1.node
546
+ end
547
+
548
+ define nd_body
549
+ printf "%su2.node%s: ", $color_highlite, $color_end
550
+ rp ($arg0).u2.node
551
+ end
552
+
553
+ define nd_else
554
+ printf "%su3.node%s: ", $color_highlite, $color_end
555
+ rp ($arg0).u3.node
556
+ end
557
+
558
+
559
+ define nd_orig
560
+ printf "%su3.value%s: ", $color_highlite, $color_end
561
+ rp ($arg0).u3.value
562
+ end
563
+
564
+
565
+ define nd_resq
566
+ printf "%su2.node%s: ", $color_highlite, $color_end
567
+ rp ($arg0).u2.node
568
+ end
569
+
570
+ define nd_ensr
571
+ printf "%su3.node%s: ", $color_highlite, $color_end
572
+ rp ($arg0).u3.node
573
+ end
574
+
575
+
576
+ define nd_1st
577
+ printf "%su1.node%s: ", $color_highlite, $color_end
578
+ rp ($arg0).u1.node
579
+ end
580
+
581
+ define nd_2nd
582
+ printf "%su2.node%s: ", $color_highlite, $color_end
583
+ rp ($arg0).u2.node
584
+ end
585
+
586
+
587
+ define nd_stts
588
+ printf "%su1.node%s: ", $color_highlite, $color_end
589
+ rp ($arg0).u1.node
590
+ end
591
+
592
+
593
+ define nd_entry
594
+ printf "%su3.entry%s: ", $color_highlite, $color_end
595
+ p ($arg0).u3.entry
596
+ end
597
+
598
+ define nd_vid
599
+ printf "%su1.id%s: ", $color_highlite, $color_end
600
+ p ($arg0).u1.id
601
+ end
602
+
603
+ define nd_cflag
604
+ printf "%su2.id%s: ", $color_highlite, $color_end
605
+ p ($arg0).u2.id
606
+ end
607
+
608
+ define nd_cval
609
+ printf "%su3.value%s: ", $color_highlite, $color_end
610
+ rp ($arg0).u3.value
611
+ end
612
+
613
+
614
+ define nd_cnt
615
+ printf "%su3.cnt%s: ", $color_highlite, $color_end
616
+ p ($arg0).u3.cnt
617
+ end
618
+
619
+ define nd_tbl
620
+ printf "%su1.tbl%s: ", $color_highlite, $color_end
621
+ p ($arg0).u1.tbl
622
+ end
623
+
624
+
625
+ define nd_var
626
+ printf "%su1.node%s: ", $color_highlite, $color_end
627
+ rp ($arg0).u1.node
628
+ end
629
+
630
+ define nd_ibdy
631
+ printf "%su2.node%s: ", $color_highlite, $color_end
632
+ rp ($arg0).u2.node
633
+ end
634
+
635
+ define nd_iter
636
+ printf "%su3.node%s: ", $color_highlite, $color_end
637
+ rp ($arg0).u3.node
638
+ end
639
+
640
+
641
+ define nd_value
642
+ printf "%su2.node%s: ", $color_highlite, $color_end
643
+ rp ($arg0).u2.node
644
+ end
645
+
646
+ define nd_aid
647
+ printf "%su3.id%s: ", $color_highlite, $color_end
648
+ p ($arg0).u3.id
649
+ end
650
+
651
+
652
+ define nd_lit
653
+ printf "%su1.value%s: ", $color_highlite, $color_end
654
+ rp ($arg0).u1.value
655
+ end
656
+
657
+
658
+ define nd_frml
659
+ printf "%su1.node%s: ", $color_highlite, $color_end
660
+ rp ($arg0).u1.node
661
+ end
662
+
663
+ define nd_rest
664
+ printf "%su2.argc%s: ", $color_highlite, $color_end
665
+ p ($arg0).u2.argc
666
+ end
667
+
668
+ define nd_opt
669
+ printf "%su1.node%s: ", $color_highlite, $color_end
670
+ rp ($arg0).u1.node
671
+ end
672
+
673
+
674
+ define nd_recv
675
+ printf "%su1.node%s: ", $color_highlite, $color_end
676
+ rp ($arg0).u1.node
677
+ end
678
+
679
+ define nd_mid
680
+ printf "%su2.id%s: ", $color_highlite, $color_end
681
+ p ($arg0).u2.id
682
+ end
683
+
684
+ define nd_args
685
+ printf "%su3.node%s: ", $color_highlite, $color_end
686
+ rp ($arg0).u3.node
687
+ end
688
+
689
+
690
+ define nd_noex
691
+ printf "%su1.id%s: ", $color_highlite, $color_end
692
+ p ($arg0).u1.id
693
+ end
694
+
695
+ define nd_defn
696
+ printf "%su3.node%s: ", $color_highlite, $color_end
697
+ rp ($arg0).u3.node
698
+ end
699
+
700
+
701
+ define nd_old
702
+ printf "%su1.id%s: ", $color_highlite, $color_end
703
+ p ($arg0).u1.id
704
+ end
705
+
706
+ define nd_new
707
+ printf "%su2.id%s: ", $color_highlite, $color_end
708
+ p ($arg0).u2.id
709
+ end
710
+
711
+
712
+ define nd_cfnc
713
+ printf "%su1.cfunc%s: ", $color_highlite, $color_end
714
+ p ($arg0).u1.cfunc
715
+ end
716
+
717
+ define nd_argc
718
+ printf "%su2.argc%s: ", $color_highlite, $color_end
719
+ p ($arg0).u2.argc
720
+ end
721
+
722
+
723
+ define nd_cname
724
+ printf "%su1.id%s: ", $color_highlite, $color_end
725
+ p ($arg0).u1.id
726
+ end
727
+
728
+ define nd_super
729
+ printf "%su3.node%s: ", $color_highlite, $color_end
730
+ rp ($arg0).u3.node
731
+ end
732
+
733
+
734
+ define nd_modl
735
+ printf "%su1.id%s: ", $color_highlite, $color_end
736
+ p ($arg0).u1.id
737
+ end
738
+
739
+ define nd_clss
740
+ printf "%su1.value%s: ", $color_highlite, $color_end
741
+ rp ($arg0).u1.value
742
+ end
743
+
744
+
745
+ define nd_beg
746
+ printf "%su1.node%s: ", $color_highlite, $color_end
747
+ rp ($arg0).u1.node
748
+ end
749
+
750
+ define nd_end
751
+ printf "%su2.node%s: ", $color_highlite, $color_end
752
+ rp ($arg0).u2.node
753
+ end
754
+
755
+ define nd_state
756
+ printf "%su3.state%s: ", $color_highlite, $color_end
757
+ p ($arg0).u3.state
758
+ end
759
+
760
+ define nd_rval
761
+ printf "%su2.value%s: ", $color_highlite, $color_end
762
+ rp ($arg0).u2.value
763
+ end
764
+
765
+
766
+ define nd_nth
767
+ printf "%su2.argc%s: ", $color_highlite, $color_end
768
+ p ($arg0).u2.argc
769
+ end
770
+
771
+
772
+ define nd_tag
773
+ printf "%su1.id%s: ", $color_highlite, $color_end
774
+ p ($arg0).u1.id
775
+ end
776
+
777
+ define nd_tval
778
+ printf "%su2.value%s: ", $color_highlite, $color_end
779
+ rp ($arg0).u2.value
780
+ end
781
+
782
+ define nd_tree
783
+ set $buf = (struct RString *)rb_str_buf_new(0)
784
+ call dump_node((VALUE)($buf), rb_str_new(0, 0), 0, ($arg0))
785
+ printf "%s\n", $buf->as.heap.ptr
786
+ end
787
+
788
+ define rb_p
789
+ call rb_p($arg0)
790
+ end
791
+
792
+ define rb_numtable_entry
793
+ set $rb_numtable_tbl = $arg0
794
+ set $rb_numtable_id = (st_data_t)$arg1
795
+ set $rb_numtable_key = 0
796
+ set $rb_numtable_rec = 0
797
+ if $rb_numtable_tbl->entries_packed
798
+ set $rb_numtable_p = $rb_numtable_tbl->as.packed.bins
799
+ while $rb_numtable_p && $rb_numtable_p < $rb_numtable_tbl->as.packed.bins+$rb_numtable_tbl->num_entries
800
+ if $rb_numtable_p.k == $rb_numtable_id
801
+ set $rb_numtable_key = $rb_numtable_p.k
802
+ set $rb_numtable_rec = $rb_numtable_p.v
803
+ set $rb_numtable_p = 0
804
+ else
805
+ set $rb_numtable_p = $rb_numtable_p + 1
806
+ end
807
+ end
808
+ else
809
+ set $rb_numtable_p = $rb_numtable_tbl->as.big.bins[st_numhash($rb_numtable_id) % $rb_numtable_tbl->num_bins]
810
+ while $rb_numtable_p
811
+ if $rb_numtable_p->key == $rb_numtable_id
812
+ set $rb_numtable_key = $rb_numtable_p->key
813
+ set $rb_numtable_rec = $rb_numtable_p->record
814
+ set $rb_numtable_p = 0
815
+ else
816
+ set $rb_numtable_p = $rb_numtable_p->next
817
+ end
818
+ end
819
+ end
820
+ end
821
+
822
+ define rb_id2name
823
+ ruby_gdb_init
824
+ printf "%sID%s: ", $color_type, $color_end
825
+ rp_id $arg0
826
+ end
827
+ document rb_id2name
828
+ Print the name of id
829
+ end
830
+
831
+ define rb_method_entry
832
+ set $rb_method_entry_klass = (struct RClass *)$arg0
833
+ set $rb_method_entry_id = (ID)$arg1
834
+ set $rb_method_entry_me = (rb_method_entry_t *)0
835
+ while !$rb_method_entry_me && $rb_method_entry_klass
836
+ rb_numtable_entry $rb_method_entry_klass->m_tbl_wrapper->tbl $rb_method_entry_id
837
+ set $rb_method_entry_me = (rb_method_entry_t *)$rb_numtable_rec
838
+ if !$rb_method_entry_me
839
+ set $rb_method_entry_klass = (struct RClass *)RCLASS_SUPER($rb_method_entry_klass)
840
+ end
841
+ end
842
+ if $rb_method_entry_me
843
+ print *$rb_method_entry_klass
844
+ print *$rb_method_entry_me
845
+ else
846
+ echo method not found\n
847
+ end
848
+ end
849
+ document rb_method_entry
850
+ Search method entry by class and id
851
+ end
852
+
853
+ define rb_classname
854
+ # up to 128bit int
855
+ set $rb_classname_permanent = "0123456789ABCDEF"
856
+ set $rb_classname = classname($arg0, $rb_classname_permanent)
857
+ if $rb_classname != RUBY_Qnil
858
+ rp $rb_classname
859
+ else
860
+ echo anonymous class/module\n
861
+ end
862
+ end
863
+
864
+ define rb_ancestors
865
+ set $rb_ancestors_module = $arg0
866
+ while $rb_ancestors_module
867
+ rp_class $rb_ancestors_module
868
+ set $rb_ancestors_module = RCLASS_SUPER($rb_ancestors_module)
869
+ end
870
+ end
871
+ document rb_ancestors
872
+ Print ancestors.
873
+ end
874
+
875
+ define rb_backtrace
876
+ call rb_backtrace()
877
+ end
878
+
879
+ define iseq
880
+ if ruby_dummy_gdb_enums.special_consts
881
+ end
882
+ if ($arg0)->type == ISEQ_ELEMENT_NONE
883
+ echo [none]\n
884
+ end
885
+ if ($arg0)->type == ISEQ_ELEMENT_LABEL
886
+ print *(LABEL*)($arg0)
887
+ end
888
+ if ($arg0)->type == ISEQ_ELEMENT_INSN
889
+ print *(INSN*)($arg0)
890
+ if ((INSN*)($arg0))->insn_id != YARVINSN_jump
891
+ set $i = 0
892
+ set $operand_size = ((INSN*)($arg0))->operand_size
893
+ set $operands = ((INSN*)($arg0))->operands
894
+ while $i < $operand_size
895
+ rp $operands[$i++]
896
+ end
897
+ end
898
+ end
899
+ if ($arg0)->type == ISEQ_ELEMENT_ADJUST
900
+ print *(ADJUST*)($arg0)
901
+ end
902
+ end
903
+
904
+ define rb_ps
905
+ rb_ps_vm ruby_current_vm
906
+ end
907
+ document rb_ps
908
+ Dump all threads and their callstacks
909
+ end
910
+
911
+ define rb_ps_vm
912
+ print $ps_vm = (rb_vm_t*)$arg0
913
+ set $ps_thread_ln = $ps_vm->living_threads.n.next
914
+ set $ps_thread_ln_last = $ps_vm->living_threads.n.prev
915
+ while 1
916
+ set $ps_thread_th = (rb_thread_t *)$ps_thread_ln
917
+ set $ps_thread = (VALUE)($ps_thread_th->self)
918
+ rb_ps_thread $ps_thread
919
+ if $ps_thread_ln == $ps_thread_ln_last
920
+ loop_break
921
+ end
922
+ set $ps_thread_ln = $ps_thread_ln->next
923
+ end
924
+ end
925
+ document rb_ps_vm
926
+ Dump all threads in a (rb_vm_t*) and their callstacks
927
+ end
928
+
929
+ define rb_ps_thread
930
+ set $ps_thread = (struct RTypedData*)$arg0
931
+ set $ps_thread_th = (rb_thread_t*)$ps_thread->data
932
+ printf "* #<Thread:%p rb_thread_t:%p native_thread:%p>\n", \
933
+ $ps_thread, $ps_thread_th, $ps_thread_th->thread_id
934
+ end
935
+
936
+ # Details: https://bugs.ruby-lang.org/projects/ruby-trunk/wiki/MachineInstructionsTraceWithGDB
937
+ define trace_machine_instructions
938
+ set logging on
939
+ set height 0
940
+ set width 0
941
+ display/i $pc
942
+ while !$exit_code
943
+ info line *$pc
944
+ si
945
+ end
946
+ end
947
+
948
+ define SDR
949
+ call rb_vmdebug_stack_dump_raw_current()
950
+ end
951
+
952
+ define rbi
953
+ if ((LINK_ELEMENT*)$arg0)->type == ISEQ_ELEMENT_LABEL
954
+ p *(LABEL*)$arg0
955
+ else
956
+ if ((LINK_ELEMENT*)$arg0)->type == ISEQ_ELEMENT_INSN
957
+ p *(INSN*)$arg0
958
+ else
959
+ if ((LINK_ELEMENT*)$arg0)->type == ISEQ_ELEMENT_ADJUST
960
+ p *(ADJUST*)$arg0
961
+ else
962
+ print *$arg0
963
+ end
964
+ end
965
+ end
966
+ end