rbtrace 0.3.5 → 0.3.6
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.
- data/Gemfile.lock +1 -1
- data/README.md +7 -7
- data/bin/rbtrace +105 -41
- data/ext/extconf.rb +2 -0
- data/ext/rbtrace.c +157 -94
- data/rbtrace.gemspec +1 -1
- metadata +4 -4
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -15,7 +15,7 @@ in production.
|
|
15
15
|
|
16
16
|
## tracer types
|
17
17
|
|
18
|
-
rbtrace has several different tracing modes
|
18
|
+
rbtrace has several different tracing modes.
|
19
19
|
|
20
20
|
### firehose: show everything
|
21
21
|
|
@@ -33,6 +33,12 @@ rbtrace has several different tracing modes:
|
|
33
33
|
|
34
34
|
% rbtrace -p <PID> --gc
|
35
35
|
|
36
|
+
### notes
|
37
|
+
|
38
|
+
`--firehose` is not reliable on osx.
|
39
|
+
|
40
|
+
`--slow`, `--gc` and `--methods` can be combined.
|
41
|
+
|
36
42
|
## predefined tracers
|
37
43
|
|
38
44
|
rbtrace also includes a set of [predefined tracers](https://github.com/tmm1/rbtrace/tree/master/tracers)
|
@@ -186,12 +192,6 @@ for popular ruby libraries and functions.
|
|
186
192
|
|
187
193
|
## todo
|
188
194
|
|
189
|
-
* write some real tests (that assert things)
|
190
|
-
* more expressive selectors (.*Controller#)
|
191
|
-
* include date in show time (-t)
|
192
|
-
* add --eval
|
193
|
-
* add --forkgdb
|
194
|
-
* add --strace mode/expression
|
195
195
|
* add triggers to start tracing slow methods only inside another method
|
196
196
|
* add watch expressions to fire tracers only when an expression is true
|
197
197
|
* add special expressions for method args (_arg0_, _arguments_)
|
data/bin/rbtrace
CHANGED
@@ -142,7 +142,7 @@ class RBTracer
|
|
142
142
|
raise ArgumentError, 'could not signal process, are you running as root?'
|
143
143
|
end
|
144
144
|
|
145
|
-
|
145
|
+
signal
|
146
146
|
sleep 0.25 # wait for process to create msgqs
|
147
147
|
|
148
148
|
@qi = MsgQ.msgget( pid, 0666)
|
@@ -169,6 +169,7 @@ class RBTracer
|
|
169
169
|
|
170
170
|
@out = STDOUT
|
171
171
|
@prefix = ' '
|
172
|
+
@printed_newline = true
|
172
173
|
|
173
174
|
@show_time = false
|
174
175
|
@show_duration = true
|
@@ -201,6 +202,35 @@ class RBTracer
|
|
201
202
|
send_cmd(:devmode)
|
202
203
|
end
|
203
204
|
|
205
|
+
# Fork the process and return the copy's pid.
|
206
|
+
#
|
207
|
+
# Returns a Fixnum pid.
|
208
|
+
def fork
|
209
|
+
send_cmd(:fork)
|
210
|
+
if wait_for(30, 'for fork'){ !!@forked_pid }
|
211
|
+
@forked_pid
|
212
|
+
else
|
213
|
+
STDERR.puts '*** timed out waiting for fork'
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
# Evaluate some ruby code.
|
218
|
+
#
|
219
|
+
# Returns the String result.
|
220
|
+
def eval(code)
|
221
|
+
if (err = valid_syntax?(code)) != true
|
222
|
+
raise ArgumentError, "#{err.class} for expression #{code.inspect}"
|
223
|
+
end
|
224
|
+
|
225
|
+
send_cmd(:eval, code)
|
226
|
+
|
227
|
+
if wait_for(10, 'for eval response'){ !!@eval_result }
|
228
|
+
@eval_result
|
229
|
+
else
|
230
|
+
STDERR.puts '*** timed out waiting for eval response'
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
204
234
|
# Turn on GC tracing.
|
205
235
|
#
|
206
236
|
# Returns nothing.
|
@@ -257,17 +287,17 @@ class RBTracer
|
|
257
287
|
rescue Errno::ESRCH
|
258
288
|
end
|
259
289
|
|
260
|
-
|
290
|
+
newline
|
261
291
|
|
262
292
|
if wait_for{ @attached == false }
|
263
|
-
|
293
|
+
newline
|
264
294
|
STDERR.puts "*** detached from process #{pid}"
|
265
295
|
else
|
266
|
-
|
296
|
+
newline
|
267
297
|
STDERR.puts "*** could not detach cleanly from process #{pid}"
|
268
298
|
end
|
269
299
|
rescue Errno::EINVAL, Errno::EIDRM
|
270
|
-
|
300
|
+
newline
|
271
301
|
STDERR.puts "*** process #{pid} is gone"
|
272
302
|
STDERR.puts "*** #{$!.inspect}"
|
273
303
|
STDERR.puts $!.backtrace.join("\n ")
|
@@ -302,15 +332,24 @@ class RBTracer
|
|
302
332
|
end
|
303
333
|
end
|
304
334
|
|
335
|
+
def puts(arg=nil)
|
336
|
+
@printed_newline = true
|
337
|
+
arg ? @out.puts(arg) : @out.puts
|
338
|
+
end
|
339
|
+
|
305
340
|
private
|
306
341
|
|
342
|
+
def signal
|
343
|
+
Process.kill 'URG', @pid
|
344
|
+
end
|
345
|
+
|
307
346
|
# Process incoming events until either a timeout or a condition becomes true.
|
308
347
|
#
|
309
348
|
# time - The Fixnum timeout in seconds.
|
310
349
|
# block - The Block that is checked every 50ms until it returns true.
|
311
350
|
#
|
312
351
|
# Returns true when the condition was met, or false on a timeout.
|
313
|
-
def wait_for(time=5)
|
352
|
+
def wait_for(time=5, reason='to detach cleanly')
|
314
353
|
wait = 0.05 # polling interval
|
315
354
|
|
316
355
|
(time/wait).to_i.times do
|
@@ -321,7 +360,7 @@ class RBTracer
|
|
321
360
|
|
322
361
|
return true if yield
|
323
362
|
rescue Interrupt
|
324
|
-
STDERR.puts "*** waiting
|
363
|
+
STDERR.puts "*** waiting #{reason} (#{time.to_i}s left)"
|
325
364
|
retry
|
326
365
|
end
|
327
366
|
end
|
@@ -337,7 +376,7 @@ class RBTracer
|
|
337
376
|
rescue Errno::EINTR
|
338
377
|
retry
|
339
378
|
end
|
340
|
-
|
379
|
+
signal
|
341
380
|
recv_lines
|
342
381
|
end
|
343
382
|
|
@@ -351,18 +390,20 @@ class RBTracer
|
|
351
390
|
|
352
391
|
def valid_syntax?(code)
|
353
392
|
begin
|
354
|
-
eval("#{code}\nBEGIN {return true}", nil, 'rbtrace_expression', 0)
|
393
|
+
Kernel.eval("#{code}\nBEGIN {return true}", nil, 'rbtrace_expression', 0)
|
355
394
|
rescue Exception => e
|
356
395
|
e
|
357
396
|
end
|
358
397
|
end
|
359
398
|
|
360
|
-
def print(
|
361
|
-
@
|
399
|
+
def print(arg)
|
400
|
+
@printed_newline = false
|
401
|
+
@out.print(arg)
|
362
402
|
end
|
363
403
|
|
364
|
-
def
|
365
|
-
@
|
404
|
+
def newline
|
405
|
+
puts unless @printed_newline
|
406
|
+
@printed_newline = true
|
366
407
|
end
|
367
408
|
|
368
409
|
def parse_cmd(line)
|
@@ -379,6 +420,11 @@ class RBTracer
|
|
379
420
|
event = cmd.shift
|
380
421
|
|
381
422
|
case event
|
423
|
+
when 'during_gc'
|
424
|
+
sleep 0.01
|
425
|
+
signal
|
426
|
+
return
|
427
|
+
|
382
428
|
when 'attached'
|
383
429
|
tracer_pid, = *cmd
|
384
430
|
if tracer_pid != Process.pid
|
@@ -406,6 +452,14 @@ class RBTracer
|
|
406
452
|
end
|
407
453
|
|
408
454
|
case event
|
455
|
+
when 'forked'
|
456
|
+
pid, = *cmd
|
457
|
+
@forked_pid = pid
|
458
|
+
|
459
|
+
when 'evaled'
|
460
|
+
res, = *cmd
|
461
|
+
@eval_result = res
|
462
|
+
|
409
463
|
when 'mid'
|
410
464
|
mid, name = *cmd
|
411
465
|
@methods[mid] = name
|
@@ -562,7 +616,7 @@ class RBTracer
|
|
562
616
|
parser = Trollop::Parser.new do
|
563
617
|
version <<-EOS
|
564
618
|
rbtrace: like strace, but for ruby code
|
565
|
-
version 0.3.
|
619
|
+
version 0.3.6
|
566
620
|
(c) 2011 Aman Gupta (tmm1)
|
567
621
|
http://github.com/tmm1/rbtrace
|
568
622
|
EOS
|
@@ -665,6 +719,14 @@ EOS
|
|
665
719
|
|
666
720
|
opt :devmode,
|
667
721
|
"assume the ruby process is reloading classes and methods"
|
722
|
+
|
723
|
+
opt :fork,
|
724
|
+
"fork a copy of the process for debugging (so you can attach gdb.rb)"
|
725
|
+
|
726
|
+
opt :eval,
|
727
|
+
"evaluate a ruby expression in the process",
|
728
|
+
:type => String,
|
729
|
+
:short => '-e'
|
668
730
|
end
|
669
731
|
|
670
732
|
opts = Trollop.with_standard_exception_handling(parser) do
|
@@ -672,12 +734,16 @@ EOS
|
|
672
734
|
parser.parse(ARGV)
|
673
735
|
end
|
674
736
|
|
675
|
-
unless %w[ slow firehose methods config gc ].find{ |n| opts[:"#{n}_given"] }
|
737
|
+
unless %w[ fork eval slow firehose methods config gc ].find{ |n| opts[:"#{n}_given"] }
|
676
738
|
$stderr.puts "Error: --slow, --gc, --firehose, --methods or --config required."
|
677
739
|
$stderr.puts "Try --help for help."
|
678
740
|
exit(-1)
|
679
741
|
end
|
680
742
|
|
743
|
+
if opts[:fork_given] and opts[:pid].size != 1
|
744
|
+
parser.die :fork, '(can only be invoked with one pid)'
|
745
|
+
end
|
746
|
+
|
681
747
|
methods = []
|
682
748
|
|
683
749
|
if opts[:methods_given]
|
@@ -764,37 +830,35 @@ EOS
|
|
764
830
|
parser.die :pid, "(#{e.message})"
|
765
831
|
end
|
766
832
|
|
767
|
-
if opts[:
|
768
|
-
tracer.
|
769
|
-
|
770
|
-
|
771
|
-
if opts[:gc_given]
|
772
|
-
tracer.gc
|
773
|
-
end
|
774
|
-
|
775
|
-
if opts[:firehose_given]
|
776
|
-
tracer.firehose
|
777
|
-
else
|
778
|
-
if methods.any?
|
779
|
-
tracer.add(methods)
|
780
|
-
end
|
833
|
+
if opts[:fork_given]
|
834
|
+
pid = tracer.fork
|
835
|
+
STDERR.puts "*** forked off a busy looping copy at #{pid} (make sure to kill -9 it when you're done)"
|
781
836
|
|
782
|
-
|
783
|
-
|
837
|
+
elsif opts[:eval_given]
|
838
|
+
if res = tracer.eval(code = opts[:eval])
|
839
|
+
tracer.puts ">> #{code}"
|
840
|
+
tracer.puts "=> #{res}"
|
784
841
|
end
|
785
|
-
end
|
786
842
|
|
787
|
-
|
788
|
-
tracer.out = output
|
789
|
-
|
843
|
+
else
|
844
|
+
tracer.out = output if output
|
845
|
+
tracer.prefix = ' ' * opts[:prefix]
|
846
|
+
tracer.show_time = opts[:start_time]
|
847
|
+
tracer.show_duration = !opts[:no_duration]
|
790
848
|
|
791
|
-
|
792
|
-
|
793
|
-
tracer.show_time = opts[:start_time]
|
849
|
+
tracer.devmode if opts[:devmode_given]
|
850
|
+
tracer.gc if opts[:gc_given]
|
794
851
|
|
795
|
-
|
796
|
-
|
797
|
-
|
852
|
+
if opts[:firehose_given]
|
853
|
+
tracer.firehose
|
854
|
+
else
|
855
|
+
tracer.add(methods) if methods.any?
|
856
|
+
tracer.watch(opts[:slow]) if opts[:slow_given]
|
857
|
+
end
|
858
|
+
begin
|
859
|
+
tracer.recv_loop
|
860
|
+
rescue Interrupt, SignalException
|
861
|
+
end
|
798
862
|
end
|
799
863
|
ensure
|
800
864
|
if tracer
|
data/ext/extconf.rb
CHANGED
data/ext/rbtrace.c
CHANGED
@@ -21,7 +21,6 @@
|
|
21
21
|
|
22
22
|
#ifndef RUBY_VM
|
23
23
|
#include <env.h>
|
24
|
-
#include <intern.h>
|
25
24
|
#include <node.h>
|
26
25
|
#include <st.h>
|
27
26
|
#define rb_sourcefile() (ruby_current_node ? ruby_current_node->nd_file : 0)
|
@@ -264,8 +263,10 @@ rbtrace__send_names(ID mid, VALUE klass)
|
|
264
263
|
if (!rbtracer.klass_tbl)
|
265
264
|
rbtracer.klass_tbl = st_init_numtable();
|
266
265
|
|
267
|
-
if (!st_is_member(rbtracer.klass_tbl, klass)) {
|
268
|
-
|
266
|
+
if (rbtracer.devmode || !st_is_member(rbtracer.klass_tbl, klass)) {
|
267
|
+
if (!rbtracer.devmode)
|
268
|
+
st_insert(rbtracer.klass_tbl, (st_data_t)klass, (st_data_t)1);
|
269
|
+
|
269
270
|
rbtrace__send_event(2,
|
270
271
|
"klass",
|
271
272
|
'l', klass,
|
@@ -715,26 +716,17 @@ rbtracer_watch(uint32_t threshold)
|
|
715
716
|
}
|
716
717
|
}
|
717
718
|
|
718
|
-
static void
|
719
|
-
rbtracer_unwatch()
|
720
|
-
{
|
721
|
-
if (rbtracer.slow) {
|
722
|
-
event_hook_remove();
|
723
|
-
|
724
|
-
rbtracer.firehose = false;
|
725
|
-
rbtracer.slow = false;
|
726
|
-
}
|
727
|
-
}
|
728
|
-
|
729
719
|
static void
|
730
720
|
msgq_teardown()
|
731
721
|
{
|
732
|
-
|
722
|
+
pid_t pid = getpid();
|
723
|
+
|
724
|
+
if (rbtracer.mqo_id != -1 && rbtracer.mqo_key == (key_t)pid) {
|
733
725
|
msgctl(rbtracer.mqo_id, IPC_RMID, NULL);
|
734
726
|
rbtracer.mqo_id = -1;
|
735
727
|
rbtracer.mqo_key = 0;
|
736
728
|
}
|
737
|
-
if (rbtracer.mqi_id != -1) {
|
729
|
+
if (rbtracer.mqi_id != -1 && rbtracer.mqi_key == (key_t)-pid) {
|
738
730
|
msgctl(rbtracer.mqi_id, IPC_RMID, NULL);
|
739
731
|
rbtracer.mqi_id = -1;
|
740
732
|
rbtracer.mqi_key = 0;
|
@@ -774,117 +766,188 @@ msgq_setup()
|
|
774
766
|
}
|
775
767
|
|
776
768
|
static void
|
777
|
-
|
769
|
+
rbtrace__process_event(msgpack_object cmd)
|
778
770
|
{
|
771
|
+
if (cmd.type != MSGPACK_OBJECT_ARRAY)
|
772
|
+
return;
|
773
|
+
|
779
774
|
static int last_tracer_id = -1; // hax
|
780
|
-
|
781
|
-
if (rbtracer.mqi_id == -1) return;
|
775
|
+
char query[BUF_SIZE];
|
782
776
|
|
783
|
-
|
784
|
-
|
777
|
+
char code[BUF_SIZE+150];
|
778
|
+
VALUE val = Qnil;
|
785
779
|
|
786
|
-
|
787
|
-
|
780
|
+
msgpack_object_array ary;
|
781
|
+
msgpack_object_raw str;
|
788
782
|
|
789
|
-
|
790
|
-
|
783
|
+
/* fprintf(stderr, "GOT: ");*/
|
784
|
+
/* msgpack_object_print(stderr, cmd);*/
|
785
|
+
/* fprintf(stderr, "\n");*/
|
791
786
|
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
787
|
+
ary = cmd.via.array;
|
788
|
+
|
789
|
+
if (ary.size < 1 ||
|
790
|
+
ary.ptr[0].type != MSGPACK_OBJECT_RAW)
|
791
|
+
return;
|
796
792
|
|
797
|
-
|
798
|
-
msgpack_object_array ary;
|
799
|
-
msgpack_object_raw str;
|
793
|
+
str = ary.ptr[0].via.raw;
|
800
794
|
|
801
|
-
|
802
|
-
|
795
|
+
if (0 == strncmp("attach", str.ptr, str.size)) {
|
796
|
+
if (ary.size != 2 ||
|
797
|
+
ary.ptr[1].type != MSGPACK_OBJECT_POSITIVE_INTEGER)
|
798
|
+
return;
|
803
799
|
|
804
|
-
|
805
|
-
|
800
|
+
pid_t pid = (pid_t) ary.ptr[1].via.u64;
|
801
|
+
|
802
|
+
if (pid && rbtracer.attached_pid == 0)
|
803
|
+
rbtracer.attached_pid = pid;
|
806
804
|
|
807
|
-
|
808
|
-
|
805
|
+
rbtrace__send_event(1,
|
806
|
+
"attached",
|
807
|
+
'u', (uint32_t) rbtracer.attached_pid
|
808
|
+
);
|
809
|
+
|
810
|
+
} else if (0 == strncmp("detach", str.ptr, str.size)) {
|
811
|
+
if (rbtracer.attached_pid) {
|
812
|
+
rbtrace__send_event(1,
|
813
|
+
"detached",
|
814
|
+
'u', (uint32_t) rbtracer.attached_pid
|
815
|
+
);
|
816
|
+
}
|
809
817
|
|
810
|
-
|
811
|
-
/* msgpack_object_print(stderr, cmd);*/
|
812
|
-
/* fprintf(stderr, "\n");*/
|
818
|
+
rbtracer_detach();
|
813
819
|
|
814
|
-
|
820
|
+
} else if (0 == strncmp("watch", str.ptr, str.size)) {
|
821
|
+
if (ary.size != 2 ||
|
822
|
+
ary.ptr[1].type != MSGPACK_OBJECT_POSITIVE_INTEGER)
|
823
|
+
return;
|
815
824
|
|
816
|
-
|
817
|
-
|
818
|
-
continue;
|
825
|
+
unsigned int msec = ary.ptr[1].via.u64;
|
826
|
+
rbtracer_watch(msec);
|
819
827
|
|
820
|
-
|
828
|
+
} else if (0 == strncmp("firehose", str.ptr, str.size)) {
|
829
|
+
rbtracer.firehose = true;
|
830
|
+
event_hook_install();
|
821
831
|
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
832
|
+
} else if (0 == strncmp("add", str.ptr, str.size)) {
|
833
|
+
if (ary.size != 2 ||
|
834
|
+
ary.ptr[1].type != MSGPACK_OBJECT_RAW)
|
835
|
+
return;
|
826
836
|
|
827
|
-
|
837
|
+
str = ary.ptr[1].via.raw;
|
828
838
|
|
829
|
-
|
830
|
-
|
839
|
+
strncpy(query, str.ptr, str.size);
|
840
|
+
query[str.size] = 0;
|
841
|
+
last_tracer_id = rbtracer_add(query);
|
831
842
|
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
843
|
+
} else if (0 == strncmp("addexpr", str.ptr, str.size)) {
|
844
|
+
if (ary.size != 2 ||
|
845
|
+
ary.ptr[1].type != MSGPACK_OBJECT_RAW)
|
846
|
+
return;
|
836
847
|
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
848
|
+
str = ary.ptr[1].via.raw;
|
849
|
+
|
850
|
+
strncpy(query, str.ptr, str.size);
|
851
|
+
query[str.size] = 0;
|
852
|
+
rbtracer_add_expr(last_tracer_id, query);
|
853
|
+
|
854
|
+
} else if (0 == strncmp("gc", str.ptr, str.size)) {
|
855
|
+
rbtracer.gc = true;
|
856
|
+
|
857
|
+
} else if (0 == strncmp("devmode", str.ptr, str.size)) {
|
858
|
+
rbtracer.devmode = true;
|
859
|
+
|
860
|
+
} else if (0 == strncmp("fork", str.ptr, str.size)) {
|
861
|
+
pid_t outer = fork();
|
862
|
+
|
863
|
+
if (outer == 0) {
|
864
|
+
rb_eval_string_protect("$0 = \"[DEBUG] #{Process.ppid}\"", 0);
|
865
|
+
setpgrp();
|
866
|
+
pid_t inner = fork();
|
867
|
+
|
868
|
+
if (inner == 0) {
|
869
|
+
// a ruby process will never have more than 20k
|
870
|
+
// open file descriptors, right?
|
871
|
+
int fd;
|
872
|
+
for (fd=3; fd<20000; fd++)
|
873
|
+
close(fd);
|
874
|
+
|
875
|
+
// busy loop
|
876
|
+
while (1) sleep(1);
|
877
|
+
|
878
|
+
// don't return to ruby
|
879
|
+
_exit(0);
|
880
|
+
}
|
881
|
+
|
882
|
+
rbtrace__send_event(1,
|
883
|
+
"forked",
|
884
|
+
inner == -1 ? 'b' : 'u',
|
885
|
+
inner == -1 ? false : (uint32_t) inner
|
842
886
|
);
|
843
|
-
}
|
844
887
|
|
845
|
-
|
888
|
+
// kill off outer fork
|
889
|
+
_exit(0);
|
890
|
+
}
|
846
891
|
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
continue;
|
892
|
+
if (outer != -1) {
|
893
|
+
waitpid(outer, NULL, 0);
|
894
|
+
}
|
851
895
|
|
852
|
-
|
853
|
-
|
896
|
+
} else if (0 == strncmp("eval", str.ptr, str.size)) {
|
897
|
+
if (ary.size != 2 ||
|
898
|
+
ary.ptr[1].type != MSGPACK_OBJECT_RAW)
|
899
|
+
return;
|
854
900
|
|
855
|
-
|
856
|
-
rbtracer.firehose = true;
|
857
|
-
event_hook_install();
|
901
|
+
str = ary.ptr[1].via.raw;
|
858
902
|
|
859
|
-
|
860
|
-
|
861
|
-
ary.ptr[1].type != MSGPACK_OBJECT_RAW)
|
862
|
-
continue;
|
903
|
+
strncpy(query, str.ptr, str.size);
|
904
|
+
query[str.size] = 0;
|
863
905
|
|
864
|
-
|
906
|
+
snprintf(code, BUF_SIZE+150, "(begin; %s; rescue Exception => e; e; end).inspect", query);
|
907
|
+
val = rb_eval_string_protect(code, 0);
|
865
908
|
|
866
|
-
|
867
|
-
|
868
|
-
|
909
|
+
if (TYPE(val) == T_STRING) {
|
910
|
+
rbtrace__send_event(1,
|
911
|
+
"evaled",
|
912
|
+
's', RSTRING_PTR(val)
|
913
|
+
);
|
914
|
+
}
|
869
915
|
|
870
|
-
|
871
|
-
|
872
|
-
ary.ptr[1].type != MSGPACK_OBJECT_RAW)
|
873
|
-
continue;
|
916
|
+
}
|
917
|
+
}
|
874
918
|
|
875
|
-
|
919
|
+
static void
|
920
|
+
sigurg(int signal)
|
921
|
+
{
|
922
|
+
msgq_setup();
|
923
|
+
if (rbtracer.mqi_id == -1) return;
|
876
924
|
|
877
|
-
|
878
|
-
|
879
|
-
|
925
|
+
#ifdef HAVE_RB_DURING_GC
|
926
|
+
if (rb_during_gc()) {
|
927
|
+
rbtrace__send_event(0, "during_gc");
|
928
|
+
return;
|
929
|
+
}
|
930
|
+
#endif
|
880
931
|
|
881
|
-
|
882
|
-
|
932
|
+
event_msg_t msg;
|
933
|
+
int n = 0;
|
883
934
|
|
884
|
-
|
885
|
-
|
935
|
+
while (true) {
|
936
|
+
int ret = -1;
|
886
937
|
|
887
|
-
|
938
|
+
for (n=0; n<10 && ret==-1; n++)
|
939
|
+
ret = msgrcv(rbtracer.mqi_id, &msg, sizeof(msg)-sizeof(long), 0, IPC_NOWAIT);
|
940
|
+
|
941
|
+
if (ret == -1) {
|
942
|
+
break;
|
943
|
+
} else {
|
944
|
+
msgpack_unpacked unpacked;
|
945
|
+
msgpack_unpacked_init(&unpacked);
|
946
|
+
|
947
|
+
bool success = msgpack_unpack_next(&unpacked, msg.buf, sizeof(msg.buf), NULL);
|
948
|
+
if (!success) continue;
|
949
|
+
|
950
|
+
rbtrace__process_event(unpacked.data);
|
888
951
|
}
|
889
952
|
}
|
890
953
|
}
|
data/rbtrace.gemspec
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbtrace
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 31
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 0.3.
|
9
|
+
- 6
|
10
|
+
version: 0.3.6
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Aman Gupta
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-02-
|
18
|
+
date: 2011-02-22 00:00:00 -08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|