rbtrace 0.4.13 → 0.5.0
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 +4 -4
- data/.github/workflows/ci.yml +26 -0
- data/CHANGELOG +7 -0
- data/ext/extconf.rb +2 -7
- data/ext/rbtrace.c +20 -22
- data/lib/rbtrace/cli.rb +46 -5
- data/lib/rbtrace/core_ext.rb +0 -4
- data/lib/rbtrace/msgq.rb +2 -1
- data/lib/rbtrace/rbtracer.rb +4 -2
- data/lib/rbtrace/version.rb +1 -1
- data/lib/rbtrace.rb +22 -0
- data/rbtrace.gemspec +1 -1
- data/server.rb +14 -11
- data/test.sh +6 -4
- metadata +13 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc6fc7320951955050f41babf4a1effbec1eaac42e9103a0c8b08c69cc2ad090
|
4
|
+
data.tar.gz: 105f410c0c78e6f23c3d6617165b7a1c3c9a72976735cfd185481c91acb3bb17
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a4e42ec27236d32067f52fa3c0ed1a1a3eb518f1f0d4de9c42dcbec787dc62346f39c790ae2b74fcca6835bc1413c3e44216398c8ca46d74d760f0d75a551873
|
7
|
+
data.tar.gz: 4602057b9797b58337d2308a195ee1d1e6e9247a7e08bebf40d153bd9c6f4fb1f4871851b514b0fef471cf87df002632b0c75ff6511dc926e58c86be453d8b67
|
@@ -0,0 +1,26 @@
|
|
1
|
+
---
|
2
|
+
name: Test
|
3
|
+
on: [push, pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
ruby:
|
7
|
+
name: Ruby ${{ matrix.ruby }}
|
8
|
+
timeout-minutes: 15
|
9
|
+
strategy:
|
10
|
+
fail-fast: false
|
11
|
+
matrix:
|
12
|
+
os: ["ubuntu-latest"]
|
13
|
+
ruby: ["3.2", "3.1", "3.0", "2.7", "2.6"]
|
14
|
+
runs-on: ubuntu-latest
|
15
|
+
steps:
|
16
|
+
- name: Check out code
|
17
|
+
uses: actions/checkout@v3
|
18
|
+
|
19
|
+
- name: Set up Ruby
|
20
|
+
uses: ruby/setup-ruby@v1
|
21
|
+
with:
|
22
|
+
ruby-version: ${{ matrix.ruby }}
|
23
|
+
bundler-cache: true
|
24
|
+
|
25
|
+
- name: Tests
|
26
|
+
run: ./test.sh
|
data/CHANGELOG
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
- 0.5.0 - 02-12-2023
|
2
|
+
|
3
|
+
- Improved --backtraces implementation
|
4
|
+
- Added --shapedump which is useful for lighter weight object shape dumps on Ruby 3.2 and up
|
5
|
+
- Move heap dumping to a fork for better performance
|
6
|
+
- Use TypedData API which has been supported for a very long time
|
7
|
+
- Update CI and fix some small errors
|
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
|
@@ -63,11 +63,6 @@ have_func('rb_during_gc', 'ruby.h')
|
|
63
63
|
have_func('rb_gc_add_event_hook', ['ruby.h', 'node.h'])
|
64
64
|
have_func('rb_postponed_job_register_one', 'ruby.h')
|
65
65
|
|
66
|
-
# increase message size on linux
|
67
|
-
if RUBY_PLATFORM =~ /linux/
|
68
|
-
$defs.push("-DBUF_SIZE=256")
|
69
|
-
end
|
70
|
-
|
71
66
|
# warnings save lives
|
72
67
|
$CFLAGS << " -Wall "
|
73
68
|
|
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
|
{
|
@@ -73,7 +79,7 @@ timeofday_usec()
|
|
73
79
|
#define MAX_TRACERS 100 // max method tracers
|
74
80
|
#define MAX_EXPRS 10 // max expressions per tracer
|
75
81
|
#ifndef BUF_SIZE // msgq buffer size
|
76
|
-
#define BUF_SIZE
|
82
|
+
#define BUF_SIZE 1024
|
77
83
|
#endif
|
78
84
|
|
79
85
|
typedef struct {
|
@@ -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;
|
@@ -870,9 +876,7 @@ eval_inspect(VALUE rb_code) {
|
|
870
876
|
}
|
871
877
|
|
872
878
|
static VALUE
|
873
|
-
rescue_inspect(VALUE arg) {
|
874
|
-
VALUE exception = rb_errinfo(); /* get last exception */
|
875
|
-
rb_set_errinfo(Qnil);
|
879
|
+
rescue_inspect(VALUE arg, VALUE exception) {
|
876
880
|
return rb_funcall(exception, rb_intern("inspect"), 0);
|
877
881
|
}
|
878
882
|
|
@@ -885,7 +889,6 @@ rbtrace__process_event(msgpack_object cmd)
|
|
885
889
|
static int last_tracer_id = -1; // hax
|
886
890
|
char query[BUF_SIZE];
|
887
891
|
|
888
|
-
char code[BUF_SIZE+150];
|
889
892
|
VALUE val = Qnil;
|
890
893
|
|
891
894
|
msgpack_object_array ary;
|
@@ -1129,31 +1132,26 @@ send_write(VALUE klass, VALUE val) {
|
|
1129
1132
|
return Qnil;
|
1130
1133
|
}
|
1131
1134
|
|
1135
|
+
static const rb_data_type_t rbtrace_type = {
|
1136
|
+
"RBTrace",
|
1137
|
+
{
|
1138
|
+
rbtrace_gc_mark,
|
1139
|
+
}
|
1140
|
+
};
|
1141
|
+
|
1132
1142
|
void
|
1133
1143
|
Init_rbtrace()
|
1134
1144
|
{
|
1135
1145
|
rbtrace_module = rb_define_module("RBTrace");
|
1136
1146
|
VALUE output = rb_define_module_under(rbtrace_module, "OUT");
|
1137
1147
|
|
1138
|
-
|
1148
|
+
rb_const_set(rbtrace_module, rb_intern("BUF_SIZE"), INT2NUM(BUF_SIZE));
|
1139
1149
|
|
1140
|
-
|
1141
|
-
"module RBTrace\n"
|
1142
|
-
" def self.eval_context\n"
|
1143
|
-
" @eval_context ||= binding\n"
|
1144
|
-
" end\n"
|
1145
|
-
|
1146
|
-
" def self.eval_and_inspect(code)\n"
|
1147
|
-
" t = Thread.new { Thread.current[:output] = eval_context.eval(code).inspect }\n"
|
1148
|
-
" t.join\n"
|
1149
|
-
" t[:output]\n"
|
1150
|
-
" end\n"
|
1151
|
-
"end\n"
|
1152
|
-
);
|
1150
|
+
rb_define_singleton_method(output, "write", send_write, 1);
|
1153
1151
|
|
1154
1152
|
// hook into the gc
|
1155
|
-
gc_hook = Data_Wrap_Struct(rb_cObject, rbtrace_gc_mark, NULL, NULL);
|
1156
1153
|
rb_global_variable(&gc_hook);
|
1154
|
+
gc_hook = TypedData_Wrap_Struct(rb_cObject, &rbtrace_type, NULL);
|
1157
1155
|
|
1158
1156
|
// catch signal telling us to read from the msgq
|
1159
1157
|
#if defined(HAVE_RB_POSTPONED_JOB_REGISTER_ONE)
|
data/lib/rbtrace/cli.rb
CHANGED
@@ -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}"
|
@@ -225,6 +225,9 @@ EOS
|
|
225
225
|
:default => "AUTO",
|
226
226
|
:short => "-h"
|
227
227
|
|
228
|
+
opt :shapesdump,
|
229
|
+
"generate a shapes dump for the process in FILENAME",
|
230
|
+
:default => "AUTO"
|
228
231
|
end
|
229
232
|
|
230
233
|
opts = Optimist.with_standard_exception_handling(parser) do
|
@@ -241,7 +244,7 @@ EOS
|
|
241
244
|
end
|
242
245
|
|
243
246
|
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."
|
247
|
+
$stderr.puts "Error: --slow, --slowcpu, --gc, --firehose, --methods, --interactive, --backtraces, --backtrace, --memory, --heapdump, --shapesdump or --config required."
|
245
248
|
$stderr.puts "Try --help for help."
|
246
249
|
exit(-1)
|
247
250
|
end
|
@@ -273,7 +276,7 @@ EOS
|
|
273
276
|
file = [
|
274
277
|
config,
|
275
278
|
File.expand_path("../../../tracers/#{config}.tracer", __FILE__)
|
276
|
-
].find{ |f| File.
|
279
|
+
].find{ |f| File.exist?(f) }
|
277
280
|
|
278
281
|
unless file
|
279
282
|
parser.die :config, '(file does not exist)'
|
@@ -449,7 +452,7 @@ EOS
|
|
449
452
|
|
450
453
|
delim = "146621c9d681409aa"
|
451
454
|
|
452
|
-
code = "Thread.list.map{|t| t.backtrace[0...#{num}].join(\"#{delim}\")}.join(\"#{delim*2}\")"
|
455
|
+
code = "Thread.list.reject { |t| t.name == '__RBTrace__' }.map{ |t| t.backtrace[0...#{num}].join(\"#{delim}\")}.join(\"#{delim*2}\")"
|
453
456
|
|
454
457
|
if res = tracer.eval(code)
|
455
458
|
tracer.puts res.split(delim).join("\n")
|
@@ -499,9 +502,47 @@ EOS
|
|
499
502
|
temp.unlink
|
500
503
|
end
|
501
504
|
|
502
|
-
tracer.eval(
|
505
|
+
tracer.eval(<<-RUBY)
|
506
|
+
Thread.new do
|
507
|
+
Thread.current.name = '__RBTrace__'
|
508
|
+
pid = ::Process.fork do
|
509
|
+
file = File.open('#{filename}.tmp', 'w')
|
510
|
+
ObjectSpace.dump_all(output: file)
|
511
|
+
file.close
|
512
|
+
File.rename('#{filename}.tmp', '#{filename}')
|
513
|
+
exit!(0)
|
514
|
+
end
|
515
|
+
Process.waitpid(pid)
|
516
|
+
end
|
517
|
+
RUBY
|
503
518
|
puts "Heapdump being written to #{filename}"
|
504
519
|
|
520
|
+
elsif opts[:shapesdump_given]
|
521
|
+
filename = opts[:shapesdump]
|
522
|
+
|
523
|
+
if filename == "AUTO"
|
524
|
+
require 'tempfile'
|
525
|
+
temp = Tempfile.new("dump")
|
526
|
+
filename = temp.path
|
527
|
+
temp.close
|
528
|
+
temp.unlink
|
529
|
+
end
|
530
|
+
|
531
|
+
tracer.eval(<<-RUBY)
|
532
|
+
Thread.new do
|
533
|
+
Thread.current.name = '__RBTrace__'
|
534
|
+
pid = ::Process.fork do
|
535
|
+
file = File.open('#{filename}.tmp', 'w')
|
536
|
+
ObjectSpace.dump_shapes(output: file)
|
537
|
+
file.close
|
538
|
+
File.rename('#{filename}.tmp', '#{filename}')
|
539
|
+
exit!(0)
|
540
|
+
end
|
541
|
+
Process.waitpid(pid)
|
542
|
+
end
|
543
|
+
RUBY
|
544
|
+
puts "Shapes dump being written to #{filename}"
|
545
|
+
|
505
546
|
elsif opts[:eval_given]
|
506
547
|
if res = tracer.eval(code = opts[:eval])
|
507
548
|
tracer.puts ">> #{code}"
|
data/lib/rbtrace/core_ext.rb
CHANGED
data/lib/rbtrace/msgq.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'rbtrace'
|
1
2
|
require 'ffi'
|
2
3
|
|
3
4
|
module MsgQ
|
@@ -5,7 +6,7 @@ module MsgQ
|
|
5
6
|
ffi_lib FFI::CURRENT_PROCESS
|
6
7
|
|
7
8
|
class EventMsg < FFI::Struct
|
8
|
-
BUF_SIZE =
|
9
|
+
BUF_SIZE = RBTrace::BUF_SIZE
|
9
10
|
IPC_NOWAIT = 004000
|
10
11
|
|
11
12
|
layout :mtype, :long,
|
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.
|
@@ -323,7 +323,9 @@ class RBTracer
|
|
323
323
|
msg = cmd.to_msgpack
|
324
324
|
# A message is null-terminated, but bytesize gives the unterminated
|
325
325
|
# length.
|
326
|
-
|
326
|
+
if msg.bytesize >= RbTrace::BUF_SIZE
|
327
|
+
raise ArgumentError, "command is too long (#{msg.bytesize}B >= #{MsgQ::EventMsg::BUF_SIZE}B)"
|
328
|
+
end
|
327
329
|
MsgQ::EventMsg.send_cmd(@qo, msg)
|
328
330
|
rescue Errno::EINTR
|
329
331
|
retry
|
data/lib/rbtrace/version.rb
CHANGED
data/lib/rbtrace.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RBTrace
|
4
|
+
class << self
|
5
|
+
def eval_and_inspect(code)
|
6
|
+
t = Thread.new do
|
7
|
+
Thread.current.name = '__RBTrace__'
|
8
|
+
Thread.current[:output] = eval_context.eval(code).inspect
|
9
|
+
end
|
10
|
+
t.join
|
11
|
+
t[:output]
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def eval_context
|
17
|
+
@eval_context ||= binding
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'rbtrace.so'
|
data/rbtrace.gemspec
CHANGED
@@ -23,7 +23,7 @@ Gem::Specification.new do |s|
|
|
23
23
|
s.add_dependency 'optimist', '>= 3.0.0'
|
24
24
|
s.add_dependency 'msgpack', '>= 0.4.3'
|
25
25
|
|
26
|
-
s.add_development_dependency "rake"
|
26
|
+
s.add_development_dependency "rake"
|
27
27
|
|
28
28
|
s.license = "MIT"
|
29
29
|
s.summary = 'rbtrace: like strace but for ruby code'
|
data/server.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
require '
|
1
|
+
require '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/test.sh
CHANGED
@@ -12,7 +12,7 @@ cd ..
|
|
12
12
|
bundle check
|
13
13
|
export RUBYOPT="-I.:lib"
|
14
14
|
|
15
|
-
ruby server.rb &
|
15
|
+
bundle exec ruby server.rb &
|
16
16
|
export PID=$!
|
17
17
|
|
18
18
|
trap cleanup INT TERM
|
@@ -23,11 +23,11 @@ cleanup() {
|
|
23
23
|
|
24
24
|
trace() {
|
25
25
|
echo ------------------------------------------
|
26
|
-
echo ./bin/rbtrace -p $PID
|
26
|
+
echo ./bin/rbtrace -p $PID "$@"
|
27
27
|
echo ------------------------------------------
|
28
|
-
./bin/rbtrace -p $PID
|
28
|
+
bundle exec ./bin/rbtrace -p $PID "$@" &
|
29
29
|
sleep 2
|
30
|
-
kill $!
|
30
|
+
kill $! || true
|
31
31
|
wait $! || true
|
32
32
|
echo
|
33
33
|
}
|
@@ -37,6 +37,8 @@ trace -m sleep
|
|
37
37
|
trace -m sleep Dir.chdir Dir.pwd Process.pid "String#gsub" "String#*"
|
38
38
|
trace -m "Kernel#"
|
39
39
|
trace -m "String#gsub(self,@test)" "String#*(self,__source__)" "String#multiply_vowels(self,self.length,num)"
|
40
|
+
trace -e 'p(1 + 1)'
|
41
|
+
trace -h
|
40
42
|
trace --gc --slow=200
|
41
43
|
trace --gc -m Dir.
|
42
44
|
trace --slow=250
|
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
|
+
version: 0.5.0
|
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: 2023-12-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -56,16 +56,16 @@ dependencies:
|
|
56
56
|
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '0'
|
69
69
|
description: rbtrace shows you method calls happening inside another ruby process
|
70
70
|
in real time.
|
71
71
|
email: aman@tmm1.net
|
@@ -75,7 +75,9 @@ extensions:
|
|
75
75
|
- ext/extconf.rb
|
76
76
|
extra_rdoc_files: []
|
77
77
|
files:
|
78
|
+
- ".github/workflows/ci.yml"
|
78
79
|
- ".gitignore"
|
80
|
+
- CHANGELOG
|
79
81
|
- Gemfile
|
80
82
|
- LICENSE
|
81
83
|
- README.md
|
@@ -85,6 +87,7 @@ files:
|
|
85
87
|
- ext/extconf.rb
|
86
88
|
- ext/rbtrace.c
|
87
89
|
- ext/src/msgpack-1.1.0.tar.gz
|
90
|
+
- lib/rbtrace.rb
|
88
91
|
- lib/rbtrace/cli.rb
|
89
92
|
- lib/rbtrace/core_ext.rb
|
90
93
|
- lib/rbtrace/interactive/irb.rb
|
@@ -107,7 +110,7 @@ homepage: http://github.com/tmm1/rbtrace
|
|
107
110
|
licenses:
|
108
111
|
- MIT
|
109
112
|
metadata: {}
|
110
|
-
post_install_message:
|
113
|
+
post_install_message:
|
111
114
|
rdoc_options: []
|
112
115
|
require_paths:
|
113
116
|
- lib
|
@@ -123,8 +126,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
126
|
- !ruby/object:Gem::Version
|
124
127
|
version: '0'
|
125
128
|
requirements: []
|
126
|
-
rubygems_version: 3.
|
127
|
-
signing_key:
|
129
|
+
rubygems_version: 3.4.19
|
130
|
+
signing_key:
|
128
131
|
specification_version: 4
|
129
132
|
summary: 'rbtrace: like strace but for ruby code'
|
130
133
|
test_files: []
|