stack_trace 0.3.0 → 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/Gemfile.lock +1 -1
- data/Rakefile +1 -1
- data/ext/stack_trace/event_producer.c +53 -12
- data/ext/stack_trace/span.c +43 -11
- data/ext/stack_trace/trace.c +8 -3
- data/ext/stack_trace/types/argument.h +12 -0
- data/ext/stack_trace/types/event.h +7 -4
- data/ext/stack_trace/types/span.h +7 -4
- data/lib/stack_trace/argument_extractor.rb +2 -2
- data/lib/stack_trace/patch/false_class.rb +1 -1
- data/lib/stack_trace/patch/nil_class.rb +1 -1
- data/lib/stack_trace/patch/numeric.rb +1 -1
- data/lib/stack_trace/patch/true_class.rb +1 -1
- data/lib/stack_trace/version.rb +1 -1
- data/lib/stack_trace.rb +2 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e528eba64406556bc7638531e10cd80b0aa0027649d1dfcd223f3e0171e0c47
|
4
|
+
data.tar.gz: c1a935f65476ba84ef18bed8873f82f54d39f3ae6fc384ce13571039c6b3571a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d3adb5c1b7a759a18e0baad12bbefa11f27703396ae833ac887cf40bac0710268b9cda7e3e157c3df9ae313a1388e6222d7c7b50f02ac476b34d6f7d1941e022
|
7
|
+
data.tar.gz: b5cc60e857c0c28c9f0ee2b0d2cd6b64641eb97ad1d62e100f694e1ce0bbcb13f438ebb576ccba6f42536d024fd5d38b8da7305f18a273f126b2516165366756
|
data/Gemfile.lock
CHANGED
data/Rakefile
CHANGED
@@ -7,14 +7,45 @@
|
|
7
7
|
#include "utils.h"
|
8
8
|
#include "configuration.h"
|
9
9
|
|
10
|
-
|
10
|
+
struct MemoS {
|
11
|
+
int i;
|
12
|
+
Argument *arguments;
|
13
|
+
};
|
14
|
+
|
15
|
+
static void copy_str(char **target, VALUE string) {
|
16
|
+
*target = malloc(sizeof(char) * RSTRING_LEN(string) + 1);
|
17
|
+
|
18
|
+
memcpy(*target, RSTRING_PTR(string), RSTRING_LEN(string));
|
19
|
+
}
|
20
|
+
|
21
|
+
static int extract_kv(VALUE key, VALUE value, VALUE data) {
|
22
|
+
struct MemoS *memo = (struct MemoS *)data;
|
23
|
+
|
24
|
+
memo->arguments[memo->i].key = key;
|
25
|
+
copy_str(&memo->arguments[memo->i].value, value);
|
26
|
+
|
27
|
+
memo->i++;
|
28
|
+
|
29
|
+
return ST_CONTINUE;
|
30
|
+
}
|
31
|
+
|
32
|
+
static void extract_arguments(Event *event, VALUE tp_val) {
|
11
33
|
VALUE main_module = rb_const_get(rb_cObject, rb_intern("StackTrace"));
|
12
34
|
VALUE extractor_class = rb_const_get(main_module, rb_intern("ArgumentExtractor"));
|
13
35
|
|
14
|
-
VALUE
|
15
|
-
|
36
|
+
VALUE arguments_hash = rb_funcall(extractor_class, rb_intern("extract"), 1, tp_val);
|
37
|
+
VALUE hash_size = rb_funcall(arguments_hash, rb_intern("size"), 0);
|
16
38
|
|
17
|
-
|
39
|
+
int arguments_count = FIX2INT(hash_size);
|
40
|
+
|
41
|
+
if(arguments_count == 0) return;
|
42
|
+
|
43
|
+
event->arguments_count = arguments_count;
|
44
|
+
event->arguments = malloc(sizeof(Argument) * arguments_count);
|
45
|
+
|
46
|
+
struct MemoS memo = { 0, event->arguments };
|
47
|
+
|
48
|
+
rb_hash_foreach(arguments_hash, extract_kv, (VALUE)&memo);
|
18
49
|
}
|
19
50
|
|
20
51
|
void create_event(VALUE tp_val, void *_data) {
|
@@ -25,6 +56,7 @@ void create_event(VALUE tp_val, void *_data) {
|
|
25
56
|
|
26
57
|
VALUE klass = rb_tracearg_defined_class(trace_arg);
|
27
58
|
VALUE self = rb_tracearg_self(trace_arg);
|
59
|
+
VALUE receiver = rb_funcall(self, rb_intern("st_name"), 0);
|
28
60
|
VALUE method = rb_tracearg_method_id(trace_arg);
|
29
61
|
VALUE self_klass;
|
30
62
|
|
@@ -43,23 +75,32 @@ void create_event(VALUE tp_val, void *_data) {
|
|
43
75
|
event.event = rb_tracearg_event_flag(trace_arg);
|
44
76
|
event.klass = klass;
|
45
77
|
event.self_klass = self_klass;
|
46
|
-
event.receiver = rb_funcall(self, rb_intern("st_name"), 0);
|
47
78
|
event.method = method;
|
48
79
|
event.for_singleton = for_singleton;
|
49
|
-
event.return_value =
|
50
|
-
event.arguments =
|
80
|
+
event.return_value = NULL;
|
81
|
+
event.arguments = NULL;
|
51
82
|
event.at = get_monotonic_m_secs();
|
52
83
|
|
53
|
-
|
54
|
-
|
84
|
+
copy_str(&event.receiver, receiver);
|
85
|
+
|
86
|
+
if(event.event == RUBY_EVENT_RAISE) {
|
87
|
+
VALUE exception = rb_tracearg_raised_exception(trace_arg);
|
88
|
+
VALUE exception_to_s = rb_funcall(exception, rb_intern("to_s"), 0);
|
89
|
+
|
90
|
+
copy_str(&event.raised_exception, exception_to_s);
|
91
|
+
}
|
55
92
|
|
56
93
|
if(RTEST(get_inspect_arguments()) &&
|
57
94
|
(event.event == RUBY_EVENT_CALL || event.event == RUBY_EVENT_C_CALL || event.event == RUBY_EVENT_B_CALL))
|
58
|
-
event
|
95
|
+
extract_arguments(&event, tp_val);
|
59
96
|
|
60
97
|
if(RTEST(get_inspect_return_values()) &&
|
61
|
-
(event.event == RUBY_EVENT_RETURN || event.event == RUBY_EVENT_C_RETURN || event.event == RUBY_EVENT_B_RETURN))
|
62
|
-
|
98
|
+
(event.event == RUBY_EVENT_RETURN || event.event == RUBY_EVENT_C_RETURN || event.event == RUBY_EVENT_B_RETURN)) {
|
99
|
+
VALUE return_value = rb_tracearg_return_value(trace_arg);
|
100
|
+
VALUE return_value_st_name = rb_funcall(return_value, rb_intern("st_name"), 0);
|
101
|
+
|
102
|
+
copy_str(&event.return_value, return_value_st_name);
|
103
|
+
}
|
63
104
|
|
64
105
|
produce_event(event);
|
65
106
|
}
|
data/ext/stack_trace/span.c
CHANGED
@@ -11,9 +11,10 @@ Span *create_span(Event *event) {
|
|
11
11
|
span->klass = event->klass;
|
12
12
|
span->self_klass = event->self_klass;
|
13
13
|
span->method = event->method;
|
14
|
-
span->return_value =
|
14
|
+
span->return_value = NULL;
|
15
15
|
span->arguments = event->arguments;
|
16
|
-
span->
|
16
|
+
span->arguments_count = event->arguments_count;
|
17
|
+
span->exception = NULL;
|
17
18
|
span->children_count = 0;
|
18
19
|
span->singleton = event->for_singleton ? Qtrue : Qfalse;
|
19
20
|
|
@@ -48,6 +49,16 @@ Span *close_span(Span *span, Event *event) {
|
|
48
49
|
return span->caller;
|
49
50
|
}
|
50
51
|
|
52
|
+
static void free_arguments(Span *span) {
|
53
|
+
int i;
|
54
|
+
|
55
|
+
for(i = 0; i < span->arguments_count; i++) {
|
56
|
+
free(span->arguments[i].value);
|
57
|
+
}
|
58
|
+
|
59
|
+
free(span->arguments);
|
60
|
+
}
|
61
|
+
|
51
62
|
|
52
63
|
// Deallocate the memory occupied by span
|
53
64
|
// and its children.
|
@@ -61,6 +72,18 @@ void free_span(Span *span) {
|
|
61
72
|
free(span->children);
|
62
73
|
}
|
63
74
|
|
75
|
+
if(span->receiver != NULL)
|
76
|
+
free(span->receiver);
|
77
|
+
|
78
|
+
if(span->return_value != NULL)
|
79
|
+
free(span->return_value);
|
80
|
+
|
81
|
+
if(span->arguments != NULL)
|
82
|
+
free_arguments(span);
|
83
|
+
|
84
|
+
if(span->exception != NULL)
|
85
|
+
free(span->exception);
|
86
|
+
|
64
87
|
free(span);
|
65
88
|
}
|
66
89
|
|
@@ -68,10 +91,21 @@ int duration_of(Span *span) {
|
|
68
91
|
return (int)(span->finished_at - span->started_at);
|
69
92
|
}
|
70
93
|
|
94
|
+
VALUE serialize_arguments(Argument *arguments, int count) {
|
95
|
+
VALUE hash = rb_hash_new();
|
96
|
+
int i;
|
97
|
+
|
98
|
+
for(i = 0; i < count; i++) {
|
99
|
+
rb_hash_aset(hash, arguments[i].key, rb_str_new_cstr(arguments[i].value));
|
100
|
+
}
|
101
|
+
|
102
|
+
return hash;
|
103
|
+
}
|
104
|
+
|
71
105
|
VALUE span_to_ruby_hash(Span *span) {
|
72
106
|
VALUE hash = rb_hash_new();
|
73
107
|
|
74
|
-
rb_hash_aset(hash, rb_str_new2("receiver"), span->receiver);
|
108
|
+
rb_hash_aset(hash, rb_str_new2("receiver"), rb_str_new_cstr(span->receiver));
|
75
109
|
rb_hash_aset(hash, rb_str_new2("defined_class"), span->klass);
|
76
110
|
rb_hash_aset(hash, rb_str_new2("self_class"), span->self_klass);
|
77
111
|
rb_hash_aset(hash, rb_str_new2("method_name"), span->method);
|
@@ -79,16 +113,14 @@ VALUE span_to_ruby_hash(Span *span) {
|
|
79
113
|
rb_hash_aset(hash, rb_str_new2("duration"), INT2FIX(duration_of(span)));
|
80
114
|
rb_hash_aset(hash, rb_str_new2("spans"), to_ruby_array(span->children_count, span->children));
|
81
115
|
|
82
|
-
if(span->exception !=
|
83
|
-
rb_hash_aset(hash, rb_str_new2("exception"), span->exception);
|
84
|
-
|
85
|
-
if(span->return_value != Qundef)
|
86
|
-
rb_hash_aset(hash, rb_str_new2("return_value"), rb_funcall(span->return_value, rb_intern("st_name"), 0));
|
116
|
+
if(span->exception != NULL)
|
117
|
+
rb_hash_aset(hash, rb_str_new2("exception"), rb_str_new_cstr(span->exception));
|
87
118
|
|
88
|
-
if(span->
|
89
|
-
|
119
|
+
if(span->return_value != NULL)
|
120
|
+
rb_hash_aset(hash, rb_str_new2("return_value"), rb_str_new_cstr(span->return_value));
|
90
121
|
|
91
|
-
|
122
|
+
if(span->arguments != NULL) {
|
123
|
+
rb_hash_aset(hash, rb_str_new2("arguments"), serialize_arguments(span->arguments, span->arguments_count));
|
92
124
|
}
|
93
125
|
|
94
126
|
return hash;
|
data/ext/stack_trace/trace.c
CHANGED
@@ -20,7 +20,8 @@ void free_trace(Trace *trace) {
|
|
20
20
|
}
|
21
21
|
|
22
22
|
void process_obsolote_event(Event *event) {
|
23
|
-
//
|
23
|
+
// Free this trace as there is no reference to it anymore!
|
24
|
+
free_trace(event->trace);
|
24
25
|
}
|
25
26
|
|
26
27
|
void set_check_proc(VALUE proc) {
|
@@ -118,10 +119,14 @@ VALUE to_ruby_hash(Trace *trace) {
|
|
118
119
|
}
|
119
120
|
|
120
121
|
VALUE rb_get_current_trace(VALUE _self) {
|
122
|
+
VALUE main_module = rb_const_get(rb_cObject, rb_intern("StackTrace"));
|
123
|
+
VALUE tracePoint = rb_iv_get(main_module, "@trace_point");
|
124
|
+
VALUE is_tracepoint_enabled = rb_funcall(tracePoint, rb_intern("enabled?"), 0);
|
125
|
+
|
126
|
+
if(RTEST(is_tracepoint_enabled)) rb_raise(rb_eRuntimeError, "Trace is active!");
|
127
|
+
|
121
128
|
Trace *trace = get_current_trace_without_gvl();
|
122
129
|
VALUE ruby_hash = to_ruby_hash(trace);
|
123
130
|
|
124
|
-
free_trace(trace);
|
125
|
-
|
126
131
|
return ruby_hash;
|
127
132
|
}
|
@@ -4,6 +4,8 @@
|
|
4
4
|
#include <stdbool.h>
|
5
5
|
#include <sys/time.h>
|
6
6
|
|
7
|
+
#include "types/argument.h"
|
8
|
+
|
7
9
|
#ifndef EVENT_H
|
8
10
|
#define EVENT_H
|
9
11
|
|
@@ -18,13 +20,14 @@
|
|
18
20
|
VALUE tp_val;
|
19
21
|
rb_event_flag_t event;
|
20
22
|
rb_trace_arg_t *trace_arg;
|
23
|
+
char *receiver;
|
21
24
|
VALUE klass;
|
22
25
|
VALUE self_klass;
|
23
|
-
VALUE receiver;
|
24
26
|
VALUE method;
|
25
|
-
|
26
|
-
|
27
|
-
|
27
|
+
char *return_value;
|
28
|
+
Argument *arguments;
|
29
|
+
int arguments_count;
|
30
|
+
char *raised_exception;
|
28
31
|
bool for_singleton;
|
29
32
|
long int at;
|
30
33
|
};
|
@@ -1,3 +1,5 @@
|
|
1
|
+
#include "types/argument.h"
|
2
|
+
|
1
3
|
#ifndef SPAN_H
|
2
4
|
#define SPAN_H
|
3
5
|
|
@@ -7,14 +9,15 @@
|
|
7
9
|
long int started_at;
|
8
10
|
long int finished_at;
|
9
11
|
|
12
|
+
char *receiver;
|
10
13
|
VALUE klass;
|
11
14
|
VALUE self_klass;
|
12
|
-
VALUE receiver;
|
13
15
|
VALUE method;
|
14
16
|
VALUE singleton;
|
15
|
-
|
16
|
-
|
17
|
-
|
17
|
+
char *return_value;
|
18
|
+
Argument *arguments;
|
19
|
+
int arguments_count;
|
20
|
+
char *exception;
|
18
21
|
Span *caller;
|
19
22
|
int children_count;
|
20
23
|
Span **children;
|
@@ -7,14 +7,14 @@ module StackTrace
|
|
7
7
|
trace_point.parameters
|
8
8
|
.map(&:last)
|
9
9
|
.each_with_object({}) do |parameter, memo|
|
10
|
-
memo[parameter] = extract_argument(trace_point, parameter)
|
10
|
+
memo[parameter] = extract_argument(trace_point, parameter).st_name
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
14
|
private
|
15
15
|
|
16
16
|
def extract_argument(trace_point, parameter)
|
17
|
-
trace_point.binding.eval(parameter.to_s)
|
17
|
+
trace_point.binding.eval(parameter.to_s)
|
18
18
|
rescue Exception # SyntaxError can happen as we are calling `eval` here!
|
19
19
|
end
|
20
20
|
end
|
data/lib/stack_trace/version.rb
CHANGED
data/lib/stack_trace.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stack_trace
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mehmet Emin INAC
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-04-
|
11
|
+
date: 2023-04-06 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: StackTrace
|
14
14
|
email:
|
@@ -44,6 +44,7 @@ files:
|
|
44
44
|
- ext/stack_trace/stack_trace.c
|
45
45
|
- ext/stack_trace/trace.c
|
46
46
|
- ext/stack_trace/trace.h
|
47
|
+
- ext/stack_trace/types/argument.h
|
47
48
|
- ext/stack_trace/types/event.h
|
48
49
|
- ext/stack_trace/types/span.h
|
49
50
|
- ext/stack_trace/types/trace.h
|