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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 47f96b6948a61ee96134de40f22548c97d265549
4
- data.tar.gz: 406b7e0a333f356278bc813082cbffc599f7fcc6
3
+ metadata.gz: aaf969a8db507b5039c1388a62aeb79b3ed84b25
4
+ data.tar.gz: 3997ea8491bd4e51eac15a947f94b77987c3d59a
5
5
  SHA512:
6
- metadata.gz: 73adc0c34ac5e358de859b99be87e59da5558cce6fbcc1ba5ffc01d366d1c0d3fe27abe82afc1b2966dccd6b9165e09932147402a09f29172b7345fc30a0e4b3
7
- data.tar.gz: eea4efc06c19748d84b626b6593a2afcb89ab9876f5e44c3686658bf222ce9f30d2a875de4efd4ff3db78373b5a5b532655cee35a21db5ea013d733794fe5486
6
+ metadata.gz: 4f1509a7d172d61d4a03ae1783a07f4cce70ff31a644c6a84feca32bf6b7e104b5b99ae2f25f7e2d9739f89968b00a85faa521a0122bb3692fb447d233960f1d
7
+ data.tar.gz: 44df74f4bca8c8ec24da6e07ecfcab451952c0c835ee8652f1c0f05fa338358711fda6d3a1887716168d6cb1e40fb2ce97cb2c640f9d5274fb323645967ab1d0
data/.gitignore CHANGED
@@ -8,3 +8,4 @@
8
8
  /spec/reports/
9
9
  /tmp/
10
10
  .ruby-version
11
+ core.*
@@ -1,3 +1,9 @@
1
+ # 0.9.4
2
+
3
+ Enhancements:
4
+
5
+ * Support core file
6
+
1
7
  # 0.9.3
2
8
 
3
9
  Enhancements:
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # gdbdump
2
2
 
3
- Print C level and Ruby level backtrace of living ruby process using gdb
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 verfied that gdbdump works with ruby executables built by [rbenv/ruby-build](https://github.com/rbenv/ruby-build).
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
- ### .gdbinit
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 living ruby 2.4.1 process of pid 1897,
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 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.
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
 
@@ -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{Print C level and Ruby level backtrace of living process using gdb.}
13
- spec.description = %q{Print C level and Ruby level backtrace of living process using gdb.}
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
 
@@ -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
- @pid = args.first
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(pid: @pid, **(@opts)).print_backtrace
56
+ GDB.new(@opts).print_backtrace
56
57
  end
57
58
  end
58
59
  end
@@ -9,17 +9,27 @@ class Gdbdump
9
9
  COMMAND_READ_BUFFER_SIZE = 1024
10
10
  SUDO_CMD = 'sudo'
11
11
 
12
- def initialize(pid:, debug: false, gdbinit: nil, gdb: nil, ruby: nil)
13
- @pid = pid.to_s
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
- @ruby = (ruby || Procfs.new(@pid).exe).tap do |path|
17
- raise "ruby #{path} is not accessible" unless File.executable?(path)
18
- end
19
- @gdbinit = (gdbinit || File.join(ROOT, 'vendor', 'ruby', ruby_minor_version, 'gdbinit')).tap do |path|
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
@@ -1,3 +1,3 @@
1
1
  class Gdbdump
2
- VERSION = "0.9.3"
2
+ VERSION = "0.9.4"
3
3
  end
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.3
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-04 00:00:00.000000000 Z
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: Print C level and Ruby level backtrace of living process using gdb.
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: Print C level and Ruby level backtrace of living process using gdb.
115
+ summary: Dump C level and Ruby level backtrace from living process or core file using
116
+ gdb.
115
117
  test_files: []