ruby-static-tracing 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +5 -5
  2. data/ext/ruby-static-tracing/darwin/provider.c +128 -0
  3. data/ext/ruby-static-tracing/darwin/provider.h +62 -0
  4. data/ext/ruby-static-tracing/darwin/ruby_static_tracing.c +48 -0
  5. data/ext/ruby-static-tracing/darwin/tracepoint.c +231 -0
  6. data/ext/ruby-static-tracing/darwin/tracepoint.h +52 -0
  7. data/ext/ruby-static-tracing/extconf.rb +45 -5
  8. data/ext/ruby-static-tracing/{linux → include}/ruby_static_tracing.h +3 -6
  9. data/ext/ruby-static-tracing/lib/deps-extconf.rb +47 -0
  10. data/ext/ruby-static-tracing/lib/libstapsdt/example/demo.c +42 -0
  11. data/ext/ruby-static-tracing/lib/libstapsdt/src/dynamic-symbols.c +41 -0
  12. data/ext/ruby-static-tracing/lib/libstapsdt/src/dynamic-symbols.h +34 -0
  13. data/ext/ruby-static-tracing/lib/libstapsdt/src/errors.c +30 -0
  14. data/ext/ruby-static-tracing/lib/libstapsdt/src/errors.h +8 -0
  15. data/ext/ruby-static-tracing/lib/libstapsdt/src/hash-table.c +27 -0
  16. data/ext/ruby-static-tracing/lib/libstapsdt/src/hash-table.h +3 -0
  17. data/ext/ruby-static-tracing/lib/libstapsdt/src/libstapsdt.c +208 -0
  18. data/ext/ruby-static-tracing/lib/libstapsdt/src/libstapsdt.h +66 -0
  19. data/ext/ruby-static-tracing/lib/libstapsdt/src/sdtnote.c +176 -0
  20. data/ext/ruby-static-tracing/lib/libstapsdt/src/sdtnote.h +46 -0
  21. data/ext/ruby-static-tracing/lib/libstapsdt/src/section.c +30 -0
  22. data/ext/ruby-static-tracing/lib/libstapsdt/src/section.h +21 -0
  23. data/ext/ruby-static-tracing/lib/libstapsdt/src/shared-lib.c +563 -0
  24. data/ext/ruby-static-tracing/lib/libstapsdt/src/shared-lib.h +46 -0
  25. data/ext/ruby-static-tracing/lib/libstapsdt/src/string-table.c +67 -0
  26. data/ext/ruby-static-tracing/lib/libstapsdt/src/string-table.h +28 -0
  27. data/ext/ruby-static-tracing/lib/libstapsdt/src/util.c +12 -0
  28. data/ext/ruby-static-tracing/lib/libstapsdt/src/util.h +6 -0
  29. data/ext/ruby-static-tracing/lib/libstapsdt/tests/test-errors.c +77 -0
  30. data/ext/ruby-static-tracing/lib/libstapsdt/tests/test-memory-leaks.c +25 -0
  31. data/ext/ruby-static-tracing/lib/post-extconf.rb +37 -0
  32. data/ext/ruby-static-tracing/linux/provider.c +1 -1
  33. data/ext/ruby-static-tracing/linux/provider.h +2 -7
  34. data/ext/ruby-static-tracing/linux/ruby_static_tracing.c +4 -3
  35. data/ext/ruby-static-tracing/linux/tracepoint.c +0 -1
  36. data/ext/ruby-static-tracing/linux/tracepoint.h +1 -5
  37. data/ext/ruby-static-tracing/linux/types.h +11 -0
  38. data/lib/ruby-static-tracing.rb +5 -7
  39. data/lib/ruby-static-tracing/platform.rb +48 -0
  40. data/lib/ruby-static-tracing/provider.rb +18 -1
  41. data/lib/ruby-static-tracing/tracepoint.rb +15 -3
  42. data/lib/ruby-static-tracing/tracepoints.rb +36 -0
  43. data/lib/ruby-static-tracing/tracers.rb +1 -0
  44. data/lib/ruby-static-tracing/tracers/base.rb +68 -0
  45. data/lib/ruby-static-tracing/tracers/helpers.rb +17 -0
  46. data/lib/ruby-static-tracing/tracers/latency_tracer.rb +13 -60
  47. data/lib/ruby-static-tracing/tracers/stack_tracer.rb +19 -0
  48. data/lib/ruby-static-tracing/version.rb +1 -1
  49. metadata +41 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 394cdc6b04834088de888916e5ebcfb9481a8c75
4
- data.tar.gz: 744d75e5564b7e3e0021d64cf2e141b97090e999
2
+ SHA256:
3
+ metadata.gz: f901c3dd17e5873073d011db778b9ef22983fa9c6225be6b90abc226e223d1ff
4
+ data.tar.gz: 525513e06cc54471b1f2c09f3c8d82e4ba47fac56b89e3d68a80ac8747dd4d3f
5
5
  SHA512:
6
- metadata.gz: e23b757367de4ddb676dbaac7da56d0d4ccb70e0bc7d4762df30c66221d0c5ec9cd2a2e2cc448c11c3bc11607d2e52b76d9eae451ed40a49883abf4cc478f2ff
7
- data.tar.gz: 8ab4b39ffc8e234d9570bfc3cc1b62a019c3cbe7b1a4bcb595a7d09e01e9acd5280d9e5b97d6c597d9bab85970395f85d1183a50b0290e61d59e5d29d13132ca
6
+ metadata.gz: 987a3b0391cdbf22db11795cf5d53f5ebe8d71bf9962969a73fbf952dd455ff4656c3b4ca88dc01d8418b4278f84f83a10b8943be7aaf0da1a0329b861aa2015
7
+ data.tar.gz: f14b0d94b0bfce0ea110a379cb1954a51c498fd5b4370ecc7bbee5fecf40c11a66bf725a28a79e690a1a7119f3d5d31ac9691e2c83ecaa17391003383328c3e9
@@ -0,0 +1,128 @@
1
+ #include "provider.h"
2
+
3
+ static const rb_data_type_t
4
+ static_tracing_provider_type;
5
+
6
+ // Forward decls
7
+ static const char*
8
+ check_name_arg(VALUE name);
9
+
10
+ /*
11
+ Wraps usdt_create_provider from libusdt.h
12
+ */
13
+ VALUE
14
+ provider_initialize(VALUE self, VALUE name)
15
+ {
16
+ const char *c_name_str = NULL;
17
+ static_tracing_provider_t *res = NULL;
18
+
19
+ c_name_str = check_name_arg(name);
20
+
21
+ TypedData_Get_Struct(self, static_tracing_provider_t, &static_tracing_provider_type, res);
22
+ res->usdt_provider = usdt_create_provider(c_name_str, c_name_str); // FIXME make module from name and just prepend "_module_"
23
+ return self;
24
+ }
25
+
26
+ // // Internal function used to register a tracepoint against a provider instance
27
+ int
28
+ provider_add_tracepoint_internal(VALUE self, usdt_probedef_t *probedef)
29
+ {
30
+ static_tracing_provider_t *res = NULL;
31
+ TypedData_Get_Struct(self, static_tracing_provider_t, &static_tracing_provider_type, res);
32
+ return usdt_provider_add_probe(res->usdt_provider, probedef) == 0 ? Qtrue : Qfalse;
33
+ }
34
+
35
+ /*
36
+ Wraps usdt_provider_enable from libusdt.h
37
+ */
38
+ VALUE
39
+ provider_enable(VALUE self)
40
+ {
41
+ static_tracing_provider_t *res = NULL;
42
+ TypedData_Get_Struct(self, static_tracing_provider_t, &static_tracing_provider_type, res);
43
+ return usdt_provider_enable(res->usdt_provider) == 0 ? Qtrue : Qfalse;
44
+ }
45
+
46
+ /*
47
+ Wraps usdt_provider_disable from libusdt.h
48
+ */
49
+ VALUE
50
+ provider_disable(VALUE self)
51
+ {
52
+ static_tracing_provider_t *res = NULL;
53
+ TypedData_Get_Struct(self, static_tracing_provider_t, &static_tracing_provider_type, res);
54
+ return usdt_provider_disable(res->usdt_provider) == 0 ? Qtrue : Qfalse;
55
+ }
56
+
57
+ /*
58
+ Wraps usdt_provider_free from libusdt.h
59
+ */
60
+ VALUE
61
+ provider_destroy(VALUE self)
62
+ {
63
+ static_tracing_provider_t *res = NULL;
64
+ TypedData_Get_Struct(self, static_tracing_provider_t, &static_tracing_provider_type, res);
65
+ usdt_provider_free(res->usdt_provider);
66
+ return Qnil;
67
+ }
68
+
69
+ // Allocate a static_tracing_provider_type struct for ruby memory management
70
+ VALUE
71
+ static_tracing_provider_alloc(VALUE klass)
72
+ {
73
+ static_tracing_provider_t *res;
74
+ VALUE obj = TypedData_Make_Struct(klass, static_tracing_provider_t, &static_tracing_provider_type, res);
75
+ return obj;
76
+ }
77
+
78
+
79
+ static const char*
80
+ check_name_arg(VALUE name)
81
+ {
82
+ const char *c_name_str = NULL;
83
+
84
+ if (TYPE(name) != T_SYMBOL && TYPE(name) != T_STRING) {
85
+ rb_raise(rb_eTypeError, "name must be a symbol or string");
86
+ }
87
+ if (TYPE(name) == T_SYMBOL) {
88
+ c_name_str = rb_id2name(rb_to_id(name));
89
+ } else if (TYPE(name) == T_STRING) {
90
+ c_name_str = RSTRING_PTR(name);
91
+ }
92
+
93
+ return c_name_str;
94
+ }
95
+
96
+ static inline void
97
+ static_tracing_provider_mark(void *ptr)
98
+ {
99
+ /* noop */
100
+ }
101
+
102
+ static inline void
103
+ static_tracing_provider_free(void *ptr)
104
+ {
105
+ static_tracing_provider_t *res = (static_tracing_provider_t *) ptr;
106
+ //if (res->name) {
107
+ // free(res->name);
108
+ // res->name = NULL;
109
+ //}
110
+ xfree(res);
111
+ }
112
+
113
+ static inline size_t
114
+ static_tracing_provider_memsize(const void *ptr)
115
+ {
116
+ return sizeof(static_tracing_provider_t);
117
+ }
118
+
119
+ static const rb_data_type_t
120
+ static_tracing_provider_type = {
121
+ "static_tracing_provider",
122
+ {
123
+ static_tracing_provider_mark,
124
+ static_tracing_provider_free,
125
+ static_tracing_provider_memsize
126
+ },
127
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
128
+ };
@@ -0,0 +1,62 @@
1
+ #ifndef STATIC_TRACING_PROVIDER_H
2
+ #define STATIC_TRACING_PROVIDER_H
3
+
4
+ #include "usdt.h"
5
+
6
+ #include "ruby_static_tracing.h"
7
+ #include "tracepoint.h"
8
+
9
+ typedef struct {
10
+ char *name;
11
+ usdt_provider_t *usdt_provider;
12
+ } static_tracing_provider_t;
13
+
14
+ /*
15
+ * call-seq:
16
+ * StaticTracing::Provider.new(id) -> provider
17
+ *
18
+ * Creates a new Provider.
19
+ */
20
+ VALUE
21
+ provider_initialize(VALUE self, VALUE id);
22
+
23
+ /*
24
+ * call-seq:
25
+ * provider.enable() -> true
26
+ *
27
+ * Enable this provider
28
+ *
29
+ * Return true if the enable operation succeeded
30
+ */
31
+ VALUE
32
+ provider_enable(VALUE self);
33
+
34
+ /*
35
+ * call-seq:
36
+ * provider.disable() -> true
37
+ *
38
+ * Disable this provider
39
+ *
40
+ * Return true if the disable operation succeeded
41
+ */
42
+ VALUE
43
+ provider_disable(VALUE self);
44
+ /*
45
+ * call-seq:
46
+ * provider.destroy() -> true
47
+ *
48
+ * Destroys this provider.
49
+ *
50
+ * Return true if the destory operation succeeded
51
+ */
52
+ VALUE
53
+ provider_destroy(VALUE self);
54
+
55
+ // Allocate a static_tracing_provider_type struct for ruby memory management
56
+ VALUE
57
+ static_tracing_provider_alloc(VALUE klass);
58
+
59
+ int
60
+ provider_add_tracepoint_internal(VALUE self, usdt_probedef_t* probedef);
61
+
62
+ #endif //STATIC_TRACING_PROVIDER_H
@@ -0,0 +1,48 @@
1
+ #include "ruby_static_tracing.h"
2
+
3
+ VALUE eUSDT, eInternal;
4
+
5
+ void Init_ruby_static_tracing()
6
+ {
7
+ VALUE cStaticTracing, cProvider, cTracepoint;
8
+
9
+ cStaticTracing = rb_const_get(rb_cObject, rb_intern("StaticTracing"));
10
+
11
+ /*
12
+ * Document-class: StaticTracing::Provider
13
+ *
14
+ * Provider is the wrapper around libstapsdt
15
+ */
16
+ cProvider = rb_const_get(cStaticTracing, rb_intern("Provider"));
17
+
18
+ /*
19
+ * Document-class: Statictracing::Tracepoint
20
+ *
21
+ * A Tracepoint is a wrapper around an SDTProbe
22
+ */
23
+ cTracepoint = rb_const_get(cStaticTracing, rb_intern("Tracepoint"));
24
+
25
+ /* Document-class: StaticTracing::SyscallError
26
+ *
27
+ * Represents failures to fire a tracepoint or register a provider
28
+ */
29
+ eUSDT = rb_const_get(cStaticTracing, rb_intern("USDTError"));
30
+
31
+ /* Document-class: StaticTracing::InternalError
32
+ *
33
+ * An internal StaticTracing error. These errors may constitute bugs.
34
+ */
35
+ eInternal = rb_const_get(cStaticTracing, rb_intern("InternalError"));
36
+
37
+ rb_define_alloc_func(cProvider, static_tracing_provider_alloc);
38
+ rb_define_method(cProvider, "provider_initialize", provider_initialize, 1);
39
+ rb_define_method(cProvider, "enable", provider_enable, 0);
40
+ rb_define_method(cProvider, "disable", provider_disable, 0);
41
+ rb_define_method(cProvider, "destroy", provider_destroy, 0);
42
+
43
+ rb_define_alloc_func(cTracepoint, static_tracing_tracepoint_alloc);
44
+ rb_define_method(cTracepoint, "tracepoint_initialize", tracepoint_initialize, 3);
45
+ rb_define_method(cTracepoint, "_fire_tracepoint", tracepoint_fire, 1);
46
+ rb_define_method(cTracepoint, "enabled?", tracepoint_enabled, 0);
47
+ }
48
+
@@ -0,0 +1,231 @@
1
+ #include "tracepoint.h"
2
+
3
+ static const rb_data_type_t
4
+ static_tracing_tracepoint_type;
5
+
6
+ static const char*
7
+ check_name_arg(VALUE provider);
8
+
9
+ static const char*
10
+ check_provider_arg(VALUE provider);
11
+
12
+ static char
13
+ **check_vargs(int *argc, VALUE vargs);
14
+
15
+ static void
16
+ **check_fire_args(int *argc, VALUE vargs);
17
+
18
+ VALUE
19
+ tracepoint_initialize(VALUE self, VALUE provider, VALUE name, VALUE vargs)
20
+ {
21
+ VALUE cStaticTracing, cProvider, cProviderInst;
22
+ static_tracing_tracepoint_t *tracepoint = NULL;
23
+ const char *c_name_str = NULL;
24
+ int argc = 0;
25
+
26
+ c_name_str = check_name_arg(name);
27
+ check_provider_arg(provider); // FIXME should only accept string
28
+ char **args = check_vargs(&argc, vargs);
29
+
30
+ /// Get a handle to global provider list for lookup
31
+ cStaticTracing = rb_const_get(rb_cObject, rb_intern("StaticTracing"));
32
+ cProvider = rb_const_get(cStaticTracing, rb_intern("Provider"));
33
+ cProviderInst = rb_funcall(cProvider, rb_intern("register"), 1, provider);
34
+
35
+ // Create a probe
36
+ usdt_probedef_t *probe = usdt_create_probe(c_name_str, c_name_str, argc, args);
37
+
38
+ // Use the provider to register a tracepoint
39
+ int success = provider_add_tracepoint_internal(cProviderInst, probe); // FIXME handle error checking here and throw an exception if failure
40
+ TypedData_Get_Struct(self, static_tracing_tracepoint_t, &static_tracing_tracepoint_type, tracepoint);
41
+
42
+ // FIXME check for nulls
43
+ // FIXME Do we really need to store both references? refactor this.
44
+ // Store the tracepoint handle in our struct
45
+ tracepoint->usdt_tracepoint_def = probe;
46
+
47
+ return self;
48
+ }
49
+
50
+ VALUE
51
+ tracepoint_fire(VALUE self, VALUE vargs)
52
+ {
53
+ static_tracing_tracepoint_t *res = NULL;
54
+ TypedData_Get_Struct(self, static_tracing_tracepoint_t, &static_tracing_tracepoint_type, res);
55
+ int argc = 0;
56
+ void *args = check_fire_args(&argc, vargs);
57
+
58
+ usdt_fire_probe(res->usdt_tracepoint_def->probe, argc, args);
59
+ return Qnil;
60
+ }
61
+
62
+ VALUE
63
+ tracepoint_enabled(VALUE self)
64
+ {
65
+ static_tracing_tracepoint_t *res = NULL;
66
+ TypedData_Get_Struct(self, static_tracing_tracepoint_t, &static_tracing_tracepoint_type, res);
67
+ return usdt_is_enabled(res->usdt_tracepoint_def->probe) == 0 ? Qfalse : Qtrue;
68
+ }
69
+
70
+ static const char*
71
+ check_name_arg(VALUE name)
72
+ {
73
+ const char *c_name_str = NULL;
74
+
75
+ if (TYPE(name) != T_SYMBOL && TYPE(name) != T_STRING) {
76
+ rb_raise(rb_eTypeError, "name must be a symbol or string");
77
+ }
78
+ if (TYPE(name) == T_SYMBOL) {
79
+ c_name_str = rb_id2name(rb_to_id(name));
80
+ } else if (TYPE(name) == T_STRING) {
81
+ c_name_str = RSTRING_PTR(name);
82
+ }
83
+
84
+ return c_name_str;
85
+ }
86
+
87
+ static const char*
88
+ check_provider_arg(VALUE provider)
89
+ {
90
+ const char *c_provider_str = NULL;
91
+
92
+ if (TYPE(provider) != T_SYMBOL && TYPE(provider) != T_STRING) {
93
+ rb_raise(rb_eTypeError, "provider must be a symbol or string");
94
+ }
95
+ if (TYPE(provider) == T_SYMBOL) {
96
+ c_provider_str = rb_id2name(rb_to_id(provider));
97
+ } else if (TYPE(provider) == T_STRING) {
98
+ c_provider_str = RSTRING_PTR(provider);
99
+ }
100
+
101
+ return c_provider_str;
102
+ }
103
+
104
+ static char
105
+ **check_vargs(int *argc, VALUE vargs)
106
+ {
107
+ if(TYPE(vargs) == T_ARRAY)
108
+ {
109
+ VALUE rLength = rb_funcall(vargs, rb_intern("length"), 0, Qnil);
110
+ *argc = NUM2INT(rLength);
111
+
112
+ if(*argc > 6)
113
+ {
114
+ printf("ERROR - passed %i args, maximum 6 argument types can be passed", *argc);
115
+ return NULL;
116
+ }
117
+ // FIXME ensure this is freed
118
+ char **args = malloc(*argc * sizeof(char*));
119
+ for (int i = 0; i < *argc; i++)
120
+ {
121
+ VALUE str = rb_funcall(rb_ary_entry(vargs, i), rb_intern("to_s"), 0, Qnil);
122
+ const char* cStr = RSTRING_PTR(str);
123
+ if (strcmp(cStr, "Integer")) {
124
+ args[i] = strdup(cStr);
125
+ } else if (strcmp(cStr, "String")) {
126
+ args[i] = strdup(cStr);
127
+ } else {
128
+ printf("ERROR - type \"%s\" is unsupported\n", cStr);
129
+ }
130
+ }
131
+ return args;
132
+ } else {
133
+ printf("ERROR - array was expected\n");
134
+ return NULL;
135
+ }
136
+ }
137
+
138
+
139
+ /*
140
+ * Yeah, returning a void ** array is a bit sketchy, but since
141
+ * usdt_fire_probe takes a void **, that's what we'll give it.
142
+ *
143
+ * The structure of the data is actually an array of 64 bit unions
144
+ * So the size of the data should be argc * 8 bytes.
145
+ * We assume that reads will be aligned on 64 bits in the tracer.
146
+ *
147
+ * The approach libstapsdt takes is pretty similar, just not an array.
148
+ */
149
+ static void
150
+ **check_fire_args(int *argc, VALUE vargs)
151
+ {
152
+ if(TYPE(vargs) == T_ARRAY)
153
+ {
154
+ VALUE rLength = rb_funcall(vargs, rb_intern("length"), 0, Qnil);
155
+ *argc = NUM2INT(rLength);
156
+
157
+ if(*argc > 6)
158
+ {
159
+ printf("ERROR - passed %i args, maximum 6 argument types can be passed", *argc);
160
+ return NULL;
161
+ }
162
+
163
+ Tracepoint_fire_arg *args = malloc(*argc * sizeof(Tracepoint_fire_arg));
164
+ //printf("SIZE: %i ARGC: %i \n", sizeof(Tracepoint_fire_arg), *argc);
165
+ // FIXME check against registered argtypes here
166
+ for (int i = 0; i < *argc; i++)
167
+ {
168
+ VALUE val = rb_ary_entry(vargs, i);
169
+ switch(TYPE(val))
170
+ {
171
+ case T_FIXNUM:
172
+ args[i].intval = FIX2LONG(val);
173
+ break;
174
+ case T_STRING:
175
+ args[i].strval = RSTRING_PTR(val);
176
+ break;
177
+ default:
178
+ printf("ERROR unsupported type passed for argument %i to fire\n", i);
179
+ break;
180
+ }
181
+ }
182
+ // This downcast is explained the comment section of this function.
183
+ return (void **) args;
184
+ } else {
185
+ printf("ERROR - array was expected\n");
186
+ return NULL;
187
+ }
188
+ }
189
+
190
+ // Allocate a static_tracing_tracepoint_type struct for ruby memory management
191
+ VALUE
192
+ static_tracing_tracepoint_alloc(VALUE klass)
193
+ {
194
+ static_tracing_tracepoint_t *res;
195
+ VALUE obj = TypedData_Make_Struct(klass, static_tracing_tracepoint_t, &static_tracing_tracepoint_type, res);
196
+ return obj;
197
+ }
198
+
199
+ static inline void
200
+ static_tracing_tracepoint_mark(void *ptr)
201
+ {
202
+ /* noop */
203
+ }
204
+
205
+ static inline void
206
+ static_tracing_tracepoint_free(void *ptr)
207
+ {
208
+ static_tracing_tracepoint_t *res = (static_tracing_tracepoint_t *) ptr;
209
+ //if (res->name) {
210
+ // free(res->name);
211
+ // res->name = NULL;
212
+ //}
213
+ xfree(res);
214
+ }
215
+
216
+ static inline size_t
217
+ static_tracing_tracepoint_memsize(const void *ptr)
218
+ {
219
+ return sizeof(static_tracing_provider_t);
220
+ }
221
+
222
+ static const rb_data_type_t
223
+ static_tracing_tracepoint_type = {
224
+ "static_tracing_tracepoint",
225
+ {
226
+ static_tracing_tracepoint_mark,
227
+ static_tracing_tracepoint_free,
228
+ static_tracing_tracepoint_memsize
229
+ },
230
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
231
+ };