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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: a8cd3dd5d2826625fbf017e93f76f52edbaa0b83
4
- data.tar.gz: 50b49986ffdeab614a9076c5f861738c9d4e4a70
2
+ SHA256:
3
+ metadata.gz: 78fc8aa96b3b20a4663ceaef1253f41443689e85f344a9efecb60c240e85183b
4
+ data.tar.gz: 2f2ab561dfe12096dcbe28ff188d07e34af48bbed936f09bbc0dd23309132bea
5
5
  SHA512:
6
- metadata.gz: ab75bcf6469ae23f80ec62e520e840710ef912e7080ef69474821e38077a9893a1a16d812048d3d47d990ffbe79e4d2dc075ed9367484835e240b35257f22dee
7
- data.tar.gz: 9a2ce4b26b191f1064ba30601a37f4b0f8e6490bb1dec9776720bbcd4935653c823db45f1381d09d0f00b9735a8c0bab31e772985da0524c7f72b7ed17d4ebf1
6
+ metadata.gz: 1710793189ea23b9048c68ff61c1c7f52202b4e7770991e4c049f9b1b069dbbe4fd71f59e2e79a06d34c4c15628073d0498175fcbb64572152c22b9636557a09
7
+ data.tar.gz: 315c8c2bc040cf790e4964a93ee9f50b97f9b2b7718f71790e8af36cb2d1fe01d529da06fd6b346747e45fc82b52b2fde6fd62bf9053010e8e93d38f76e575fe
data/.gitignore CHANGED
@@ -1,3 +1,5 @@
1
1
  *.gem
2
2
  .bundle
3
3
  ext/src/msgpack*
4
+ tmp/*
5
+ Gemfile.lock
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_)
@@ -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
+
@@ -13,7 +13,7 @@ require 'fileutils'
13
13
 
14
14
  libdir = File.basename RbConfig::CONFIG['libdir']
15
15
 
16
- unless File.exists?("#{CWD}/dst/#{libdir}/libmsgpackc.a")
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.exists?(dir)
31
+ FileUtils.rm_rf(dir) if File.exist?(dir)
32
32
 
33
33
  sys("tar zxvfo #{msgpack}")
34
34
  Dir.chdir(dir) do
@@ -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 = rindex(query, '.'))) {
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 = rindex(query, '#'))) {
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
- snprintf(code, BUF_SIZE+150, "(begin; %s; rescue Exception => e; e; end).inspect", query);
1016
- val = rb_eval_string_protect(code, 0);
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);
@@ -1,4 +1,4 @@
1
- require 'trollop'
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.exists?(msgmnb = "/proc/sys/kernel/msgmnb")
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 = Trollop::Parser.new do
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 = Trollop.with_standard_exception_handling(parser) do
215
- raise Trollop::HelpNeeded if ARGV.empty?
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.exists?(f) }
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} processes matching #{opts[:ps].inspect}"
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
- STDERR.puts " [#{(i+1).to_s.rjust(max_len)}] #{line.strip}"
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
- STDERR.print "*** trace which processes? (0/1,4): "
319
+
320
+ if filtered.length > 1
321
+ STDERR.print "*** trace which processes? (0/1,4): "
322
+ end
297
323
 
298
324
  begin
299
- input = gets
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 |pid|
405
+ tracers.each do |pid1|
376
406
  begin
377
- Process.kill 'INT', pid
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
@@ -96,7 +96,7 @@ class RBTracer
96
96
  end
97
97
 
98
98
  def clean_socket_path
99
- FileUtils.rm(socket_path) if File.exists?(socket_path)
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
- raise ArgumentError, 'command is too long' if msg.bytesize > MsgQ::EventMsg::BUF_SIZE
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
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class RBTracer
2
- VERSION = '0.4.9'
4
+ VERSION = '0.4.14'
3
5
  end
@@ -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
- s.add_dependency 'ffi', '>= 1.0.6'
18
- s.add_dependency 'trollop', '>= 1.16.2'
19
- s.add_dependency 'msgpack', '>= 0.4.3'
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.chdir("/tmp") do
30
- Dir.pwd
31
- Process.pid
32
- 'hello'.multiply_vowels(3){ :ohai }
33
- sleep rand*0.5
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
- ENV['blah']
36
- GC.start
37
+ ENV['blah']
38
+ GC.start
37
39
 
38
- reload_test.call
39
- Test.run
40
+ reload_test.call
41
+ Test.run
40
42
 
41
- #fib(1024*100)
43
+ #fib(1024*100)
44
+ end
42
45
  end
43
46
  }.call
44
47
  end
@@ -1,3 +1,4 @@
1
+ ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter#execute(sql)
1
2
  ActiveRecord::ConnectionAdapters::MysqlAdapter#execute(sql)
2
3
  ActiveRecord::ConnectionAdapters::PostgreSQLAdapter#execute(sql)
3
4
  ActiveRecord::ConnectionAdapters::SQLiteAdapter#execute(sql)
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.9
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: 2018-01-03 00:00:00.000000000 Z
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: trollop
28
+ name: optimist
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 1.16.2
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: 1.16.2
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
- rubyforge_project:
111
- rubygems_version: 2.6.13
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: []
@@ -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!