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