rbtrace 0.4.9 → 0.4.14
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 +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!
|