stack_trace 0.4.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/ext/stack_trace/event_producer.c +53 -12
- data/ext/stack_trace/span.c +43 -11
- 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
- metadata +2 -1
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
@@ -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;
|
@@ -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
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
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
|
@@ -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
|