gdbdump 0.9.3 → 0.9.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +6 -0
- data/README.md +24 -11
- data/gdbdump.gemspec +2 -2
- data/lib/gdbdump/cli.rb +8 -7
- data/lib/gdbdump/gdb.rb +20 -16
- data/lib/gdbdump/version.rb +1 -1
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aaf969a8db507b5039c1388a62aeb79b3ed84b25
|
4
|
+
data.tar.gz: 3997ea8491bd4e51eac15a947f94b77987c3d59a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f1509a7d172d61d4a03ae1783a07f4cce70ff31a644c6a84feca32bf6b7e104b5b99ae2f25f7e2d9739f89968b00a85faa521a0122bb3692fb447d233960f1d
|
7
|
+
data.tar.gz: 44df74f4bca8c8ec24da6e07ecfcab451952c0c835ee8652f1c0f05fa338358711fda6d3a1887716168d6cb1e40fb2ce97cb2c640f9d5274fb323645967ab1d0
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# gdbdump
|
2
2
|
|
3
|
-
|
3
|
+
Dump C level and Ruby level backtrace from living ruby process or core file using gdb.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -12,33 +12,31 @@ $ gem install gdbdump
|
|
12
12
|
|
13
13
|
* gdb
|
14
14
|
* linux
|
15
|
-
* `sudo gdb` must be allowed
|
15
|
+
* `sudo gdb` must be allowed to dump backtrace of living ruby process
|
16
16
|
|
17
|
-
It was
|
17
|
+
It was verified that gdbdump works with ruby executables built by [rbenv/ruby-build](https://github.com/rbenv/ruby-build).
|
18
18
|
|
19
19
|
## Usage
|
20
20
|
|
21
21
|
```
|
22
|
-
Usage: gdbdump [options] pid
|
22
|
+
Usage: gdbdump [options] [ pid | /path/to/ruby pid | /path/to/ruby core ]
|
23
23
|
-d, --[no-]debug print debug log (default: false)
|
24
24
|
-x, --gdbinit FILE path to ruby repo's .gdbinit (default: some of ruby repo's .gdbinit is pre-bundle in this gem)
|
25
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)
|
27
26
|
```
|
28
27
|
|
29
|
-
###
|
28
|
+
### --gdbinit
|
30
29
|
|
31
30
|
Default supported ruby versions: 2.1.x - 2.4.x
|
32
31
|
|
33
|
-
Ruby repo'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.
|
34
|
-
Some versions written as above of .gdbinit are bundled in this gem, but if you want to use `gdbdump` for older or newer ruby versions:
|
32
|
+
Ruby repo'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. `.gdbinit` of some versions written on above are pre-bundled in this gem. But, if you want to use `gdbdump` for older or newer ruby versions:
|
35
33
|
|
36
34
|
1. Download .gdbinit from ruby repo like [ruby/2.4.1/.gdbinit](https://github.com/ruby/ruby/blob/v2_4_1/.gdbinit), and specify with `-x` option
|
37
35
|
2. Or, send PR to bundle the .gdbinit in `gdbdump` gem.
|
38
36
|
|
39
|
-
## Example
|
37
|
+
## Example (live ruby process)
|
40
38
|
|
41
|
-
With
|
39
|
+
With live ruby process of pid 1897,
|
42
40
|
|
43
41
|
```
|
44
42
|
$ gdbdump 1897
|
@@ -63,6 +61,20 @@ loop.rb:13:in `block (2 levels) in <main>'
|
|
63
61
|
loop.rb:11:in `block in <main>'
|
64
62
|
```
|
65
63
|
|
64
|
+
## Example (core file)
|
65
|
+
|
66
|
+
With core file, you have to specify path of ruby executable.
|
67
|
+
|
68
|
+
```
|
69
|
+
$ gdbdump $HOME/.rbenv/versions/2.4.1/bin/ruby core.1897
|
70
|
+
```
|
71
|
+
|
72
|
+
You can get a core file with `gcore` command as:
|
73
|
+
|
74
|
+
```
|
75
|
+
$ sudo gcore 1897
|
76
|
+
```
|
77
|
+
|
66
78
|
## FAQ
|
67
79
|
|
68
80
|
* Q. How this work?
|
@@ -81,7 +93,8 @@ loop.rb:11:in `block in <main>'
|
|
81
93
|
* [gdbruby](https://github.com/gunyarakun/gdbruby)
|
82
94
|
* gdbruby enables to print C level and ruby level backtrace of living ruby process and core file.
|
83
95
|
* 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
|
96
|
+
* gdbruby supports only ruby 2.0 and 2.1 (2017-06-05).
|
97
|
+
* I believe `gdbdump` can replace `gdbruby`.
|
85
98
|
|
86
99
|
## Development
|
87
100
|
|
data/gdbdump.gemspec
CHANGED
@@ -9,8 +9,8 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["Naotoshi Seo"]
|
10
10
|
spec.email = ["sonots@gmail.com"]
|
11
11
|
|
12
|
-
spec.summary = %q{
|
13
|
-
spec.description = %q{
|
12
|
+
spec.summary = %q{Dump C level and Ruby level backtrace from living process or core file using gdb.}
|
13
|
+
spec.description = %q{Dump C level and Ruby level backtrace from living process or core file using gdb.}
|
14
14
|
spec.homepage = "https://github.com/sonots/gdbdump-ruby"
|
15
15
|
spec.license = "MIT"
|
16
16
|
|
data/lib/gdbdump/cli.rb
CHANGED
@@ -19,6 +19,7 @@ class Gdbdump
|
|
19
19
|
gdbinit: nil,
|
20
20
|
gdb: nil,
|
21
21
|
ruby: nil,
|
22
|
+
pid_or_core: nil,
|
22
23
|
}
|
23
24
|
|
24
25
|
op.on('-d', '--[no-]debug', "print debug log (default: #{opts[:debug]})") {|v|
|
@@ -30,11 +31,8 @@ class Gdbdump
|
|
30
31
|
op.on('--gdb PATH', "path to gdb command (default: gdb)") {|v|
|
31
32
|
opts[:gdb] = v
|
32
33
|
}
|
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
|
-
}
|
36
34
|
|
37
|
-
op.banner += ' pid'
|
35
|
+
op.banner += ' [ pid | /path/to/ruby pid | /path/to/ruby core ]'
|
38
36
|
begin
|
39
37
|
args = op.parse(argv)
|
40
38
|
rescue OptionParser::InvalidOption => e
|
@@ -42,9 +40,12 @@ class Gdbdump
|
|
42
40
|
end
|
43
41
|
|
44
42
|
if args.size == 1
|
45
|
-
|
43
|
+
opts[:pid_or_core] = args[0]
|
44
|
+
elsif args.size == 2
|
45
|
+
opts[:ruby] = args[0]
|
46
|
+
opts[:pid_or_core] = args[1]
|
46
47
|
else
|
47
|
-
usage 'number of arguments must be 1'
|
48
|
+
usage 'number of arguments must be 1 or 2'
|
48
49
|
end
|
49
50
|
|
50
51
|
@opts = opts
|
@@ -52,7 +53,7 @@ class Gdbdump
|
|
52
53
|
|
53
54
|
def run
|
54
55
|
parse_options
|
55
|
-
GDB.new(
|
56
|
+
GDB.new(@opts).print_backtrace
|
56
57
|
end
|
57
58
|
end
|
58
59
|
end
|
data/lib/gdbdump/gdb.rb
CHANGED
@@ -9,17 +9,27 @@ class Gdbdump
|
|
9
9
|
COMMAND_READ_BUFFER_SIZE = 1024
|
10
10
|
SUDO_CMD = 'sudo'
|
11
11
|
|
12
|
-
def initialize(
|
13
|
-
|
12
|
+
def initialize(ruby: nil, pid_or_core:, debug: false, gdbinit: nil, gdb: nil)
|
13
|
+
if pid_or_core =~ /\A\d+\z/
|
14
|
+
@pid = pid_or_core.to_s
|
15
|
+
@ruby = ruby || Procfs.new(@pid).exe
|
16
|
+
else
|
17
|
+
@core = pid_or_core
|
18
|
+
raise "core #{@core} is not readable" unless File.readable?(@core)
|
19
|
+
@ruby = ruby || raise("With core file, ruby path is required")
|
20
|
+
end
|
21
|
+
@pid_or_core = pid_or_core
|
22
|
+
raise "ruby #{@ruby} is not accessible" unless File.executable?(@ruby)
|
23
|
+
|
24
|
+
@gdbinit = gdbinit || File.join(ROOT, 'vendor', 'ruby', ruby_minor_version, 'gdbinit')
|
25
|
+
raise "gdbinit #{@gdbinit} is not readable" unless File.readable?(@gdbinit)
|
26
|
+
|
14
27
|
@debug = debug
|
15
28
|
@gdb = gdb || 'gdb'
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
raise "gdbinit #{path} is not readable" unless File.readable?(path)
|
21
|
-
end
|
22
|
-
@exec_options = [SUDO_CMD, @gdb, '-silent', '-nw', '-x', @gdbinit, @ruby, @pid]
|
29
|
+
|
30
|
+
@exec_options = [@gdb, '-silent', '-nw', '-x', @gdbinit, @ruby, @pid_or_core]
|
31
|
+
@exec_options.unshift(SUDO_CMD) if @pid # sudo is required to ptrace a living process
|
32
|
+
log('C', @exec_options.join(' '))
|
23
33
|
end
|
24
34
|
|
25
35
|
private def ruby_version
|
@@ -36,12 +46,6 @@ class Gdbdump
|
|
36
46
|
$stdout.puts out
|
37
47
|
$stderr.puts err unless err.empty?
|
38
48
|
end
|
39
|
-
# run do |gdb|
|
40
|
-
# gdb.cmd_exec('call write(2, "== c backtrace ==\n", 18)')
|
41
|
-
# gdb.cmd_exec('call rb_print_backtrace()')
|
42
|
-
# gdb.cmd_exec('call write(2, "== ruby backtrace ==\n", 21)')
|
43
|
-
# gdb.cmd_exec('call rb_backtrace()')
|
44
|
-
# end
|
45
49
|
end
|
46
50
|
|
47
51
|
def run
|
@@ -54,7 +58,7 @@ class Gdbdump
|
|
54
58
|
yield(self)
|
55
59
|
detach
|
56
60
|
ensure
|
57
|
-
Process.kill('CONT', @pid.to_i)
|
61
|
+
Process.kill('CONT', @pid.to_i) if @pid
|
58
62
|
@stdin.close
|
59
63
|
@stdout.close
|
60
64
|
@stderr.close
|
data/lib/gdbdump/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gdbdump
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Naotoshi Seo
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-06-
|
11
|
+
date: 2017-06-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,7 +52,8 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
-
description:
|
55
|
+
description: Dump C level and Ruby level backtrace from living process or core file
|
56
|
+
using gdb.
|
56
57
|
email:
|
57
58
|
- sonots@gmail.com
|
58
59
|
executables:
|
@@ -111,5 +112,6 @@ rubyforge_project:
|
|
111
112
|
rubygems_version: 2.6.11
|
112
113
|
signing_key:
|
113
114
|
specification_version: 4
|
114
|
-
summary:
|
115
|
+
summary: Dump C level and Ruby level backtrace from living process or core file using
|
116
|
+
gdb.
|
115
117
|
test_files: []
|