rbtrace 0.4.9 → 0.4.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +2 -0
- data/README.md +14 -0
- data/Rakefile +14 -0
- data/ext/extconf.rb +2 -2
- data/ext/rbtrace.c +57 -5
- data/lib/rbtrace/cli.rb +105 -16
- data/lib/rbtrace/memory_report.rb +20 -0
- data/lib/rbtrace/rbtracer.rb +8 -2
- data/lib/rbtrace/version.rb +3 -1
- data/rbtrace.gemspec +10 -3
- data/server.rb +13 -10
- data/tracers/activerecord.tracer +1 -0
- metadata +26 -11
- data/Gemfile.lock +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 78fc8aa96b3b20a4663ceaef1253f41443689e85f344a9efecb60c240e85183b
|
4
|
+
data.tar.gz: 2f2ab561dfe12096dcbe28ff188d07e34af48bbed936f09bbc0dd23309132bea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1710793189ea23b9048c68ff61c1c7f52202b4e7770991e4c049f9b1b069dbbe4fd71f59e2e79a06d34c4c15628073d0498175fcbb64572152c22b9636557a09
|
7
|
+
data.tar.gz: 315c8c2bc040cf790e4964a93ee9f50b97f9b2b7718f71790e8af36cb2d1fe01d529da06fd6b346747e45fc82b52b2fde6fd62bf9053010e8e93d38f76e575fe
|
data/.gitignore
CHANGED
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/ext/extconf.rb
CHANGED
@@ -13,7 +13,7 @@ require 'fileutils'
|
|
13
13
|
|
14
14
|
libdir = File.basename RbConfig::CONFIG['libdir']
|
15
15
|
|
16
|
-
unless File.
|
16
|
+
unless File.exist?("#{CWD}/dst/#{libdir}/libmsgpackc.a")
|
17
17
|
Logging.message "Building msgpack\n"
|
18
18
|
|
19
19
|
msgpack = File.basename('msgpack-1.1.0.tar.gz')
|
@@ -28,7 +28,7 @@ unless File.exists?("#{CWD}/dst/#{libdir}/libmsgpackc.a")
|
|
28
28
|
end
|
29
29
|
|
30
30
|
Dir.chdir('src') do
|
31
|
-
FileUtils.rm_rf(dir) if File.
|
31
|
+
FileUtils.rm_rf(dir) if File.exist?(dir)
|
32
32
|
|
33
33
|
sys("tar zxvfo #{msgpack}")
|
34
34
|
Dir.chdir(dir) do
|
data/ext/rbtrace.c
CHANGED
@@ -22,6 +22,7 @@
|
|
22
22
|
|
23
23
|
#include <msgpack.h>
|
24
24
|
#include <ruby.h>
|
25
|
+
#include <ruby/debug.h>
|
25
26
|
|
26
27
|
#ifndef RUBY_VM
|
27
28
|
#include <env.h>
|
@@ -51,6 +52,11 @@
|
|
51
52
|
#endif
|
52
53
|
|
53
54
|
|
55
|
+
// The SUN_LEN macro is not available on Android
|
56
|
+
#ifndef SUN_LEN
|
57
|
+
#define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) + strlen((ptr)->sun_path))
|
58
|
+
#endif
|
59
|
+
|
54
60
|
static uint64_t
|
55
61
|
ru_utime_usec()
|
56
62
|
{
|
@@ -688,7 +694,7 @@ rbtracer_add(char *query, bool is_slow)
|
|
688
694
|
*idx = NULL,
|
689
695
|
*method = NULL;
|
690
696
|
|
691
|
-
if (NULL != (idx =
|
697
|
+
if (NULL != (idx = strrchr(query, '.'))) {
|
692
698
|
klass_begin = 0;
|
693
699
|
klass_end = idx - query;
|
694
700
|
is_singleton = true;
|
@@ -700,7 +706,7 @@ rbtracer_add(char *query, bool is_slow)
|
|
700
706
|
|
701
707
|
method = idx+1;
|
702
708
|
|
703
|
-
} else if (NULL != (idx =
|
709
|
+
} else if (NULL != (idx = strrchr(query, '#'))) {
|
704
710
|
klass_begin = 0;
|
705
711
|
klass_end = idx - query;
|
706
712
|
is_singleton = false;
|
@@ -862,6 +868,20 @@ msgq_setup()
|
|
862
868
|
#endif
|
863
869
|
}
|
864
870
|
|
871
|
+
static VALUE rbtrace_module;
|
872
|
+
|
873
|
+
static VALUE
|
874
|
+
eval_inspect(VALUE rb_code) {
|
875
|
+
return rb_funcall(rbtrace_module, rb_intern("eval_and_inspect"), 1, rb_code);
|
876
|
+
}
|
877
|
+
|
878
|
+
static VALUE
|
879
|
+
rescue_inspect(VALUE arg) {
|
880
|
+
VALUE exception = rb_errinfo(); /* get last exception */
|
881
|
+
rb_set_errinfo(Qnil);
|
882
|
+
return rb_funcall(exception, rb_intern("inspect"), 0);
|
883
|
+
}
|
884
|
+
|
865
885
|
static void
|
866
886
|
rbtrace__process_event(msgpack_object cmd)
|
867
887
|
{
|
@@ -1012,8 +1032,10 @@ rbtrace__process_event(msgpack_object cmd)
|
|
1012
1032
|
strncpy(query, str.ptr, str.size);
|
1013
1033
|
query[str.size] = 0;
|
1014
1034
|
|
1015
|
-
|
1016
|
-
|
1035
|
+
VALUE rb_code;
|
1036
|
+
rb_code = rb_str_new2(query);
|
1037
|
+
|
1038
|
+
val = rb_rescue(eval_inspect, rb_code, rescue_inspect, Qnil);
|
1017
1039
|
|
1018
1040
|
if (TYPE(val) == T_STRING) {
|
1019
1041
|
rbtrace__send_event(1,
|
@@ -1021,7 +1043,6 @@ rbtrace__process_event(msgpack_object cmd)
|
|
1021
1043
|
's', RSTRING_PTR(val)
|
1022
1044
|
);
|
1023
1045
|
}
|
1024
|
-
|
1025
1046
|
}
|
1026
1047
|
}
|
1027
1048
|
|
@@ -1102,9 +1123,40 @@ signal_handler_wrapper(VALUE arg, VALUE ctx)
|
|
1102
1123
|
}
|
1103
1124
|
#endif
|
1104
1125
|
|
1126
|
+
static VALUE
|
1127
|
+
send_write(VALUE klass, VALUE val) {
|
1128
|
+
if (TYPE(val) == T_STRING) {
|
1129
|
+
rbtrace__send_event(1,
|
1130
|
+
"write",
|
1131
|
+
's', RSTRING_PTR(val)
|
1132
|
+
);
|
1133
|
+
}
|
1134
|
+
|
1135
|
+
return Qnil;
|
1136
|
+
}
|
1137
|
+
|
1105
1138
|
void
|
1106
1139
|
Init_rbtrace()
|
1107
1140
|
{
|
1141
|
+
rbtrace_module = rb_define_module("RBTrace");
|
1142
|
+
VALUE output = rb_define_module_under(rbtrace_module, "OUT");
|
1143
|
+
|
1144
|
+
rb_define_singleton_method(output, "write", send_write, 1);
|
1145
|
+
|
1146
|
+
rb_eval_string(
|
1147
|
+
"module RBTrace\n"
|
1148
|
+
" def self.eval_context\n"
|
1149
|
+
" @eval_context ||= binding\n"
|
1150
|
+
" end\n"
|
1151
|
+
|
1152
|
+
" def self.eval_and_inspect(code)\n"
|
1153
|
+
" t = Thread.new { Thread.current[:output] = eval_context.eval(code).inspect }\n"
|
1154
|
+
" t.join\n"
|
1155
|
+
" t[:output]\n"
|
1156
|
+
" end\n"
|
1157
|
+
"end\n"
|
1158
|
+
);
|
1159
|
+
|
1108
1160
|
// hook into the gc
|
1109
1161
|
gc_hook = Data_Wrap_Struct(rb_cObject, rbtrace_gc_mark, NULL, NULL);
|
1110
1162
|
rb_global_variable(&gc_hook);
|
data/lib/rbtrace/cli.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'optimist'
|
2
2
|
require 'rbtrace/rbtracer'
|
3
3
|
require 'rbtrace/version'
|
4
4
|
|
@@ -12,7 +12,7 @@ class RBTraceCLI
|
|
12
12
|
#
|
13
13
|
# Returns nothing.
|
14
14
|
def self.check_msgmnb
|
15
|
-
if File.
|
15
|
+
if File.exist?(msgmnb = "/proc/sys/kernel/msgmnb")
|
16
16
|
curr = File.read(msgmnb).to_i
|
17
17
|
max = 1024*1024
|
18
18
|
cmd = "sysctl kernel.msgmnb=#{max}"
|
@@ -34,7 +34,7 @@ class RBTraceCLI
|
|
34
34
|
# Returns nothing.
|
35
35
|
def self.cleanup_queues
|
36
36
|
if (pids = `ps ax -o pid`.split("\n").map{ |p| p.strip.to_i }).any?
|
37
|
-
ipcs = `ipcs -q`.split("\n").grep(/^(q|0x)/).map{ |line| line[/(0x[a-f0-9]+)/,1] }
|
37
|
+
ipcs = `ipcs -q`.split("\n").grep(/^(q|0x)/).map{ |line| line[/(0x[a-f0-9]+)/,1] }.compact
|
38
38
|
ipcs.each do |ipci|
|
39
39
|
next if ipci.match(/^0xf/)
|
40
40
|
|
@@ -54,7 +54,7 @@ class RBTraceCLI
|
|
54
54
|
check_msgmnb
|
55
55
|
cleanup_queues
|
56
56
|
|
57
|
-
parser =
|
57
|
+
parser = Optimist::Parser.new do
|
58
58
|
version <<-EOS
|
59
59
|
rbtrace: like strace, but for ruby code
|
60
60
|
version #{RBTracer::VERSION}
|
@@ -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,10 +215,20 @@ 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
|
-
opts =
|
215
|
-
raise
|
230
|
+
opts = Optimist.with_standard_exception_handling(parser) do
|
231
|
+
raise Optimist::HelpNeeded if ARGV.empty?
|
216
232
|
parser.stop_on '--exec'
|
217
233
|
parser.parse(ARGV)
|
218
234
|
end
|
@@ -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
|
@@ -257,7 +273,7 @@ EOS
|
|
257
273
|
file = [
|
258
274
|
config,
|
259
275
|
File.expand_path("../../../tracers/#{config}.tracer", __FILE__)
|
260
|
-
].find{ |f| File.
|
276
|
+
].find{ |f| File.exist?(f) }
|
261
277
|
|
262
278
|
unless file
|
263
279
|
parser.die :config, '(file does not exist)'
|
@@ -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/rbtracer.rb
CHANGED
@@ -96,7 +96,7 @@ class RBTracer
|
|
96
96
|
end
|
97
97
|
|
98
98
|
def clean_socket_path
|
99
|
-
FileUtils.rm(socket_path) if File.
|
99
|
+
FileUtils.rm(socket_path) if File.exist?(socket_path)
|
100
100
|
end
|
101
101
|
|
102
102
|
# Watch for method calls slower than a threshold.
|
@@ -321,7 +321,9 @@ class RBTracer
|
|
321
321
|
def send_cmd(*cmd)
|
322
322
|
begin
|
323
323
|
msg = cmd.to_msgpack
|
324
|
-
|
324
|
+
# A message is null-terminated, but bytesize gives the unterminated
|
325
|
+
# length.
|
326
|
+
raise ArgumentError, 'command is too long' if msg.bytesize >= MsgQ::EventMsg::BUF_SIZE
|
325
327
|
MsgQ::EventMsg.send_cmd(@qo, msg)
|
326
328
|
rescue Errno::EINTR
|
327
329
|
retry
|
@@ -575,6 +577,10 @@ class RBTracer
|
|
575
577
|
puts if @watch_slow
|
576
578
|
end
|
577
579
|
|
580
|
+
when 'write'
|
581
|
+
data, = *cmd
|
582
|
+
STDOUT.write(data)
|
583
|
+
|
578
584
|
else
|
579
585
|
puts "unknown event #{event}: #{cmd.inspect}"
|
580
586
|
|
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,15 +10,20 @@ 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
|
|
17
|
-
|
18
|
-
s.add_dependency '
|
19
|
-
s.add_dependency '
|
21
|
+
|
22
|
+
s.add_dependency 'ffi', '>= 1.0.6'
|
23
|
+
s.add_dependency 'optimist', '>= 3.0.0'
|
24
|
+
s.add_dependency 'msgpack', '>= 0.4.3'
|
25
|
+
|
26
|
+
s.add_development_dependency "rake", "~> 10.0"
|
20
27
|
|
21
28
|
s.license = "MIT"
|
22
29
|
s.summary = 'rbtrace: like strace but for ruby code'
|
data/server.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'ext/rbtrace'
|
2
|
+
require 'tmpdir'
|
2
3
|
|
3
4
|
class String
|
4
5
|
def multiply_vowels(num)
|
@@ -26,19 +27,21 @@ end
|
|
26
27
|
|
27
28
|
while true
|
28
29
|
proc {
|
29
|
-
Dir.
|
30
|
-
Dir.
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
Dir.mktmpdir do |tmp|
|
31
|
+
Dir.chdir(tmp) do
|
32
|
+
Dir.pwd
|
33
|
+
Process.pid
|
34
|
+
'hello'.multiply_vowels(3){ :ohai }
|
35
|
+
sleep rand*0.5
|
34
36
|
|
35
|
-
|
36
|
-
|
37
|
+
ENV['blah']
|
38
|
+
GC.start
|
37
39
|
|
38
|
-
|
39
|
-
|
40
|
+
reload_test.call
|
41
|
+
Test.run
|
40
42
|
|
41
|
-
|
43
|
+
#fib(1024*100)
|
44
|
+
end
|
42
45
|
end
|
43
46
|
}.call
|
44
47
|
end
|
data/tracers/activerecord.tracer
CHANGED
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.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aman Gupta
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-08-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -25,19 +25,19 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 1.0.6
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: optimist
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 3.0.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 3.0.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: msgpack
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -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
|
@@ -63,9 +77,9 @@ extra_rdoc_files: []
|
|
63
77
|
files:
|
64
78
|
- ".gitignore"
|
65
79
|
- Gemfile
|
66
|
-
- Gemfile.lock
|
67
80
|
- LICENSE
|
68
81
|
- README.md
|
82
|
+
- Rakefile
|
69
83
|
- bin/rbtrace
|
70
84
|
- ext/.gitignore
|
71
85
|
- ext/extconf.rb
|
@@ -75,6 +89,7 @@ files:
|
|
75
89
|
- lib/rbtrace/core_ext.rb
|
76
90
|
- lib/rbtrace/interactive/irb.rb
|
77
91
|
- lib/rbtrace/interactive/rib.rb
|
92
|
+
- lib/rbtrace/memory_report.rb
|
78
93
|
- lib/rbtrace/msgq.rb
|
79
94
|
- lib/rbtrace/rbtracer.rb
|
80
95
|
- lib/rbtrace/version.rb
|
@@ -92,10 +107,11 @@ homepage: http://github.com/tmm1/rbtrace
|
|
92
107
|
licenses:
|
93
108
|
- MIT
|
94
109
|
metadata: {}
|
95
|
-
post_install_message:
|
110
|
+
post_install_message:
|
96
111
|
rdoc_options: []
|
97
112
|
require_paths:
|
98
113
|
- lib
|
114
|
+
- ext
|
99
115
|
required_ruby_version: !ruby/object:Gem::Requirement
|
100
116
|
requirements:
|
101
117
|
- - ">="
|
@@ -107,9 +123,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
107
123
|
- !ruby/object:Gem::Version
|
108
124
|
version: '0'
|
109
125
|
requirements: []
|
110
|
-
|
111
|
-
|
112
|
-
signing_key:
|
126
|
+
rubygems_version: 3.0.3
|
127
|
+
signing_key:
|
113
128
|
specification_version: 4
|
114
129
|
summary: 'rbtrace: like strace but for ruby code'
|
115
130
|
test_files: []
|
data/Gemfile.lock
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
rbtrace (0.4.7)
|
5
|
-
ffi (>= 1.0.6)
|
6
|
-
msgpack (>= 0.4.3)
|
7
|
-
trollop (>= 1.16.2)
|
8
|
-
|
9
|
-
GEM
|
10
|
-
remote: https://rubygems.org/
|
11
|
-
specs:
|
12
|
-
ffi (1.9.8)
|
13
|
-
msgpack (0.6.0)
|
14
|
-
trollop (2.1.2)
|
15
|
-
|
16
|
-
PLATFORMS
|
17
|
-
ruby
|
18
|
-
|
19
|
-
DEPENDENCIES
|
20
|
-
rbtrace!
|