stack_trace 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ac9e909692657f9e1b0cd9fc6475faf494458954513aa2e659e9faeacfb3d51b
4
- data.tar.gz: d4819f5e40ef2d81cc5cc539247916ed16416eed9400f63007fe85edc8c9c4cf
3
+ metadata.gz: 3e528eba64406556bc7638531e10cd80b0aa0027649d1dfcd223f3e0171e0c47
4
+ data.tar.gz: c1a935f65476ba84ef18bed8873f82f54d39f3ae6fc384ce13571039c6b3571a
5
5
  SHA512:
6
- metadata.gz: 072443043f5910dfd02ded927653a23abacefede4f17fd87155521275818b0b90aa769544c30e9f06b5c46c24193e9bac12f711ae39c4f887340d435402f40c2
7
- data.tar.gz: d3a5c0ae3803776ea0ad504c825c75ca0d9a70d5153a22133f809633631f824a7540fe7dd72c76c9e4eece214bb578d04765445f39089adadc6076abbe7af10a
6
+ metadata.gz: d3adb5c1b7a759a18e0baad12bbefa11f27703396ae833ac887cf40bac0710268b9cda7e3e157c3df9ae313a1388e6222d7c7b50f02ac476b34d6f7d1941e022
7
+ data.tar.gz: b5cc60e857c0c28c9f0ee2b0d2cd6b64641eb97ad1d62e100f694e1ce0bbcb13f438ebb576ccba6f42536d024fd5d38b8da7305f18a273f126b2516165366756
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- stack_trace (0.4.0)
4
+ stack_trace (0.5.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -7,14 +7,45 @@
7
7
  #include "utils.h"
8
8
  #include "configuration.h"
9
9
 
10
- VALUE extract_arguments(VALUE tp_val) {
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 arguments = rb_funcall(extractor_class, rb_intern("extract"), 1, tp_val);
15
- rb_gc_register_address(&arguments);
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
- return arguments;
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 = Qundef;
50
- event.arguments = Qundef;
80
+ event.return_value = NULL;
81
+ event.arguments = NULL;
51
82
  event.at = get_monotonic_m_secs();
52
83
 
53
- if(event.event == RUBY_EVENT_RAISE)
54
- event.raised_exception = rb_tracearg_raised_exception(trace_arg);
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.arguments = extract_arguments(tp_val);
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
- event.return_value = rb_tracearg_return_value(trace_arg);
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
  }
@@ -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 = Qundef;
14
+ span->return_value = NULL;
15
15
  span->arguments = event->arguments;
16
- span->exception = Qundef;
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 != Qundef)
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->arguments != Qundef) {
89
- rb_gc_unregister_address(&span->arguments);
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
- rb_hash_aset(hash, rb_str_new2("arguments"), span->arguments);
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;
@@ -0,0 +1,12 @@
1
+ #include <ruby.h>
2
+
3
+ #ifndef ARGUMENT_H
4
+ #define ARGUMENT_H
5
+
6
+ typedef struct ArgumentS Argument;
7
+
8
+ struct ArgumentS {
9
+ VALUE key;
10
+ char *value;
11
+ };
12
+ #endif
@@ -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
- VALUE raised_exception;
26
- VALUE return_value;
27
- VALUE arguments;
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
- VALUE exception;
16
- VALUE return_value;
17
- VALUE arguments;
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).st_name
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  class FalseClass
4
4
  def st_name
5
- self
5
+ inspect
6
6
  end
7
7
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  class NilClass
4
4
  def st_name
5
- self
5
+ inspect
6
6
  end
7
7
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  class Numeric
4
4
  def st_name
5
- self
5
+ inspect
6
6
  end
7
7
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  class TrueClass
4
4
  def st_name
5
- self
5
+ inspect
6
6
  end
7
7
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module StackTrace
4
- VERSION = "0.4.0"
4
+ VERSION = "0.5.0"
5
5
  end
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.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