rbtrace 0.4.9 → 0.4.10
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 +5 -5
- data/.gitignore +1 -0
- data/Gemfile.lock +8 -3
- data/README.md +14 -0
- data/Rakefile +14 -0
- data/lib/rbtrace/cli.rb +98 -9
- data/lib/rbtrace/memory_report.rb +20 -0
- data/lib/rbtrace/version.rb +1 -1
- data/rbtrace.gemspec +7 -0
- metadata +20 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 574f273f971a108d9e994a3f236c3722a649d13093f75a371249dbe6556bc6f0
|
4
|
+
data.tar.gz: 2aa00597a8016c8359276314b61d3bc43948f8db343423821b3015dcbe1be60b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1c79741a8c653395f4b371caf63f1e1e2c67aa109446ee6365543aad68bd58508808768c5c28ba96eae3db5fa760c2914dc68e66d095bf6806e130ea50511577
|
7
|
+
data.tar.gz: 7d4d8f89d2d6c63f635db87801d592a7bfffb2aa48f415e534a1ec3f9c30c55046315dd4394a804b91f7c81599d411ebab8f8168b3cbd8041b547d2b0c04a4ae
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rbtrace (0.4.
|
4
|
+
rbtrace (0.4.10)
|
5
5
|
ffi (>= 1.0.6)
|
6
6
|
msgpack (>= 0.4.3)
|
7
7
|
trollop (>= 1.16.2)
|
@@ -9,12 +9,17 @@ PATH
|
|
9
9
|
GEM
|
10
10
|
remote: https://rubygems.org/
|
11
11
|
specs:
|
12
|
-
ffi (1.9.
|
13
|
-
msgpack (
|
12
|
+
ffi (1.9.18)
|
13
|
+
msgpack (1.2.2)
|
14
|
+
rake (10.5.0)
|
14
15
|
trollop (2.1.2)
|
15
16
|
|
16
17
|
PLATFORMS
|
17
18
|
ruby
|
18
19
|
|
19
20
|
DEPENDENCIES
|
21
|
+
rake (~> 10.0)
|
20
22
|
rbtrace!
|
23
|
+
|
24
|
+
BUNDLED WITH
|
25
|
+
1.16.1
|
data/README.md
CHANGED
@@ -14,6 +14,11 @@ in production.
|
|
14
14
|
% gem install rbtrace
|
15
15
|
% rbtrace --help
|
16
16
|
|
17
|
+
## supported Rubies
|
18
|
+
|
19
|
+
rbtrace supports all stable versions of Ruby MRI, as of 23-01-2018 this is
|
20
|
+
Ruby version 2.2 and later.
|
21
|
+
|
17
22
|
## tracer types
|
18
23
|
|
19
24
|
rbtrace has several different tracing modes.
|
@@ -34,6 +39,14 @@ rbtrace has several different tracing modes.
|
|
34
39
|
|
35
40
|
% rbtrace -p <PID> --gc
|
36
41
|
|
42
|
+
### memory: produce a basic memory report regarding process (including GC.stat and ObjectSpace stats)
|
43
|
+
|
44
|
+
% rbtrace -p <PID> --memory
|
45
|
+
|
46
|
+
### backtraces: return backtraces for all active threads in a process
|
47
|
+
|
48
|
+
% rbtrace -p <PID> --backtraces
|
49
|
+
|
37
50
|
### notes
|
38
51
|
|
39
52
|
`--firehose` is not reliable on osx.
|
@@ -193,6 +206,7 @@ for popular ruby libraries and functions.
|
|
193
206
|
|
194
207
|
## todo
|
195
208
|
|
209
|
+
* correct irb implementation so it establishes a dedicated channel
|
196
210
|
* add triggers to start tracing slow methods only inside another method
|
197
211
|
* add watch expressions to fire tracers only when an expression is true
|
198
212
|
* add special expressions for method args (_arg0_, _arguments_)
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
desc "Compile the c extension"
|
4
|
+
task :compile do
|
5
|
+
if File.exist?("ext/Makefile")
|
6
|
+
system "(cd ext && make clean)"
|
7
|
+
end
|
8
|
+
system "(cd ext && ruby extconf.rb)"
|
9
|
+
system "(cd ext && make)"
|
10
|
+
end
|
11
|
+
|
12
|
+
task :build => :compile
|
13
|
+
|
14
|
+
|
data/lib/rbtrace/cli.rb
CHANGED
@@ -197,6 +197,12 @@ EOS
|
|
197
197
|
:default => 'irb',
|
198
198
|
:short => '-i'
|
199
199
|
|
200
|
+
opt :backtraces,
|
201
|
+
"get backtraces for all threads in current process, -1 denotes all frames",
|
202
|
+
:type => String,
|
203
|
+
:default => '-1',
|
204
|
+
:short => '-b'
|
205
|
+
|
200
206
|
opt :backtrace,
|
201
207
|
"get lines from the current backtrace in the process",
|
202
208
|
:type => :int
|
@@ -209,6 +215,16 @@ EOS
|
|
209
215
|
opt :timeout,
|
210
216
|
"seconds to wait before giving up on attach/detach/eval",
|
211
217
|
:default => 5
|
218
|
+
|
219
|
+
opt :memory,
|
220
|
+
"report on process memory usage"
|
221
|
+
|
222
|
+
|
223
|
+
opt :heapdump,
|
224
|
+
"generate a heap dump for the process in FILENAME",
|
225
|
+
:default => "AUTO",
|
226
|
+
:short => "-h"
|
227
|
+
|
212
228
|
end
|
213
229
|
|
214
230
|
opts = Trollop.with_standard_exception_handling(parser) do
|
@@ -224,8 +240,8 @@ EOS
|
|
224
240
|
ARGV.clear
|
225
241
|
end
|
226
242
|
|
227
|
-
unless %w[ fork eval interactive backtrace slow slowcpu firehose methods config gc ].find{ |n| opts[:"#{n}_given"] }
|
228
|
-
$stderr.puts "Error: --slow, --slowcpu, --gc, --firehose, --methods, --interactive or --config required."
|
243
|
+
unless %w[ fork eval interactive backtrace backtraces slow slowcpu firehose methods config gc memory heapdump].find{ |n| opts[:"#{n}_given"] }
|
244
|
+
$stderr.puts "Error: --slow, --slowcpu, --gc, --firehose, --methods, --interactive, --backtraces, --backtrace, --memory, --heapdump or --config required."
|
229
245
|
$stderr.puts "Try --help for help."
|
230
246
|
exit(-1)
|
231
247
|
end
|
@@ -285,18 +301,32 @@ EOS
|
|
285
301
|
if filtered.size > 0
|
286
302
|
max_len = filtered.size.to_s.size
|
287
303
|
|
288
|
-
STDERR.puts "*** found #{filtered.size}
|
304
|
+
STDERR.puts "*** found #{filtered.size} process#{filtered.size == 1 ? "" : "es"} matching #{opts[:ps].inspect}"
|
289
305
|
filtered.each_with_index do |line, i|
|
290
|
-
|
306
|
+
prefix = " [#{(i+1).to_s.rjust(max_len)}] "
|
307
|
+
if filtered.length == 1
|
308
|
+
prefix = ""
|
309
|
+
end
|
310
|
+
STDERR.puts "#{prefix}#{line.strip}"
|
311
|
+
end
|
312
|
+
|
313
|
+
if filtered.length > 1
|
314
|
+
STDERR.puts " [#{'0'.rjust(max_len)}] all #{filtered.size} processes"
|
291
315
|
end
|
292
|
-
STDERR.puts " [#{'0'.rjust(max_len)}] all #{filtered.size} processes"
|
293
316
|
|
294
317
|
while true
|
295
318
|
STDERR.sync = true
|
296
|
-
|
319
|
+
|
320
|
+
if filtered.length > 1
|
321
|
+
STDERR.print "*** trace which processes? (0/1,4): "
|
322
|
+
end
|
297
323
|
|
298
324
|
begin
|
299
|
-
|
325
|
+
if filtered.length == 1
|
326
|
+
input = "1"
|
327
|
+
else
|
328
|
+
input = gets
|
329
|
+
end
|
300
330
|
rescue Interrupt
|
301
331
|
exit 1
|
302
332
|
end
|
@@ -372,9 +402,9 @@ EOS
|
|
372
402
|
end
|
373
403
|
rescue Interrupt, SignalException
|
374
404
|
STDERR.puts "*** waiting on child tracers: #{tracers.inspect}"
|
375
|
-
tracers.each do |
|
405
|
+
tracers.each do |pid1|
|
376
406
|
begin
|
377
|
-
Process.kill 'INT',
|
407
|
+
Process.kill 'INT', pid1
|
378
408
|
rescue Errno::ESRCH
|
379
409
|
end
|
380
410
|
end
|
@@ -413,6 +443,65 @@ EOS
|
|
413
443
|
tracer.puts res[1..-2].split('|').join("\n ")
|
414
444
|
end
|
415
445
|
|
446
|
+
elsif opts[:backtraces_given]
|
447
|
+
num = opts[:backtraces].to_i
|
448
|
+
num = -1 if num == 0
|
449
|
+
|
450
|
+
delim = "146621c9d681409aa"
|
451
|
+
|
452
|
+
code = "Thread.list.map{|t| t.backtrace[0...#{num}].join(\"#{delim}\")}.join(\"#{delim*2}\")"
|
453
|
+
|
454
|
+
if res = tracer.eval(code)
|
455
|
+
tracer.puts res.split(delim).join("\n")
|
456
|
+
end
|
457
|
+
|
458
|
+
elsif opts[:memory_given]
|
459
|
+
memory_report = File.expand_path('../memory_report.rb', __FILE__)
|
460
|
+
|
461
|
+
require 'tempfile'
|
462
|
+
output = Tempfile.new("output")
|
463
|
+
output.close
|
464
|
+
|
465
|
+
begin
|
466
|
+
code = "Thread.new do; begin; output = '#{output.path}'; eval(File.read('#{memory_report}')); end; end"
|
467
|
+
tracer.eval(code)
|
468
|
+
|
469
|
+
File.open(output.path, 'r') do |f|
|
470
|
+
while true
|
471
|
+
begin
|
472
|
+
unless line = f.readline
|
473
|
+
sleep 0.1
|
474
|
+
next
|
475
|
+
end
|
476
|
+
|
477
|
+
if line.strip == "__END__"
|
478
|
+
break
|
479
|
+
else
|
480
|
+
print line
|
481
|
+
end
|
482
|
+
rescue EOFError
|
483
|
+
sleep 0.1
|
484
|
+
end
|
485
|
+
end
|
486
|
+
end
|
487
|
+
ensure
|
488
|
+
output.unlink
|
489
|
+
end
|
490
|
+
|
491
|
+
elsif opts[:heapdump_given]
|
492
|
+
filename = opts[:heapdump]
|
493
|
+
|
494
|
+
if filename == "AUTO"
|
495
|
+
require 'tempfile'
|
496
|
+
temp = Tempfile.new("dump")
|
497
|
+
filename = temp.path
|
498
|
+
temp.close
|
499
|
+
temp.unlink
|
500
|
+
end
|
501
|
+
|
502
|
+
tracer.eval("file = File.open('#{filename}', 'w'); ObjectSpace.dump_all(output: file); file.close")
|
503
|
+
puts "Heapdump being written to #{filename}"
|
504
|
+
|
416
505
|
elsif opts[:eval_given]
|
417
506
|
if res = tracer.eval(code = opts[:eval])
|
418
507
|
tracer.puts ">> #{code}"
|
@@ -0,0 +1,20 @@
|
|
1
|
+
output
|
2
|
+
fork do
|
3
|
+
file = File.new(output, 'w')
|
4
|
+
|
5
|
+
file.puts "GC Stats",""
|
6
|
+
GC.stat.each do |k, v|
|
7
|
+
file.puts "#{k}: #{v}"
|
8
|
+
end
|
9
|
+
|
10
|
+
file.puts "", "Object Stats", ""
|
11
|
+
require 'objspace'
|
12
|
+
ObjectSpace.count_objects.sort{|a,b| b[1] <=> a[1]}.each do |k, v|
|
13
|
+
file.puts "#{k}: #{v}"
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
file.puts "__END__"
|
18
|
+
file.flush
|
19
|
+
file.close
|
20
|
+
end
|
data/lib/rbtrace/version.rb
CHANGED
data/rbtrace.gemspec
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require File.expand_path('../lib/rbtrace/version', __FILE__)
|
2
4
|
|
3
5
|
Gem::Specification.new do |s|
|
@@ -8,16 +10,21 @@ Gem::Specification.new do |s|
|
|
8
10
|
s.authors = 'Aman Gupta'
|
9
11
|
s.email = 'aman@tmm1.net'
|
10
12
|
|
13
|
+
s.require_paths = ['lib', 'ext']
|
14
|
+
|
11
15
|
s.files = `git ls-files`.split("\n")
|
12
16
|
s.extensions = 'ext/extconf.rb'
|
13
17
|
|
14
18
|
s.bindir = 'bin'
|
15
19
|
s.executables << 'rbtrace'
|
16
20
|
|
21
|
+
|
17
22
|
s.add_dependency 'ffi', '>= 1.0.6'
|
18
23
|
s.add_dependency 'trollop', '>= 1.16.2'
|
19
24
|
s.add_dependency 'msgpack', '>= 0.4.3'
|
20
25
|
|
26
|
+
s.add_development_dependency "rake", "~> 10.0"
|
27
|
+
|
21
28
|
s.license = "MIT"
|
22
29
|
s.summary = 'rbtrace: like strace but for ruby code'
|
23
30
|
s.description = 'rbtrace shows you method calls happening inside another ruby process in real time.'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbtrace
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aman Gupta
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-01-
|
11
|
+
date: 2018-01-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 0.4.3
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
55
69
|
description: rbtrace shows you method calls happening inside another ruby process
|
56
70
|
in real time.
|
57
71
|
email: aman@tmm1.net
|
@@ -66,6 +80,7 @@ files:
|
|
66
80
|
- Gemfile.lock
|
67
81
|
- LICENSE
|
68
82
|
- README.md
|
83
|
+
- Rakefile
|
69
84
|
- bin/rbtrace
|
70
85
|
- ext/.gitignore
|
71
86
|
- ext/extconf.rb
|
@@ -75,6 +90,7 @@ files:
|
|
75
90
|
- lib/rbtrace/core_ext.rb
|
76
91
|
- lib/rbtrace/interactive/irb.rb
|
77
92
|
- lib/rbtrace/interactive/rib.rb
|
93
|
+
- lib/rbtrace/memory_report.rb
|
78
94
|
- lib/rbtrace/msgq.rb
|
79
95
|
- lib/rbtrace/rbtracer.rb
|
80
96
|
- lib/rbtrace/version.rb
|
@@ -96,6 +112,7 @@ post_install_message:
|
|
96
112
|
rdoc_options: []
|
97
113
|
require_paths:
|
98
114
|
- lib
|
115
|
+
- ext
|
99
116
|
required_ruby_version: !ruby/object:Gem::Requirement
|
100
117
|
requirements:
|
101
118
|
- - ">="
|
@@ -108,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
108
125
|
version: '0'
|
109
126
|
requirements: []
|
110
127
|
rubyforge_project:
|
111
|
-
rubygems_version: 2.
|
128
|
+
rubygems_version: 2.7.3
|
112
129
|
signing_key:
|
113
130
|
specification_version: 4
|
114
131
|
summary: 'rbtrace: like strace but for ruby code'
|