gdbdump 0.9.0 → 0.9.1
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 +4 -4
- data/CHANGELOG.md +10 -0
- data/README.md +12 -10
- data/lib/gdbdump/cli.rb +8 -7
- data/lib/gdbdump/gdb.rb +6 -15
- data/lib/gdbdump/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 589c4ae8d652fe1c24deb76f73deea5ba82ec242
|
4
|
+
data.tar.gz: 2689d144842a157d13168a70c28adcce61a5e78d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5923cc6b4353b49039095e8440401b92645e6080dd95bc5c45a46804ed649f2cdc3e280a3fbef2f9f3b1759ce32a4dd7c0fc9e6061fbfe7c37ad6dcb4aaabc55
|
7
|
+
data.tar.gz: 12dd18e4ca417c9d108767aa13f43d39aea3d69d477017ea19c1e91140b1a3af00fcdc2ff88b338ca6854b0256f6fd996dfecdafbae1d66859460a59a4b1c153
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
# 0.9.1
|
2
|
+
|
3
|
+
Enhancements:
|
4
|
+
|
5
|
+
* Get ruby version from `ruby -e 'puts RUBY_VERSION'` instead of `strings ruby | grep RUBY_VERSION` so that I do not need to assume `strings` command is available
|
6
|
+
|
7
|
+
Changes:
|
8
|
+
|
9
|
+
* Add `--ruby` option instead of `[prog pid]` argument style.
|
10
|
+
|
1
11
|
# 0.9.0
|
2
12
|
|
3
13
|
Enhancements:
|
data/README.md
CHANGED
@@ -19,10 +19,11 @@ It was verfied that gdbdump works with ruby executables built by [rbenv/ruby-bui
|
|
19
19
|
## Usage
|
20
20
|
|
21
21
|
```
|
22
|
-
Usage: gdbdump [options]
|
23
|
-
-d, --[no-]debug
|
24
|
-
-x, --gdbinit FILE
|
25
|
-
--gdb PATH
|
22
|
+
Usage: gdbdump [options] 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 pre-bundle in this gem)
|
25
|
+
--gdb PATH path to gdb command (default: gdb)
|
26
|
+
--ruby PATH path to ruby which the attached process uses (default: get from /proc/[PID]/exe)
|
26
27
|
```
|
27
28
|
|
28
29
|
### .gdbinit
|
@@ -43,7 +44,7 @@ With living ruby 2.4.1 process of pid 1897,
|
|
43
44
|
$ gdbdump 1897
|
44
45
|
```
|
45
46
|
|
46
|
-
You will see C and Ruby level backtrace
|
47
|
+
You will see C and Ruby level backtrace as:
|
47
48
|
|
48
49
|
```
|
49
50
|
$1 = (rb_vm_t *) 0x7f46bb071f20
|
@@ -64,11 +65,10 @@ loop.rb:11:in `block in <main>'
|
|
64
65
|
|
65
66
|
## FAQ
|
66
67
|
|
67
|
-
Q. How this work?
|
68
|
-
A. Attach to the ruby process with gdb, and call `rb_ps` defined in gdbinit. That's it.
|
69
|
-
|
70
|
-
|
71
|
-
A. GDB stops the process during printing backtrace, would cause some issues
|
68
|
+
* Q. How this work?
|
69
|
+
* A. Attach to the ruby process with gdb, and call `rb_ps` defined in gdbinit. That's it.
|
70
|
+
* Q. Is this available for production process?
|
71
|
+
* A. GDB stops the process during printing backtrace, would cause some issues
|
72
72
|
|
73
73
|
## Comparisons
|
74
74
|
|
@@ -77,9 +77,11 @@ A. GDB stops the process during printing backtrace, would cause some issues
|
|
77
77
|
* [sigdump](https://github.com/frsyuki/sigdump)
|
78
78
|
* sigdump enables to print ruby level backtrace with sending CONT signal to living ruby process.
|
79
79
|
* The ruby process must pre-install `sigdump` gem and `require 'sigdump/setup'` unlike gdbdump.
|
80
|
+
* sigdump prints backtrace in signal handler, so blocks main thread, but other threads still work unlike gdbdump.
|
80
81
|
* [gdbruby](https://github.com/gunyarakun/gdbruby)
|
81
82
|
* gdbruby enables to print C level and ruby level backtrace of living ruby process and core file.
|
82
83
|
* 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.
|
84
|
+
* gdbruby stops the process during printing backtrace as gdbdump, but it supports also core file. Using `gcore` command to get core file, it would be possible to analyze without stopping the process.
|
83
85
|
|
84
86
|
## Development
|
85
87
|
|
data/lib/gdbdump/cli.rb
CHANGED
@@ -18,19 +18,23 @@ class Gdbdump
|
|
18
18
|
debug: false,
|
19
19
|
gdbinit: nil,
|
20
20
|
gdb: nil,
|
21
|
+
ruby: nil,
|
21
22
|
}
|
22
23
|
|
23
24
|
op.on('-d', '--[no-]debug', "print debug log (default: #{opts[:debug]})") {|v|
|
24
25
|
opts[:debug] = v
|
25
26
|
}
|
26
|
-
op.on('-x', '--gdbinit FILE', "path to ruby trunk's .gdbinit (default: some of ruby trunk's .gdbinit is bundle in this gem
|
27
|
+
op.on('-x', '--gdbinit FILE', "path to ruby trunk's .gdbinit (default: some of ruby trunk's .gdbinit is pre-bundle in this gem)") {|v|
|
27
28
|
opts[:gdbinit] = v
|
28
29
|
}
|
29
30
|
op.on('--gdb PATH', "path to gdb command (default: gdb)") {|v|
|
30
31
|
opts[:gdb] = v
|
31
32
|
}
|
33
|
+
op.on('--ruby PATH', "path to ruby which the attached process uses (default: get from /proc/[PID]/exe)") {|v|
|
34
|
+
opts[:ruby] = v
|
35
|
+
}
|
32
36
|
|
33
|
-
op.banner += '
|
37
|
+
op.banner += ' pid'
|
34
38
|
begin
|
35
39
|
args = op.parse(argv)
|
36
40
|
rescue OptionParser::InvalidOption => e
|
@@ -39,11 +43,8 @@ class Gdbdump
|
|
39
43
|
|
40
44
|
if args.size == 1
|
41
45
|
@pid = args.first
|
42
|
-
@prog = Gdbdump::Procfs.new(@pid).exe
|
43
|
-
elsif args.size == 2
|
44
|
-
@prog, @pid = args
|
45
46
|
else
|
46
|
-
usage 'number of arguments must be 1
|
47
|
+
usage 'number of arguments must be 1'
|
47
48
|
end
|
48
49
|
|
49
50
|
@opts = opts
|
@@ -51,7 +52,7 @@ class Gdbdump
|
|
51
52
|
|
52
53
|
def run
|
53
54
|
parse_options
|
54
|
-
GDB.new(pid: @pid,
|
55
|
+
GDB.new(pid: @pid, **(@opts)).print_backtrace
|
55
56
|
end
|
56
57
|
end
|
57
58
|
end
|
data/lib/gdbdump/gdb.rb
CHANGED
@@ -2,21 +2,21 @@
|
|
2
2
|
require 'open3'
|
3
3
|
|
4
4
|
class Gdbdump
|
5
|
-
# GDB.new(pid: 999,
|
5
|
+
# GDB.new(pid: 999, debug: true).run do |gdb|
|
6
6
|
# puts gdb.cmd_exec('bt')
|
7
7
|
# end
|
8
8
|
class GDB
|
9
9
|
COMMAND_READ_BUFFER_SIZE = 1024
|
10
|
-
STRINGS_CMD = 'strings'
|
11
10
|
SUDO_CMD = 'sudo'
|
12
11
|
|
13
|
-
def initialize(pid:,
|
12
|
+
def initialize(pid:, debug: false, gdbinit: nil, gdb: nil, ruby: nil)
|
14
13
|
@pid = pid.to_s
|
15
|
-
@prog = prog
|
16
14
|
@debug = debug
|
17
|
-
@gdbinit = gdbinit || File.join(ROOT, 'vendor', 'ruby', ruby_version, 'gdbinit')
|
18
15
|
@gdb = gdb || 'gdb'
|
19
|
-
@
|
16
|
+
@ruby = ruby || Procfs.new(@pid).exe
|
17
|
+
@ruby_version = `#{@ruby} -e 'puts RUBY_VERSION'`.chomp
|
18
|
+
@gdbinit = gdbinit || File.join(ROOT, 'vendor', 'ruby', @ruby_version, 'gdbinit')
|
19
|
+
@exec_options = [SUDO_CMD, @gdb, '-silent', '-nw', '-x', @gdbinit, @ruby, @pid]
|
20
20
|
end
|
21
21
|
|
22
22
|
def print_backtrace
|
@@ -50,15 +50,6 @@ class Gdbdump
|
|
50
50
|
end
|
51
51
|
end
|
52
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
|
-
|
62
53
|
def cmd_exec(cmd)
|
63
54
|
log('C', cmd)
|
64
55
|
if cmd
|
data/lib/gdbdump/version.rb
CHANGED