rbtrace 0.5.4 → 0.5.5
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 +1 -1
- data/CHANGELOG +10 -4
- data/ext/extconf.rb +2 -0
- data/ext/rbtrace.c +102 -19
- data/lib/rbtrace/cli.rb +3 -1
- data/lib/rbtrace/version.rb +1 -1
- data/server.rb +1 -0
- data/test.sh +79 -5
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9628477734dcb6ba5d9e02abbcb0c599b74764cf1b4cf385958adc77caafc21b
|
|
4
|
+
data.tar.gz: 9fe0cc77c6f3dc2a98e7890bbefae1058f7a1f5258d3f3443785ca970d524496
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b487fa9ff0ed5b62d9a030057f72e8a55279b2ede600a27376895f3497a0f073882ff2ef536c0d92a960703207b8337b1cb07245a23b8e4b1e856c8bef55a961
|
|
7
|
+
data.tar.gz: a9286d573871f902c7a73f1b9f9eaa5138d84835c7849bbd37ee460678f0cb02412fb0ce7d8760d1f0accdf20120cf6370147b4521dffd4a662964ae0eb72f5d
|
data/.github/workflows/ci.yml
CHANGED
data/CHANGELOG
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
- 0.5.5 - 07-08-2026
|
|
2
|
+
|
|
3
|
+
- Add Ruby 4.1 support by using the current postponed-job and block callback APIs
|
|
4
|
+
- Fix native command handling to validate MessagePack input, release native memory, and reject invalid tracer IDs
|
|
5
|
+
- Fix traced expressions to avoid the deprecated ObjectSpace._id2ref API
|
|
6
|
+
- Fix --heapdump and --shapesdump by loading objspace before using its dump APIs
|
|
7
|
+
|
|
1
8
|
- 0.5.4 - 19-05-2026
|
|
2
9
|
|
|
3
10
|
- Fix --interactive irb mode not printing eval results
|
|
@@ -5,21 +12,20 @@
|
|
|
5
12
|
- 0.5.3 - 03-12-2025
|
|
6
13
|
|
|
7
14
|
- Fix --interactive irb mode
|
|
8
|
-
- Fix: Build failures with C23 (#100)
|
|
9
15
|
|
|
10
|
-
- 0.5.2 - 05-
|
|
16
|
+
- 0.5.2 - 13-05-2025
|
|
11
17
|
|
|
12
18
|
- Specify void* argument in rbtrace_gc_mark()'s signature, as expected by rb_data_type_t.
|
|
13
19
|
This was a warning before C23 but it's now an error, and GCC 15 defaults to C23.
|
|
14
20
|
|
|
15
21
|
- 0.5.1 - 19-12-2023
|
|
16
22
|
|
|
17
|
-
- Fix: RbTrace was used incorrectly instead of RBTrace, which
|
|
23
|
+
- Fix: RbTrace was used incorrectly instead of RBTrace, which led to a broken build
|
|
18
24
|
|
|
19
25
|
- 0.5.0 - 02-12-2023
|
|
20
26
|
|
|
21
27
|
- Improved --backtraces implementation
|
|
22
|
-
- Added --
|
|
28
|
+
- Added --shapesdump which is useful for lighter weight object shape dumps on Ruby 3.2 and up
|
|
23
29
|
- Move heap dumping to a fork for better performance
|
|
24
30
|
- Use TypedData API which has been supported for a very long time
|
|
25
31
|
- Update CI and fix some small errors
|
data/ext/extconf.rb
CHANGED
|
@@ -61,6 +61,8 @@ end
|
|
|
61
61
|
|
|
62
62
|
have_func('rb_during_gc', 'ruby.h')
|
|
63
63
|
have_func('rb_gc_add_event_hook', ['ruby.h', 'node.h'])
|
|
64
|
+
have_func('rb_postponed_job_preregister', ['ruby.h', 'ruby/debug.h'])
|
|
65
|
+
have_func('rb_postponed_job_trigger', ['ruby.h', 'ruby/debug.h'])
|
|
64
66
|
have_func('rb_postponed_job_register_one', 'ruby.h')
|
|
65
67
|
|
|
66
68
|
# warnings save lives
|
data/ext/rbtrace.c
CHANGED
|
@@ -307,6 +307,18 @@ rbtrace__send_names(ID mid, VALUE klass)
|
|
|
307
307
|
}
|
|
308
308
|
}
|
|
309
309
|
|
|
310
|
+
typedef struct {
|
|
311
|
+
VALUE proc;
|
|
312
|
+
VALUE receiver;
|
|
313
|
+
} expr_proc_call_t;
|
|
314
|
+
|
|
315
|
+
static VALUE
|
|
316
|
+
call_expr_proc(VALUE data)
|
|
317
|
+
{
|
|
318
|
+
expr_proc_call_t *args = (expr_proc_call_t *)data;
|
|
319
|
+
return rb_funcall(args->proc, rb_intern("call"), 1, args->receiver);
|
|
320
|
+
}
|
|
321
|
+
|
|
310
322
|
static int in_event_hook = 0;
|
|
311
323
|
|
|
312
324
|
static void
|
|
@@ -491,8 +503,16 @@ event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
|
|
491
503
|
val = rb_inspect(rb_ivar_get(self, rb_intern(expr)));
|
|
492
504
|
|
|
493
505
|
} else {
|
|
494
|
-
|
|
495
|
-
|
|
506
|
+
int state = 0;
|
|
507
|
+
VALUE expr_proc;
|
|
508
|
+
expr_proc_call_t args;
|
|
509
|
+
snprintf(buffer, len+150, "proc { |__rbtrace_receiver__| (begin; __rbtrace_receiver__.instance_eval { %s }; rescue Exception => e; e; end).inspect }", expr);
|
|
510
|
+
expr_proc = rb_eval_string_protect(buffer, &state);
|
|
511
|
+
if (state == 0) {
|
|
512
|
+
args.proc = expr_proc;
|
|
513
|
+
args.receiver = self;
|
|
514
|
+
val = rb_protect(call_expr_proc, (VALUE)&args, &state);
|
|
515
|
+
}
|
|
496
516
|
}
|
|
497
517
|
|
|
498
518
|
if (RTEST(val) && TYPE(val) == T_STRING) {
|
|
@@ -590,10 +610,12 @@ rbtracer_remove(char *query, int id)
|
|
|
590
610
|
}
|
|
591
611
|
}
|
|
592
612
|
} else {
|
|
593
|
-
if (id >= MAX_TRACERS) goto out;
|
|
613
|
+
if (id < 0 || id >= MAX_TRACERS) goto out;
|
|
594
614
|
tracer = &rbtracer.list[id];
|
|
595
615
|
}
|
|
596
616
|
|
|
617
|
+
if (!tracer) goto out;
|
|
618
|
+
|
|
597
619
|
if (tracer->query) {
|
|
598
620
|
tracer_id = tracer->id;
|
|
599
621
|
tracer->mid = 0;
|
|
@@ -735,10 +757,16 @@ rbtracer_add(char *query, bool is_slow)
|
|
|
735
757
|
goto out;
|
|
736
758
|
}
|
|
737
759
|
|
|
760
|
+
char *query_copy = strdup(query);
|
|
761
|
+
if (!query_copy) {
|
|
762
|
+
tracer_id = -1;
|
|
763
|
+
goto out;
|
|
764
|
+
}
|
|
765
|
+
|
|
738
766
|
memset(tracer, 0, sizeof(*tracer));
|
|
739
767
|
|
|
740
768
|
tracer->id = tracer_id;
|
|
741
|
-
tracer->query =
|
|
769
|
+
tracer->query = query_copy;
|
|
742
770
|
tracer->is_slow = is_slow;
|
|
743
771
|
|
|
744
772
|
if (klass_end != klass_begin) {
|
|
@@ -774,15 +802,19 @@ rbtracer_add_expr(int id, char *expr)
|
|
|
774
802
|
int tracer_id = -1;
|
|
775
803
|
rbtracer_t *tracer = NULL;
|
|
776
804
|
|
|
777
|
-
if (id >= MAX_TRACERS) goto out;
|
|
805
|
+
if (id < 0 || id >= MAX_TRACERS) goto out;
|
|
778
806
|
tracer = &rbtracer.list[id];
|
|
779
807
|
|
|
780
808
|
if (tracer->query) {
|
|
781
809
|
tracer_id = tracer->id;
|
|
782
810
|
|
|
783
811
|
if (tracer->num_exprs < MAX_EXPRS) {
|
|
784
|
-
|
|
785
|
-
|
|
812
|
+
char *expr_copy = strdup(expr);
|
|
813
|
+
if (!expr_copy) goto out;
|
|
814
|
+
|
|
815
|
+
expr_id = tracer->num_exprs;
|
|
816
|
+
tracer->exprs[expr_id] = expr_copy;
|
|
817
|
+
tracer->num_exprs++;
|
|
786
818
|
}
|
|
787
819
|
}
|
|
788
820
|
|
|
@@ -1043,6 +1075,20 @@ rbtrace__process_event(msgpack_object cmd)
|
|
|
1043
1075
|
}
|
|
1044
1076
|
}
|
|
1045
1077
|
|
|
1078
|
+
static VALUE
|
|
1079
|
+
rbtrace__process_unpacked_event(VALUE data)
|
|
1080
|
+
{
|
|
1081
|
+
rbtrace__process_event(*(msgpack_object *)data);
|
|
1082
|
+
return Qnil;
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
static VALUE
|
|
1086
|
+
rbtrace__destroy_unpacked(VALUE data)
|
|
1087
|
+
{
|
|
1088
|
+
msgpack_unpacked_destroy((msgpack_unpacked *)data);
|
|
1089
|
+
return Qnil;
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1046
1092
|
static void
|
|
1047
1093
|
rbtrace__receive(void *data)
|
|
1048
1094
|
{
|
|
@@ -1060,7 +1106,7 @@ rbtrace__receive(void *data)
|
|
|
1060
1106
|
int n = 0;
|
|
1061
1107
|
|
|
1062
1108
|
while (true) {
|
|
1063
|
-
|
|
1109
|
+
ssize_t ret = -1;
|
|
1064
1110
|
|
|
1065
1111
|
for (n=0; n<10 && ret==-1; n++)
|
|
1066
1112
|
ret = msgrcv(rbtracer.mqi_id, &msg, sizeof(msg)-sizeof(long), 0, IPC_NOWAIT);
|
|
@@ -1071,10 +1117,17 @@ rbtrace__receive(void *data)
|
|
|
1071
1117
|
msgpack_unpacked unpacked;
|
|
1072
1118
|
msgpack_unpacked_init(&unpacked);
|
|
1073
1119
|
|
|
1074
|
-
|
|
1075
|
-
if (
|
|
1120
|
+
msgpack_unpack_return unpack_result = msgpack_unpack_next(&unpacked, msg.buf, (size_t)ret, NULL);
|
|
1121
|
+
if (unpack_result != MSGPACK_UNPACK_SUCCESS &&
|
|
1122
|
+
unpack_result != MSGPACK_UNPACK_EXTRA_BYTES) {
|
|
1123
|
+
msgpack_unpacked_destroy(&unpacked);
|
|
1124
|
+
continue;
|
|
1125
|
+
}
|
|
1076
1126
|
|
|
1077
|
-
|
|
1127
|
+
rb_ensure(
|
|
1128
|
+
rbtrace__process_unpacked_event, (VALUE)&unpacked.data,
|
|
1129
|
+
rbtrace__destroy_unpacked, (VALUE)&unpacked
|
|
1130
|
+
);
|
|
1078
1131
|
}
|
|
1079
1132
|
}
|
|
1080
1133
|
}
|
|
@@ -1092,11 +1145,20 @@ rbtrace_gc_mark(void *ptr)
|
|
|
1092
1145
|
|
|
1093
1146
|
static VALUE gc_hook;
|
|
1094
1147
|
|
|
1095
|
-
#if defined(
|
|
1148
|
+
#if defined(HAVE_RB_POSTPONED_JOB_PREREGISTER) && defined(HAVE_RB_POSTPONED_JOB_TRIGGER)
|
|
1149
|
+
#define RBTRACE_USE_PREREGISTERED_POSTPONED_JOB 1
|
|
1150
|
+
static rb_postponed_job_handle_t rbtrace_postponed_job_handle = POSTPONED_JOB_HANDLE_INVALID;
|
|
1151
|
+
#endif
|
|
1152
|
+
|
|
1153
|
+
#if defined(RBTRACE_USE_PREREGISTERED_POSTPONED_JOB) || defined(HAVE_RB_POSTPONED_JOB_REGISTER_ONE) || !defined(RUBY_VM)
|
|
1096
1154
|
static void
|
|
1097
1155
|
sigurg(int signal)
|
|
1098
1156
|
{
|
|
1099
|
-
#if defined(
|
|
1157
|
+
#if defined(RBTRACE_USE_PREREGISTERED_POSTPONED_JOB)
|
|
1158
|
+
if (rbtrace_postponed_job_handle != POSTPONED_JOB_HANDLE_INVALID) {
|
|
1159
|
+
rb_postponed_job_trigger(rbtrace_postponed_job_handle);
|
|
1160
|
+
}
|
|
1161
|
+
#elif defined(HAVE_RB_POSTPONED_JOB_REGISTER_ONE)
|
|
1100
1162
|
rb_postponed_job_register_one(0, rbtrace__receive, 0);
|
|
1101
1163
|
#else
|
|
1102
1164
|
rbtrace__receive(0);
|
|
@@ -1104,10 +1166,10 @@ sigurg(int signal)
|
|
|
1104
1166
|
}
|
|
1105
1167
|
#endif
|
|
1106
1168
|
|
|
1107
|
-
#if
|
|
1169
|
+
#if defined(RUBY_VM) && (defined(RBTRACE_USE_PREREGISTERED_POSTPONED_JOB) || !defined(HAVE_RB_POSTPONED_JOB_REGISTER_ONE))
|
|
1108
1170
|
static VALUE signal_handler_proc;
|
|
1109
1171
|
static VALUE
|
|
1110
|
-
signal_handler_wrapper(
|
|
1172
|
+
signal_handler_wrapper(RB_BLOCK_CALL_FUNC_ARGLIST(arg, ctx))
|
|
1111
1173
|
{
|
|
1112
1174
|
static int in_signal_handler = 0;
|
|
1113
1175
|
if (in_signal_handler) return Qnil;
|
|
@@ -1118,6 +1180,14 @@ signal_handler_wrapper(VALUE arg, VALUE ctx)
|
|
|
1118
1180
|
|
|
1119
1181
|
return Qnil;
|
|
1120
1182
|
}
|
|
1183
|
+
|
|
1184
|
+
static void
|
|
1185
|
+
install_ruby_sigurg_handler(void)
|
|
1186
|
+
{
|
|
1187
|
+
signal_handler_proc = rb_proc_new(signal_handler_wrapper, Qnil);
|
|
1188
|
+
rb_global_variable(&signal_handler_proc);
|
|
1189
|
+
rb_funcall(Qnil, rb_intern("trap"), 2, rb_str_new_cstr("URG"), signal_handler_proc);
|
|
1190
|
+
}
|
|
1121
1191
|
#endif
|
|
1122
1192
|
|
|
1123
1193
|
static VALUE
|
|
@@ -1154,12 +1224,25 @@ Init_rbtrace()
|
|
|
1154
1224
|
gc_hook = TypedData_Wrap_Struct(rb_cObject, &rbtrace_type, NULL);
|
|
1155
1225
|
|
|
1156
1226
|
// catch signal telling us to read from the msgq
|
|
1157
|
-
#if defined(
|
|
1227
|
+
#if defined(RBTRACE_USE_PREREGISTERED_POSTPONED_JOB)
|
|
1228
|
+
rbtrace_postponed_job_handle = rb_postponed_job_preregister(0, rbtrace__receive, 0);
|
|
1229
|
+
if (rbtrace_postponed_job_handle == POSTPONED_JOB_HANDLE_INVALID) {
|
|
1230
|
+
|
|
1231
|
+
#ifdef RUBY_VM
|
|
1232
|
+
rb_warn("rbtrace: failed to preregister postponed job; falling back to Ruby SIGURG handler");
|
|
1233
|
+
install_ruby_sigurg_handler();
|
|
1234
|
+
#else
|
|
1235
|
+
rb_raise(rb_eRuntimeError, "rbtrace: failed to preregister postponed job");
|
|
1236
|
+
#endif
|
|
1237
|
+
|
|
1238
|
+
} else {
|
|
1239
|
+
signal(SIGURG, sigurg);
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
#elif defined(HAVE_RB_POSTPONED_JOB_REGISTER_ONE)
|
|
1158
1243
|
signal(SIGURG, sigurg);
|
|
1159
1244
|
#elif defined(RUBY_VM)
|
|
1160
|
-
|
|
1161
|
-
rb_global_variable(&signal_handler_proc);
|
|
1162
|
-
rb_funcall(Qnil, rb_intern("trap"), 2, rb_str_new_cstr("URG"), signal_handler_proc);
|
|
1245
|
+
install_ruby_sigurg_handler();
|
|
1163
1246
|
#else
|
|
1164
1247
|
signal(SIGURG, sigurg);
|
|
1165
1248
|
#endif
|
data/lib/rbtrace/cli.rb
CHANGED
|
@@ -243,7 +243,7 @@ EOS
|
|
|
243
243
|
ARGV.clear
|
|
244
244
|
end
|
|
245
245
|
|
|
246
|
-
unless %w[ fork eval interactive backtrace backtraces slow slowcpu firehose methods config gc memory heapdump].find{ |n| opts[:"#{n}_given"] }
|
|
246
|
+
unless %w[ fork eval interactive backtrace backtraces slow slowcpu firehose methods config gc memory heapdump shapesdump].find{ |n| opts[:"#{n}_given"] }
|
|
247
247
|
$stderr.puts "Error: --slow, --slowcpu, --gc, --firehose, --methods, --interactive, --backtraces, --backtrace, --memory, --heapdump, --shapesdump or --config required."
|
|
248
248
|
$stderr.puts "Try --help for help."
|
|
249
249
|
exit(-1)
|
|
@@ -505,6 +505,7 @@ EOS
|
|
|
505
505
|
tracer.eval(<<-RUBY)
|
|
506
506
|
Thread.new do
|
|
507
507
|
Thread.current.name = '__RBTrace__'
|
|
508
|
+
require 'objspace'
|
|
508
509
|
pid = ::Process.fork do
|
|
509
510
|
file = File.open('#{filename}.tmp', 'w')
|
|
510
511
|
ObjectSpace.dump_all(output: file)
|
|
@@ -531,6 +532,7 @@ EOS
|
|
|
531
532
|
tracer.eval(<<-RUBY)
|
|
532
533
|
Thread.new do
|
|
533
534
|
Thread.current.name = '__RBTrace__'
|
|
535
|
+
require 'objspace'
|
|
534
536
|
pid = ::Process.fork do
|
|
535
537
|
file = File.open('#{filename}.tmp', 'w')
|
|
536
538
|
ObjectSpace.dump_shapes(output: file)
|
data/lib/rbtrace/version.rb
CHANGED
data/server.rb
CHANGED
data/test.sh
CHANGED
|
@@ -15,10 +15,13 @@ export RUBYOPT="-I.:lib"
|
|
|
15
15
|
bundle exec ruby server.rb &
|
|
16
16
|
export PID=$!
|
|
17
17
|
|
|
18
|
-
trap cleanup INT TERM
|
|
18
|
+
trap cleanup EXIT INT TERM
|
|
19
19
|
cleanup() {
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
if [ -n "${PID:-}" ]; then
|
|
21
|
+
kill "$PID" 2>/dev/null || true
|
|
22
|
+
wait "$PID" 2>/dev/null || true
|
|
23
|
+
PID=
|
|
24
|
+
fi
|
|
22
25
|
}
|
|
23
26
|
|
|
24
27
|
trace() {
|
|
@@ -32,13 +35,84 @@ trace() {
|
|
|
32
35
|
echo
|
|
33
36
|
}
|
|
34
37
|
|
|
38
|
+
assert_trace() {
|
|
39
|
+
expected="$1"
|
|
40
|
+
shift
|
|
41
|
+
|
|
42
|
+
echo ------------------------------------------
|
|
43
|
+
echo ./bin/rbtrace -p $PID "$@"
|
|
44
|
+
echo ------------------------------------------
|
|
45
|
+
if ! output=$(bundle exec ./bin/rbtrace -p $PID "$@" 2>&1); then
|
|
46
|
+
echo "$output"
|
|
47
|
+
return 1
|
|
48
|
+
fi
|
|
49
|
+
echo "$output"
|
|
50
|
+
echo "$output" | grep -F "$expected" >/dev/null
|
|
51
|
+
echo
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
assert_dump() {
|
|
55
|
+
dump_type="$1"
|
|
56
|
+
dump=$(mktemp)
|
|
57
|
+
rm -f "$dump"
|
|
58
|
+
|
|
59
|
+
echo ------------------------------------------
|
|
60
|
+
echo ./bin/rbtrace -p $PID --"$dump_type"="$dump"
|
|
61
|
+
echo ------------------------------------------
|
|
62
|
+
if ! output=$(bundle exec ./bin/rbtrace -p $PID --"$dump_type"="$dump" 2>&1); then
|
|
63
|
+
echo "$output"
|
|
64
|
+
rm -f "$dump" "$dump.tmp"
|
|
65
|
+
return 1
|
|
66
|
+
fi
|
|
67
|
+
echo "$output"
|
|
68
|
+
|
|
69
|
+
tries=0
|
|
70
|
+
while [ "$tries" -lt 50 ] && [ ! -s "$dump" ]; do
|
|
71
|
+
sleep 0.1
|
|
72
|
+
tries=$((tries + 1))
|
|
73
|
+
done
|
|
74
|
+
|
|
75
|
+
if [ ! -s "$dump" ]; then
|
|
76
|
+
echo "Expected $dump_type to be written to $dump"
|
|
77
|
+
rm -f "$dump" "$dump.tmp"
|
|
78
|
+
return 1
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
rm -f "$dump" "$dump.tmp"
|
|
82
|
+
echo
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
assert_timed_trace() {
|
|
86
|
+
expected="$1"
|
|
87
|
+
shift
|
|
88
|
+
output=$(mktemp)
|
|
89
|
+
|
|
90
|
+
echo ------------------------------------------
|
|
91
|
+
echo ./bin/rbtrace -p $PID "$@"
|
|
92
|
+
echo ------------------------------------------
|
|
93
|
+
bundle exec ./bin/rbtrace -p $PID "$@" >"$output" 2>&1 &
|
|
94
|
+
tracer_pid=$!
|
|
95
|
+
sleep 2
|
|
96
|
+
kill "$tracer_pid" 2>/dev/null || true
|
|
97
|
+
wait "$tracer_pid" 2>/dev/null || true
|
|
98
|
+
cat "$output"
|
|
99
|
+
if ! grep -F "$expected" "$output" >/dev/null; then
|
|
100
|
+
rm -f "$output"
|
|
101
|
+
return 1
|
|
102
|
+
fi
|
|
103
|
+
rm -f "$output"
|
|
104
|
+
echo
|
|
105
|
+
}
|
|
106
|
+
|
|
35
107
|
trace -m Test.run --devmode
|
|
36
108
|
trace -m sleep
|
|
37
109
|
trace -m sleep Dir.chdir Dir.pwd Process.pid "String#gsub" "String#*"
|
|
38
110
|
trace -m "Kernel#"
|
|
39
111
|
trace -m "String#gsub(self,@test)" "String#*(self,__source__)" "String#multiply_vowels(self,self.length,num)"
|
|
40
|
-
|
|
41
|
-
|
|
112
|
+
assert_timed_trace 'String#upcase(self.class=String)' -m 'String#upcase(self.class)'
|
|
113
|
+
assert_trace '=> 2' -e 'p(1 + 1)'
|
|
114
|
+
assert_dump heapdump
|
|
115
|
+
assert_dump shapesdump
|
|
42
116
|
trace --gc --slow=200
|
|
43
117
|
trace --gc -m Dir.
|
|
44
118
|
trace --slow=250
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rbtrace
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Aman Gupta
|
|
@@ -139,7 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
139
139
|
- !ruby/object:Gem::Version
|
|
140
140
|
version: '0'
|
|
141
141
|
requirements: []
|
|
142
|
-
rubygems_version:
|
|
142
|
+
rubygems_version: 3.6.9
|
|
143
143
|
specification_version: 4
|
|
144
144
|
summary: 'rbtrace: like strace but for ruby code'
|
|
145
145
|
test_files: []
|