gdbdump 0.1.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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