gdbdump 0.9.3 → 0.9.4
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/.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: []
|