rbtrace 0.3.3 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rbtrace (0.3.3)
4
+ rbtrace (0.3.4)
5
5
  ffi (>= 1.0.5)
6
6
  msgpack (>= 0.4.3)
7
7
  trollop (>= 1.16.2)
data/README.md CHANGED
@@ -29,6 +29,10 @@ rbtrace has several different tracing modes:
29
29
 
30
30
  % rbtrace -p <PID> --methods "Kernel#sleep" "Proc#call"
31
31
 
32
+ ### gc: trace garbage collections
33
+
34
+ % rbtrace -p <PID> --gc
35
+
32
36
  ## predefined tracers
33
37
 
34
38
  rbtrace also includes a set of [predefined tracers](https://github.com/tmm1/rbtrace/tree/master/tracers)
@@ -182,7 +186,9 @@ for popular ruby libraries and functions.
182
186
 
183
187
  ## todo
184
188
 
189
+ * allow slow tracing of specific methods (--slow + --methods)
185
190
  * add triggers to start tracing slow methods only inside another method
191
+ * add watch expressions to fire tracers only when an expression is true
186
192
  * syntax check expressions before adding them
187
193
  * add special expressions for method args (_arg0_, _arguments_)
188
194
  * optimize local variable lookup to avoid instance_eval
data/bin/rbtrace CHANGED
@@ -22,7 +22,7 @@ module MsgQ
22
22
  ffi_lib 'c'
23
23
 
24
24
  class EventMsg < FFI::Struct
25
- BUF_SIZE = RUBY_PLATFORM =~ /linux/ ? 256 : 64
25
+ BUF_SIZE = RUBY_PLATFORM =~ /linux/ ? 256 : 120
26
26
  IPC_NOWAIT = 004000
27
27
 
28
28
  layout :mtype, :long,
@@ -159,7 +159,7 @@ class RBTracer
159
159
  :arglist => false
160
160
  }
161
161
  }
162
- @max_nesting = @nesting = 0
162
+ @max_nesting = @last_nesting = @nesting = 0
163
163
  @last_tracer = nil
164
164
 
165
165
  @out = STDOUT
@@ -167,6 +167,7 @@ class RBTracer
167
167
 
168
168
  @show_time = false
169
169
  @show_duration = true
170
+ @watch_slow = false
170
171
 
171
172
  attach
172
173
  end
@@ -177,6 +178,7 @@ class RBTracer
177
178
  #
178
179
  # Returns nothing.
179
180
  def watch(msec)
181
+ @watch_slow = true
180
182
  send_cmd(:watch, msec)
181
183
  end
182
184
 
@@ -187,6 +189,13 @@ class RBTracer
187
189
  send_cmd(:firehose)
188
190
  end
189
191
 
192
+ # Turn on GC tracing.
193
+ #
194
+ # Returns nothing.
195
+ def gc
196
+ send_cmd(:gc)
197
+ end
198
+
190
199
  # Add tracers for the given list of methods.
191
200
  #
192
201
  # methods - The String or Array of method selectors to trace.
@@ -342,9 +351,9 @@ class RBTracer
342
351
 
343
352
  case event
344
353
  when 'attached'
345
- tracer_pid = *cmd
354
+ tracer_pid, = *cmd
346
355
  if tracer_pid != Process.pid
347
- STDERR.puts "*** process #{pid} is already being traced"
356
+ STDERR.puts "*** process #{pid} is already being traced (#{tracer_pid} != #{Process.pid})"
348
357
  exit!(-1)
349
358
  end
350
359
 
@@ -352,7 +361,7 @@ class RBTracer
352
361
  return
353
362
 
354
363
  when 'detached'
355
- tracer_pid = *cmd
364
+ tracer_pid, = *cmd
356
365
  if tracer_pid != Process.pid
357
366
  STDERR.puts "*** process #{pid} detached #{tracer_pid}, but we are #{Process.pid}"
358
367
  else
@@ -435,6 +444,7 @@ class RBTracer
435
444
 
436
445
  @nesting += 1
437
446
  @max_nesting = @nesting if @nesting > @max_nesting
447
+ @last_nesting = @nesting
438
448
  @last_tracer = tracer
439
449
  tracer[:last] = name
440
450
 
@@ -467,14 +477,21 @@ class RBTracer
467
477
  end
468
478
 
469
479
  tracer[:arglist] = false
480
+ @last_nesting = @nesting
470
481
 
471
482
  when 'slow', 'cslow'
472
- diff, nesting, mid, is_singleton, klass = *cmd
483
+ time, diff, nesting, mid, is_singleton, klass = *cmd
473
484
 
474
485
  klass = @klasses[klass]
475
486
  name = klass ? "#{klass}#{ is_singleton ? '.' : '#' }" : ''
476
487
  name += @methods[mid] || '(unknown)'
477
488
 
489
+ if @show_time
490
+ t = Time.at(time/1_000_000)
491
+ print t.strftime("%H:%M:%S.")
492
+ print "%06d " % (time - t.to_f*1_000_000).round
493
+ end
494
+
478
495
  print @prefix*nesting if nesting > 0
479
496
  print name
480
497
  if @show_duration
@@ -484,8 +501,23 @@ class RBTracer
484
501
  puts
485
502
  puts if nesting == 0
486
503
 
504
+ @last_nesting = nesting
505
+
506
+ when 'gc'
507
+ time, = *cmd
508
+
509
+ puts unless @watch_slow
510
+ if @show_time
511
+ t = Time.at(time/1_000_000)
512
+ print t.strftime("%H:%M:%S.")
513
+ print "%06d " % (time - t.to_f*1_000_000).round
514
+ end
515
+ print @prefix*@last_nesting if @last_nesting > 0
516
+ print "garbage_collect"
517
+ puts if @watch_slow
518
+
487
519
  else
488
- puts "unknown event: #{line}"
520
+ puts "unknown event #{event}: #{cmd.inspect}"
489
521
 
490
522
  end
491
523
  rescue => e
@@ -500,7 +532,7 @@ class RBTracer
500
532
  parser = Trollop::Parser.new do
501
533
  version <<-EOS
502
534
  rbtrace: like strace, but for ruby code
503
- version 0.3.3
535
+ version 0.3.4
504
536
  (c) 2011 Aman Gupta (tmm1)
505
537
  http://github.com/tmm1/rbtrace
506
538
  EOS
@@ -525,6 +557,7 @@ Tracers:
525
557
  rbtrace --firehose # trace all method calls
526
558
  rbtrace --slow=250 # trace method calls slower than 250ms
527
559
  rbtrace --methods a b c # trace calls to given methods
560
+ rbtrace --gc # trace garbage collections
528
561
 
529
562
  rbtrace -c io # trace common input/output functions
530
563
  rbtrace -c eventmachine # trace common eventmachine functions
@@ -569,6 +602,9 @@ EOS
569
602
  :type => :strings,
570
603
  :short => '-m'
571
604
 
605
+ opt :gc,
606
+ "trace garbage collections"
607
+
572
608
  opt :start_time,
573
609
  "show start time for each method call",
574
610
  :short => '-t'
@@ -605,11 +641,17 @@ EOS
605
641
 
606
642
  if out = opts[:output]
607
643
  output = File.open(out, opts[:append] ? 'a+' : 'w')
644
+ output.sync = true
608
645
  end
609
646
 
610
647
  slow = nil
611
648
  firehose = nil
612
649
  methods = nil
650
+ gc = nil
651
+
652
+ if opts[:gc_given]
653
+ gc = true
654
+ end
613
655
 
614
656
  if opts[:slow_given]
615
657
  slow = opts[:slow]
@@ -642,8 +684,8 @@ EOS
642
684
  end
643
685
  end
644
686
 
645
- else
646
- $stderr.puts "Error: --slow, --firehose, --methods or --config required."
687
+ elsif !gc
688
+ $stderr.puts "Error: --slow, --gc, --firehose, --methods or --config required."
647
689
  $stderr.puts "Try --help for help."
648
690
  exit(-1)
649
691
  end
@@ -655,6 +697,10 @@ EOS
655
697
  parser.die :pid, "(#{e.message})"
656
698
  end
657
699
 
700
+ if gc
701
+ tracer.gc
702
+ end
703
+
658
704
  if slow
659
705
  tracer.watch(slow)
660
706
  elsif firehose
data/ext/extconf.rb CHANGED
@@ -11,18 +11,20 @@ end
11
11
  require 'mkmf'
12
12
  require 'fileutils'
13
13
 
14
- Logging.message "Building msgpack\n"
14
+ unless File.exists?("#{CWD}/dst/lib/libmsgpackc.a")
15
+ Logging.message "Building msgpack\n"
15
16
 
16
- msgpack = File.basename('msgpack-0.5.4.tar.gz')
17
- dir = File.basename(msgpack, '.tar.gz')
17
+ msgpack = File.basename('msgpack-0.5.4.tar.gz')
18
+ dir = File.basename(msgpack, '.tar.gz')
18
19
 
19
- Dir.chdir('src') do
20
- FileUtils.rm_rf(dir) if File.exists?(dir)
20
+ Dir.chdir('src') do
21
+ FileUtils.rm_rf(dir) if File.exists?(dir)
21
22
 
22
- sys("tar zxvf #{msgpack}")
23
- Dir.chdir(dir) do
24
- sys("./configure --disable-shared --with-pic --prefix=#{CWD}/dst/")
25
- sys("make install")
23
+ sys("tar zxvf #{msgpack}")
24
+ Dir.chdir(dir) do
25
+ sys("./configure --disable-shared --with-pic --prefix=#{CWD}/dst/")
26
+ sys("make install")
27
+ end
26
28
  end
27
29
  end
28
30
 
data/ext/rbtrace.c CHANGED
@@ -1,3 +1,4 @@
1
+ #include <assert.h>
1
2
  #include <inttypes.h>
2
3
  #include <errno.h>
3
4
  #include <signal.h>
@@ -51,7 +52,7 @@ timeofday_usec()
51
52
  #define MAX_TRACERS 100 // max method tracers
52
53
  #define MAX_EXPRS 10 // max expressions per tracer
53
54
  #ifndef BUF_SIZE // msgq buffer size
54
- #define BUF_SIZE 64
55
+ #define BUF_SIZE 120
55
56
  #endif
56
57
 
57
58
  typedef struct {
@@ -79,6 +80,7 @@ static struct {
79
80
 
80
81
  bool installed;
81
82
 
83
+ bool gc;
82
84
  bool firehose;
83
85
 
84
86
  bool slow;
@@ -105,6 +107,7 @@ rbtracer = {
105
107
 
106
108
  .installed = false,
107
109
 
110
+ .gc = false,
108
111
  .firehose = false,
109
112
 
110
113
  .slow = false,
@@ -124,7 +127,7 @@ rbtracer = {
124
127
  };
125
128
 
126
129
  static inline void
127
- SEND_EVENT(int nargs, char *name, ...)
130
+ rbtrace__send_event(int nargs, const char *name, ...)
128
131
  {
129
132
  if (!rbtracer.attached_pid ||
130
133
  !rbtracer.sbuf ||
@@ -144,8 +147,10 @@ SEND_EVENT(int nargs, char *name, ...)
144
147
 
145
148
  if (nargs > 0) {
146
149
  int type;
147
- uint32_t uint;
150
+
148
151
  int sint;
152
+ uint32_t uint;
153
+ uint64_t uint64;
149
154
  unsigned long ulong;
150
155
  char *str;
151
156
 
@@ -156,6 +161,11 @@ SEND_EVENT(int nargs, char *name, ...)
156
161
  type = va_arg(ap, int);
157
162
  switch (type) {
158
163
  case 't':
164
+ uint64 = va_arg(ap, uint64_t);
165
+ msgpack_pack_uint64(pk, uint64);
166
+ break;
167
+
168
+ case 'n':
159
169
  msgpack_pack_uint64(pk, timeofday_usec());
160
170
  break;
161
171
 
@@ -184,14 +194,14 @@ SEND_EVENT(int nargs, char *name, ...)
184
194
  case 's':
185
195
  str = va_arg(ap, char *);
186
196
  if (!str)
187
- str = "";
197
+ str = (char *)"";
188
198
 
189
199
  msgpack_pack_raw(pk, strlen(str));
190
200
  msgpack_pack_raw_body(pk, str, strlen(str));
191
201
  break;
192
202
 
193
203
  default:
194
- fprintf(stderr, "unknown type (%c) passed to SEND_EVENT\n", (char)type);
204
+ fprintf(stderr, "unknown type (%c) passed to rbtrace__send_event\n", (char)type);
195
205
  }
196
206
  }
197
207
 
@@ -202,7 +212,7 @@ SEND_EVENT(int nargs, char *name, ...)
202
212
  msg.mtype = 1;
203
213
 
204
214
  if (rbtracer.sbuf->size > sizeof(msg.buf)) {
205
- fprintf(stderr, "SEND_EVENT(): message is too large (%zd > %lu)\n", rbtracer.sbuf->size, sizeof(msg.buf));
215
+ fprintf(stderr, "rbtrace__send_event(): message is too large (%zd > %lu)\n", rbtracer.sbuf->size, sizeof(msg.buf));
206
216
  return;
207
217
  }
208
218
 
@@ -222,14 +232,14 @@ SEND_EVENT(int nargs, char *name, ...)
222
232
  }
223
233
 
224
234
  static inline void
225
- SEND_NAMES(ID mid, VALUE klass)
235
+ rbtrace__send_names(ID mid, VALUE klass)
226
236
  {
227
237
  if (!rbtracer.mid_tbl)
228
238
  rbtracer.mid_tbl = st_init_numtable();
229
239
 
230
240
  if (!st_is_member(rbtracer.mid_tbl, mid)) {
231
241
  st_insert(rbtracer.mid_tbl, (st_data_t)mid, (st_data_t)1);
232
- SEND_EVENT(2,
242
+ rbtrace__send_event(2,
233
243
  "mid",
234
244
  'l', mid,
235
245
  's', rb_id2name(mid)
@@ -241,7 +251,7 @@ SEND_NAMES(ID mid, VALUE klass)
241
251
 
242
252
  if (!st_is_member(rbtracer.klass_tbl, klass)) {
243
253
  st_insert(rbtracer.klass_tbl, (st_data_t)klass, (st_data_t)1);
244
- SEND_EVENT(2,
254
+ rbtrace__send_event(2,
245
255
  "klass",
246
256
  'l', klass,
247
257
  's', rb_class2name(klass)
@@ -249,6 +259,37 @@ SEND_NAMES(ID mid, VALUE klass)
249
259
  }
250
260
  }
251
261
 
262
+ static void
263
+ rbtracer__resolve_query(char *query, VALUE *klass, VALUE *self, ID *mid)
264
+ {
265
+ char *idx = NULL, *method = NULL;
266
+
267
+ assert(klass && self && mid);
268
+ *klass = *self = *mid = 0;
269
+
270
+ if (NULL != (idx = rindex(query, '.'))) {
271
+ *idx = 0;
272
+ *self = rb_eval_string_protect(query, 0);
273
+ *idx = '.';
274
+
275
+ method = idx+1;
276
+ } else if (NULL != (idx = rindex(query, '#'))) {
277
+ *idx = 0;
278
+ *klass = rb_eval_string_protect(query, 0);
279
+ *idx = '#';
280
+
281
+ method = idx+1;
282
+ } else {
283
+ method = query;
284
+ }
285
+
286
+ if (method && *method) {
287
+ *mid = rb_intern(method);
288
+ }
289
+ }
290
+
291
+ static int in_event_hook = 0;
292
+
252
293
  static void
253
294
  #ifdef RUBY_VM
254
295
  event_hook(rb_event_flag_t event, VALUE data, VALUE self, ID mid, VALUE klass)
@@ -256,8 +297,6 @@ event_hook(rb_event_flag_t event, VALUE data, VALUE self, ID mid, VALUE klass)
256
297
  event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
257
298
  #endif
258
299
  {
259
- static int in_event_hook = 0;
260
-
261
300
  // do not re-enter this function
262
301
  // after this, must `goto out` instead of `return`
263
302
  if (in_event_hook) return;
@@ -266,8 +305,8 @@ event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
266
305
  // skip allocators
267
306
  if (mid == ID_ALLOCATOR) goto out;
268
307
 
269
- // some serious 1.9.2 hax
270
308
  #ifdef RUBY_VM
309
+ // some serious 1.9.2 hax
271
310
  if (mid == 0 && ruby_current_thread) {
272
311
  ID _mid;
273
312
  VALUE _klass;
@@ -312,9 +351,10 @@ event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
312
351
  }
313
352
 
314
353
  if (diff > rbtracer.threshold * 1e3) {
315
- SEND_NAMES(mid, singleton ? self : klass);
316
- SEND_EVENT(5,
354
+ rbtrace__send_names(mid, singleton ? self : klass);
355
+ rbtrace__send_event(6,
317
356
  event == RUBY_EVENT_RETURN ? "slow" : "cslow",
357
+ 't', rbtracer.call_times[ rbtracer.num_calls ],
318
358
  'u', diff,
319
359
  'u', rbtracer.num_calls,
320
360
  'l', mid,
@@ -334,13 +374,15 @@ event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
334
374
  if (rbtracer.num == 0) goto out;
335
375
 
336
376
  for (i=0, n=0; i<MAX_TRACERS && n<rbtracer.num; i++) {
337
- if (rbtracer.list[i].query) {
377
+ rbtracer_t *curr = &rbtracer.list[i];
378
+
379
+ if (curr->query) {
338
380
  n++;
339
381
 
340
- if (!rbtracer.list[i].mid || rbtracer.list[i].mid == mid) {
341
- if (!rbtracer.list[i].klass || rbtracer.list[i].klass == klass) {
342
- if (!rbtracer.list[i].self || rbtracer.list[i].self == self) {
343
- tracer = &rbtracer.list[i];
382
+ if (!curr->mid || curr->mid == mid) {
383
+ if (!curr->klass || curr->klass == klass) {
384
+ if (!curr->self || curr->self == self) {
385
+ tracer = curr;
344
386
  break;
345
387
  }
346
388
  }
@@ -355,10 +397,10 @@ event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
355
397
  switch (event) {
356
398
  case RUBY_EVENT_CALL:
357
399
  case RUBY_EVENT_C_CALL:
358
- SEND_NAMES(mid, singleton ? self : klass);
359
- SEND_EVENT(5,
400
+ rbtrace__send_names(mid, singleton ? self : klass);
401
+ rbtrace__send_event(5,
360
402
  event == RUBY_EVENT_CALL ? "call" : "ccall",
361
- 't',
403
+ 'n',
362
404
  'd', tracer ? tracer->id : 255, // hax
363
405
  'l', mid,
364
406
  'b', singleton,
@@ -394,7 +436,7 @@ event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
394
436
  }
395
437
 
396
438
  if (result && *result) {
397
- SEND_EVENT(3,
439
+ rbtrace__send_event(3,
398
440
  "exprval",
399
441
  'd', tracer->id,
400
442
  'd', i,
@@ -407,9 +449,9 @@ event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
407
449
 
408
450
  case RUBY_EVENT_RETURN:
409
451
  case RUBY_EVENT_C_RETURN:
410
- SEND_EVENT(2,
452
+ rbtrace__send_event(2,
411
453
  event == RUBY_EVENT_RETURN ? "return" : "creturn",
412
- 't',
454
+ 'n',
413
455
  'd', tracer ? tracer->id : 255 // hax
414
456
  );
415
457
  break;
@@ -486,7 +528,7 @@ rbtracer_remove(char *query, int id)
486
528
  }
487
529
 
488
530
  out:
489
- SEND_EVENT(2,
531
+ rbtrace__send_event(2,
490
532
  "remove",
491
533
  'd', tracer_id,
492
534
  's', query
@@ -499,6 +541,7 @@ rbtracer_remove_all()
499
541
  {
500
542
  rbtracer.firehose = false;
501
543
  rbtracer.slow = false;
544
+ rbtracer.gc = false;
502
545
 
503
546
  int i;
504
547
  for (i=0; i<MAX_TRACERS; i++) {
@@ -534,34 +577,13 @@ rbtracer_add(char *query)
534
577
  }
535
578
  if (!tracer) goto out;
536
579
 
537
- char *idx, *method;
538
580
  VALUE klass = 0, self = 0;
539
581
  ID mid = 0;
540
582
 
541
- if (NULL != (idx = rindex(query, '.'))) {
542
- *idx = 0;
543
- self = rb_eval_string_protect(query, 0);
544
- *idx = '.';
583
+ rbtracer__resolve_query(query, &klass, &self, &mid);
545
584
 
546
- method = idx+1;
547
- } else if (NULL != (idx = rindex(query, '#'))) {
548
- *idx = 0;
549
- klass = rb_eval_string_protect(query, 0);
550
- *idx = '#';
551
-
552
- method = idx+1;
553
- } else {
554
- method = query;
555
- }
556
-
557
- if (method && *method) {
558
- mid = rb_intern(method);
559
- if (!mid) goto out;
560
- } else if (klass || self) {
561
- mid = 0;
562
- } else {
585
+ if (!mid && !klass && !self)
563
586
  goto out;
564
- }
565
587
 
566
588
  memset(tracer, 0, sizeof(*tracer));
567
589
 
@@ -578,7 +600,7 @@ rbtracer_add(char *query)
578
600
  rbtracer.num++;
579
601
 
580
602
  out:
581
- SEND_EVENT(2,
603
+ rbtrace__send_event(2,
582
604
  "add",
583
605
  'd', tracer_id,
584
606
  's', query
@@ -606,7 +628,7 @@ rbtracer_add_expr(int id, char *expr)
606
628
  }
607
629
 
608
630
  out:
609
- SEND_EVENT(3,
631
+ rbtrace__send_event(3,
610
632
  "newexpr",
611
633
  'd', tracer_id,
612
634
  'd', expr_id,
@@ -719,6 +741,10 @@ sigurg(int signal)
719
741
  if (!success || cmd.type != MSGPACK_OBJECT_ARRAY)
720
742
  continue;
721
743
 
744
+ /* fprintf(stderr, "GOT: ");*/
745
+ /* msgpack_object_print(stderr, cmd);*/
746
+ /* fprintf(stderr, "\n");*/
747
+
722
748
  ary = cmd.via.array;
723
749
 
724
750
  if (ary.size < 1 ||
@@ -737,13 +763,13 @@ sigurg(int signal)
737
763
  if (pid && rbtracer.attached_pid == 0)
738
764
  rbtracer.attached_pid = pid;
739
765
 
740
- SEND_EVENT(1,
766
+ rbtrace__send_event(1,
741
767
  "attached",
742
768
  'u', (uint32_t) rbtracer.attached_pid
743
769
  );
744
770
 
745
771
  } else if (0 == strncmp("detach", str.ptr, str.size)) {
746
- SEND_EVENT(1,
772
+ rbtrace__send_event(1,
747
773
  "detached",
748
774
  'u', (uint32_t) rbtracer.attached_pid
749
775
  );
@@ -785,14 +811,34 @@ sigurg(int signal)
785
811
  query[str.size] = 0;
786
812
  rbtracer_add_expr(last_tracer_id, query);
787
813
 
814
+ } else if (0 == strncmp("gc", str.ptr, str.size)) {
815
+ rbtracer.gc = true;
816
+
788
817
  }
789
818
  }
790
819
  }
791
820
  }
792
821
 
822
+ static void
823
+ rbtrace_gc_mark()
824
+ {
825
+ if (rbtracer.gc && !in_event_hook) {
826
+ rbtrace__send_event(1,
827
+ "gc",
828
+ 'n'
829
+ );
830
+ }
831
+ }
832
+
833
+ static VALUE gc_hook;
834
+
793
835
  void
794
836
  Init_rbtrace()
795
837
  {
838
+ // hook into the gc
839
+ gc_hook = Data_Wrap_Struct(rb_cObject, rbtrace_gc_mark, NULL, NULL);
840
+ rb_global_variable(&gc_hook);
841
+
796
842
  // setup msgpack
797
843
  rbtracer.sbuf = msgpack_sbuffer_new();
798
844
  rbtracer.msgpacker = msgpack_packer_new(rbtracer.sbuf, msgpack_sbuffer_write);
data/rbtrace.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'rbtrace'
3
- s.version = '0.3.3'
3
+ s.version = '0.3.4'
4
4
  s.homepage = 'http://github.com/tmm1/rbtrace'
5
5
 
6
6
  s.authors = 'Aman Gupta'
data/server.rb CHANGED
@@ -14,6 +14,7 @@ while true
14
14
  Process.pid
15
15
  'hello'.multiply_vowels(3){ :ohai }
16
16
  sleep rand*0.5
17
+ GC.start
17
18
  end
18
19
  }.call
19
20
  end
data/test.sh CHANGED
@@ -1,7 +1,15 @@
1
1
  #!/bin/sh
2
2
  set -e
3
3
 
4
- make -C ext 2>&1 >/dev/null
4
+ cd ext
5
+ [ -f Makefile ] && make clean
6
+ ruby extconf.rb
7
+ make
8
+ cd ..
9
+
10
+ bundle check
11
+ export RUBYOPT="-I."
12
+
5
13
  ruby server.rb &
6
14
  export PID=$!
7
15
 
@@ -26,6 +34,8 @@ trace -m sleep
26
34
  trace -m sleep Dir.chdir Dir.pwd Process.pid "String#gsub" "String#*"
27
35
  trace -m "Kernel#"
28
36
  trace -m "String#gsub(self,@test)" "String#*(self,__source__)" "String#multiply_vowels(self,self.length,num)"
37
+ trace --gc --slow=200
38
+ trace --gc -m Dir.
29
39
  trace --slow=250
30
40
  trace --firehose
31
41
 
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: 21
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 3
9
- - 3
10
- version: 0.3.3
9
+ - 4
10
+ version: 0.3.4
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 00:00:00 -08:00
18
+ date: 2011-02-19 00:00:00 -08:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency