ruby-dtrace 0.0.6 → 0.2.8
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.
- data/History.txt +21 -0
- data/Manifest.txt +86 -19
- data/README.txt +48 -6
- data/Rakefile +61 -20
- data/examples/scsi.rb +1 -1
- data/ext/dof/Makefile +154 -0
- data/ext/dof/constants.c +57 -0
- data/ext/dof/dof.h +56 -0
- data/ext/dof/dof_api.c +58 -0
- data/ext/dof/dof_helper.c +82 -0
- data/ext/dof/extconf.rb +4 -0
- data/ext/dof/file.c +90 -0
- data/ext/dof/generator.c +9 -0
- data/ext/dof/header.c +79 -0
- data/ext/dof/mkmf.log +10 -0
- data/ext/dof/parser.c +415 -0
- data/ext/dof/parser.h +10 -0
- data/ext/dof/section.c +312 -0
- data/ext/dtrace_aggdata.c +2 -2
- data/ext/dtrace_api.c +46 -34
- data/ext/dtrace_api.h +31 -7
- data/ext/dtrace_bufdata.c +3 -3
- data/ext/dtrace_hdl.c +66 -3
- data/ext/dtrace_probedata.c +4 -4
- data/ext/{dtrace_probe.c → dtrace_probedesc.c} +7 -7
- data/ext/extconf.rb +25 -0
- data/ext/i386-darwin/dtrace_probe.c +278 -0
- data/ext/i386-solaris/dtrace_probe.c +225 -0
- data/ext/stubs.txt +78 -0
- data/lib/dtrace.rb +34 -13
- data/lib/dtrace/aggregate.rb +40 -0
- data/lib/dtrace/aggregateset.rb +19 -0
- data/lib/dtrace/consumer.rb +174 -0
- data/lib/dtrace/data.rb +82 -0
- data/lib/dtrace/dof.rb +8 -0
- data/lib/dtrace/dof/file.rb +64 -0
- data/lib/dtrace/dof/section.rb +75 -0
- data/lib/dtrace/dof/section/strtab.rb +28 -0
- data/lib/{dtraceprintfrecord.rb → dtrace/printfrecord.rb} +4 -2
- data/lib/dtrace/probe.rb +3 -6
- data/lib/dtrace/probedata.rb +23 -0
- data/lib/dtrace/probedesc.rb +15 -0
- data/lib/dtrace/provider.rb +190 -169
- data/lib/dtrace/provider/klass.rb +33 -0
- data/lib/dtrace/provider/probedef.rb +24 -0
- data/lib/{dtracerecord.rb → dtrace/record.rb} +4 -2
- data/lib/{dtracestackrecord.rb → dtrace/stackrecord.rb} +10 -8
- data/lib/dtrace/version.rb +9 -0
- data/lib/dtraceconsumer.rb +3 -167
- data/plugin/dtrace/lib/dtracer.rb +4 -4
- data/test/apple-dof +0 -0
- data/test/disabled_probe_effect.txt +19 -0
- data/test/dof +0 -0
- data/test/dof2 +0 -0
- data/test/test_disabled_probe_effect.rb +56 -0
- data/test/test_dof_generator.rb +142 -0
- data/test/test_dof_helper.rb +106 -0
- data/test/test_dof_parser.rb +27 -0
- data/test/test_dof_providers.rb +278 -0
- data/test/test_dof_strtabs.rb +98 -0
- data/test/test_dtrace.rb +67 -1
- data/test/test_dtrace_aggregates.rb +5 -5
- data/test/test_dtrace_drops_errors.rb +5 -5
- data/test/test_dtrace_probe.rb +385 -0
- data/test/test_dtrace_probes.rb +414 -0
- data/test/test_dtrace_processes.rb +2 -2
- data/test/test_dtrace_profile.rb +12 -12
- data/test/test_dtrace_provider.rb +138 -0
- data/test/test_dtrace_repeat.rb +1 -1
- data/test/test_dtrace_rubyprobe.rb +3 -1
- data/test/test_dtrace_typefilter.rb +9 -9
- data/test/test_legacy_consumer.rb +56 -0
- metadata +112 -71
- data/lib/dtrace/provider/osx.rb +0 -25
- data/lib/dtrace/provider/solaris.rb +0 -29
- data/lib/dtraceaggregate.rb +0 -37
- data/lib/dtraceaggregateset.rb +0 -17
- data/lib/dtracedata.rb +0 -80
- data/lib/dtraceprobe.rb +0 -13
- data/lib/dtraceprobedata.rb +0 -21
- data/test/test_dynusdt.rb +0 -135
data/ext/dof/parser.c
ADDED
@@ -0,0 +1,415 @@
|
|
1
|
+
/*
|
2
|
+
* Ruby-Dtrace
|
3
|
+
* (c) 2008 Chris Andrews <chris@nodnol.org>
|
4
|
+
*/
|
5
|
+
|
6
|
+
#include "dof.h"
|
7
|
+
|
8
|
+
RUBY_EXTERN eDtraceDofException;
|
9
|
+
|
10
|
+
static void
|
11
|
+
rubydump(void *data, int len)
|
12
|
+
{
|
13
|
+
VALUE str;
|
14
|
+
VALUE dumped;
|
15
|
+
char *out;
|
16
|
+
|
17
|
+
str = rb_str_new(data, len);
|
18
|
+
dumped = rb_funcall(str, rb_intern("inspect"), 0);
|
19
|
+
out = STR2CSTR(dumped);
|
20
|
+
|
21
|
+
fprintf(stderr, "%s\n", out);
|
22
|
+
}
|
23
|
+
|
24
|
+
static void
|
25
|
+
rubyinspect(VALUE data)
|
26
|
+
{
|
27
|
+
VALUE dumped;
|
28
|
+
char *out;
|
29
|
+
|
30
|
+
dumped = rb_funcall(data, rb_intern("inspect"), 0);
|
31
|
+
out = STR2CSTR(dumped);
|
32
|
+
|
33
|
+
fprintf(stderr, "%s\n", out);
|
34
|
+
}
|
35
|
+
|
36
|
+
static const char *
|
37
|
+
_dof_sec_type(uint32_t type)
|
38
|
+
{
|
39
|
+
switch(type) {
|
40
|
+
case DOF_SECT_NONE:
|
41
|
+
return "null section";
|
42
|
+
case DOF_SECT_COMMENTS:
|
43
|
+
return "compiler comments";
|
44
|
+
case DOF_SECT_SOURCE:
|
45
|
+
return "D program source code";
|
46
|
+
case DOF_SECT_ECBDESC:
|
47
|
+
return "dof_ecbdesc_t";
|
48
|
+
case DOF_SECT_PROBEDESC:
|
49
|
+
return "dof_probedesc_t";
|
50
|
+
case DOF_SECT_ACTDESC:
|
51
|
+
return "dof_actdesc_t array";
|
52
|
+
case DOF_SECT_DIFOHDR:
|
53
|
+
return "dof_difohdr_t (variable length)";
|
54
|
+
case DOF_SECT_DIF:
|
55
|
+
return "uint32_t array of byte code";
|
56
|
+
case DOF_SECT_STRTAB:
|
57
|
+
return "string table";
|
58
|
+
case DOF_SECT_VARTAB:
|
59
|
+
return "dtrace_difv_t array";
|
60
|
+
case DOF_SECT_RELTAB:
|
61
|
+
return "dof_relodesc_t array";
|
62
|
+
case DOF_SECT_TYPTAB:
|
63
|
+
return "dtrace_diftype_t array";
|
64
|
+
case DOF_SECT_URELHDR:
|
65
|
+
return "dof_relohdr_t (user relocations)";
|
66
|
+
case DOF_SECT_KRELHDR:
|
67
|
+
return "dof_relohdr_t (kernel relocations)";
|
68
|
+
case DOF_SECT_OPTDESC:
|
69
|
+
return "dof_optdesc_t array";
|
70
|
+
case DOF_SECT_PROVIDER:
|
71
|
+
return "dof_provider_t";
|
72
|
+
case DOF_SECT_PROBES:
|
73
|
+
return "dof_probe_t array";
|
74
|
+
case DOF_SECT_PRARGS:
|
75
|
+
return "uint8_t array (probe arg mappings)";
|
76
|
+
case DOF_SECT_PROFFS:
|
77
|
+
return "uint32_t array (probe arg offsets)";
|
78
|
+
case DOF_SECT_INTTAB:
|
79
|
+
return "uint64_t array";
|
80
|
+
case DOF_SECT_UTSNAME:
|
81
|
+
return "struct utsname";
|
82
|
+
case DOF_SECT_XLTAB:
|
83
|
+
return "dof_xlref_t array";
|
84
|
+
case DOF_SECT_XLMEMBERS:
|
85
|
+
return "dof_xlmember_t array";
|
86
|
+
case DOF_SECT_XLIMPORT:
|
87
|
+
return "dof_xlator_t";
|
88
|
+
case DOF_SECT_XLEXPORT:
|
89
|
+
return "dof_xlator_t";
|
90
|
+
case DOF_SECT_PREXPORT:
|
91
|
+
return "dof_secidx_t array (exported objs)";
|
92
|
+
case DOF_SECT_PRENOFFS:
|
93
|
+
return "uint32_t array (enabled offsets)";
|
94
|
+
default:
|
95
|
+
return "unknown section type";
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
99
|
+
static VALUE
|
100
|
+
_dof_parse_string_table(VALUE self, char *dof, dof_sec_t *sec)
|
101
|
+
{
|
102
|
+
char *data = (char *)(dof + sec->dofs_offset);
|
103
|
+
|
104
|
+
VALUE strtab = rb_hash_new();
|
105
|
+
VALUE ctx = rb_cv_get(self, "@@ctx");
|
106
|
+
int i, bool = 0;
|
107
|
+
|
108
|
+
for (i = 0; i < sec->dofs_size - 1; ++i) {
|
109
|
+
if (*data) {
|
110
|
+
if (bool)
|
111
|
+
rb_hash_aset(strtab, INT2FIX(i), rb_str_new2(data));
|
112
|
+
bool = 0;
|
113
|
+
}
|
114
|
+
else if (!bool) {
|
115
|
+
bool = 1;
|
116
|
+
}
|
117
|
+
++data;
|
118
|
+
}
|
119
|
+
|
120
|
+
rb_hash_aset(ctx, ID2SYM(rb_intern("strtab")), strtab);
|
121
|
+
return strtab;
|
122
|
+
}
|
123
|
+
|
124
|
+
static VALUE
|
125
|
+
_dof_parse_dof_probe_t_array(VALUE self, char *dof, dof_sec_t *sec)
|
126
|
+
{
|
127
|
+
dof_probe_t probe;
|
128
|
+
char *data = (char *)(dof + sec->dofs_offset);
|
129
|
+
VALUE probes = rb_ary_new();
|
130
|
+
VALUE ctx = rb_cv_get(self, "@@ctx");
|
131
|
+
VALUE strtab;
|
132
|
+
VALUE probe_data;
|
133
|
+
char addr_str[18]; // XXX length of pointer as string?
|
134
|
+
int count = 0;
|
135
|
+
int offset = 0;
|
136
|
+
|
137
|
+
strtab = rb_hash_aref(ctx, ID2SYM(rb_intern("strtab")));
|
138
|
+
if (NIL_P(strtab)) {
|
139
|
+
rb_raise(eDtraceDofException, "no string table available while parsing probe_t array");
|
140
|
+
return Qnil;
|
141
|
+
}
|
142
|
+
|
143
|
+
while (offset < sec->dofs_size) {
|
144
|
+
memcpy(&probe, dof + sec->dofs_offset + offset, sizeof(probe));
|
145
|
+
count++;
|
146
|
+
|
147
|
+
probe_data = rb_hash_new();
|
148
|
+
sprintf(addr_str, "%p", probe.dofpr_addr);
|
149
|
+
rb_hash_aset(probe_data, ID2SYM(rb_intern("addr")), rb_str_new2(addr_str));
|
150
|
+
rb_hash_aset(probe_data, ID2SYM(rb_intern("func")), rb_hash_aref(strtab, INT2FIX(probe.dofpr_func)));
|
151
|
+
rb_hash_aset(probe_data, ID2SYM(rb_intern("name")), rb_hash_aref(strtab, INT2FIX(probe.dofpr_name)));
|
152
|
+
rb_hash_aset(probe_data, ID2SYM(rb_intern("nargv")), rb_hash_aref(strtab, INT2FIX(probe.dofpr_nargv)));
|
153
|
+
rb_hash_aset(probe_data, ID2SYM(rb_intern("xargv")), rb_hash_aref(strtab, INT2FIX(probe.dofpr_xargv)));
|
154
|
+
|
155
|
+
rb_hash_aset(probe_data, ID2SYM(rb_intern("argidx")), INT2FIX(probe.dofpr_argidx));
|
156
|
+
rb_hash_aset(probe_data, ID2SYM(rb_intern("offidx")), INT2FIX(probe.dofpr_offidx));
|
157
|
+
rb_hash_aset(probe_data, ID2SYM(rb_intern("nargc")), INT2FIX(probe.dofpr_nargc));
|
158
|
+
rb_hash_aset(probe_data, ID2SYM(rb_intern("xargc")), INT2FIX(probe.dofpr_xargc));
|
159
|
+
rb_hash_aset(probe_data, ID2SYM(rb_intern("noffs")), INT2FIX(probe.dofpr_noffs));
|
160
|
+
rb_hash_aset(probe_data, ID2SYM(rb_intern("enoffidx")), INT2FIX(probe.dofpr_enoffidx));
|
161
|
+
rb_hash_aset(probe_data, ID2SYM(rb_intern("nenoffs")), INT2FIX(probe.dofpr_nenoffs));
|
162
|
+
|
163
|
+
rb_ary_push(probes, probe_data);
|
164
|
+
offset += sizeof(probe);
|
165
|
+
}
|
166
|
+
|
167
|
+
return probes;
|
168
|
+
}
|
169
|
+
|
170
|
+
static VALUE
|
171
|
+
_dof_parse_dof_relodesc_t_array(VALUE self, char *dof, dof_sec_t *sec)
|
172
|
+
{
|
173
|
+
dof_relodesc_t relodesc;
|
174
|
+
char *data = (char *)(dof + sec->dofs_offset);
|
175
|
+
VALUE relodescs = rb_ary_new();
|
176
|
+
VALUE ctx = rb_cv_get(self, "@@ctx");
|
177
|
+
VALUE strtab = rb_hash_aref(ctx, ID2SYM(rb_intern("strtab")));
|
178
|
+
VALUE relodesc_data;
|
179
|
+
int count = 0;
|
180
|
+
int offset = 0;
|
181
|
+
|
182
|
+
while (offset < sec->dofs_size) {
|
183
|
+
memcpy(&relodesc, dof + sec->dofs_offset + offset, sizeof(relodesc));
|
184
|
+
count++;
|
185
|
+
|
186
|
+
relodesc_data = rb_hash_new();
|
187
|
+
rb_hash_aset(relodesc_data, ID2SYM(rb_intern("name")), rb_hash_aref(strtab, INT2FIX(relodesc.dofr_name)));
|
188
|
+
|
189
|
+
switch(relodesc.dofr_type) {
|
190
|
+
case DOF_RELO_NONE:
|
191
|
+
rb_hash_aset(relodesc_data, ID2SYM(rb_intern("type")), rb_str_new2("none"));
|
192
|
+
break;
|
193
|
+
case DOF_RELO_SETX:
|
194
|
+
rb_hash_aset(relodesc_data, ID2SYM(rb_intern("type")), rb_str_new2("setx"));
|
195
|
+
break;
|
196
|
+
default:
|
197
|
+
rb_hash_aset(relodesc_data, ID2SYM(rb_intern("type")), rb_str_new2("unknown"));
|
198
|
+
break;
|
199
|
+
}
|
200
|
+
|
201
|
+
rb_hash_aset(relodesc_data, ID2SYM(rb_intern("offset")), INT2FIX(relodesc.dofr_offset));
|
202
|
+
rb_hash_aset(relodesc_data, ID2SYM(rb_intern("data")), INT2FIX(relodesc.dofr_data));
|
203
|
+
|
204
|
+
rb_ary_push(relodescs, relodesc_data);
|
205
|
+
offset += sizeof(relodesc);
|
206
|
+
}
|
207
|
+
|
208
|
+
return relodescs;
|
209
|
+
}
|
210
|
+
|
211
|
+
static VALUE
|
212
|
+
_dof_parse_dof_relohdr_t(VALUE self, char *dof, dof_sec_t *sec)
|
213
|
+
{
|
214
|
+
dof_relohdr_t relohdr;
|
215
|
+
char *data = (char *)(dof + sec->dofs_offset);
|
216
|
+
VALUE relohdr_data = rb_hash_new();
|
217
|
+
|
218
|
+
memcpy(&relohdr, dof + sec->dofs_offset, sizeof(relohdr));
|
219
|
+
rb_hash_aset(relohdr_data, ID2SYM(rb_intern("strtab")), INT2FIX(relohdr.dofr_strtab));
|
220
|
+
rb_hash_aset(relohdr_data, ID2SYM(rb_intern("relsec")), INT2FIX(relohdr.dofr_relsec));
|
221
|
+
rb_hash_aset(relohdr_data, ID2SYM(rb_intern("tgtsec")), INT2FIX(relohdr.dofr_tgtsec));
|
222
|
+
|
223
|
+
return relohdr_data;
|
224
|
+
}
|
225
|
+
|
226
|
+
static VALUE
|
227
|
+
_dof_parse_dof_attr_t(dof_attr_t attr)
|
228
|
+
{
|
229
|
+
VALUE attr_data = rb_hash_new();
|
230
|
+
|
231
|
+
rb_hash_aset(attr_data, ID2SYM(rb_intern("name")), INT2FIX(DOF_ATTR_NAME(attr)));
|
232
|
+
rb_hash_aset(attr_data, ID2SYM(rb_intern("data")), INT2FIX(DOF_ATTR_DATA(attr)));
|
233
|
+
rb_hash_aset(attr_data, ID2SYM(rb_intern("class")), INT2FIX(DOF_ATTR_CLASS(attr)));
|
234
|
+
|
235
|
+
return attr_data;
|
236
|
+
}
|
237
|
+
|
238
|
+
static VALUE
|
239
|
+
_dof_parse_dof_provider_t(VALUE self, char *dof, dof_sec_t *sec)
|
240
|
+
{
|
241
|
+
dof_provider_t provider;
|
242
|
+
char *data = (char *)(dof + sec->dofs_offset);
|
243
|
+
VALUE provider_data = rb_hash_new();
|
244
|
+
VALUE ctx = rb_cv_get(self, "@@ctx");
|
245
|
+
VALUE strtab = rb_hash_aref(ctx, ID2SYM(rb_intern("strtab")));
|
246
|
+
|
247
|
+
memcpy(&provider, dof + sec->dofs_offset, sizeof(provider));
|
248
|
+
rb_hash_aset(provider_data, ID2SYM(rb_intern("name")), rb_hash_aref(strtab, INT2FIX(provider.dofpv_name)));
|
249
|
+
rb_hash_aset(provider_data, ID2SYM(rb_intern("strtab")), INT2FIX(provider.dofpv_strtab));
|
250
|
+
rb_hash_aset(provider_data, ID2SYM(rb_intern("probes")), INT2FIX(provider.dofpv_probes));
|
251
|
+
rb_hash_aset(provider_data, ID2SYM(rb_intern("prargs")), INT2FIX(provider.dofpv_prargs));
|
252
|
+
rb_hash_aset(provider_data, ID2SYM(rb_intern("proffs")), INT2FIX(provider.dofpv_proffs));
|
253
|
+
|
254
|
+
rb_hash_aset(provider_data, ID2SYM(rb_intern("provattr")), _dof_parse_dof_attr_t(provider.dofpv_provattr));
|
255
|
+
rb_hash_aset(provider_data, ID2SYM(rb_intern("modattr")), _dof_parse_dof_attr_t(provider.dofpv_modattr));
|
256
|
+
rb_hash_aset(provider_data, ID2SYM(rb_intern("funcattr")), _dof_parse_dof_attr_t(provider.dofpv_funcattr));
|
257
|
+
rb_hash_aset(provider_data, ID2SYM(rb_intern("nameattr")), _dof_parse_dof_attr_t(provider.dofpv_nameattr));
|
258
|
+
rb_hash_aset(provider_data, ID2SYM(rb_intern("argsattr")), _dof_parse_dof_attr_t(provider.dofpv_argsattr));
|
259
|
+
|
260
|
+
return provider_data;
|
261
|
+
}
|
262
|
+
|
263
|
+
static VALUE
|
264
|
+
_dof_parse_uint8_t_array(VALUE self, char *dof, dof_sec_t *sec)
|
265
|
+
{
|
266
|
+
VALUE ary_data = rb_ary_new();
|
267
|
+
char *data = (char *)(dof + sec->dofs_offset);
|
268
|
+
int len = sec->dofs_size / sizeof(uint8_t);
|
269
|
+
uint8_t array[len];
|
270
|
+
int i;
|
271
|
+
|
272
|
+
memcpy(&array, data, len * sizeof(uint8_t));
|
273
|
+
for (i = 0; i < len; i++) {
|
274
|
+
rb_ary_push(ary_data, INT2FIX(array[i]));
|
275
|
+
}
|
276
|
+
|
277
|
+
return ary_data;
|
278
|
+
}
|
279
|
+
|
280
|
+
static VALUE
|
281
|
+
_dof_parse_uint32_t_array(VALUE self, char *dof, dof_sec_t *sec)
|
282
|
+
{
|
283
|
+
VALUE ary_data = rb_ary_new();
|
284
|
+
char *data = (char *)(dof + sec->dofs_offset);
|
285
|
+
int len = sec->dofs_size / sizeof(uint32_t);
|
286
|
+
uint32_t array[len];
|
287
|
+
int i;
|
288
|
+
|
289
|
+
memcpy(&array, data, len * sizeof(uint32_t));
|
290
|
+
for (i = 0; i < len; i++) {
|
291
|
+
rb_ary_push(ary_data, INT2FIX((unsigned int)array[i]));
|
292
|
+
}
|
293
|
+
|
294
|
+
return ary_data;
|
295
|
+
}
|
296
|
+
|
297
|
+
static VALUE
|
298
|
+
_dof_parse_comments(VALUE self, char *dof, dof_sec_t *sec)
|
299
|
+
{
|
300
|
+
char comment[sec->dofs_size + 1];
|
301
|
+
char *data = (char *)(dof + sec->dofs_offset);
|
302
|
+
|
303
|
+
strncpy(comment, data, sec->dofs_size);
|
304
|
+
return rb_str_new2(comment);
|
305
|
+
}
|
306
|
+
|
307
|
+
static VALUE
|
308
|
+
_dof_parse_utsname(VALUE self, char *dof, dof_sec_t *sec)
|
309
|
+
{
|
310
|
+
struct utsname uts;
|
311
|
+
VALUE uts_data = rb_hash_new();
|
312
|
+
char *data = (char *)(dof + sec->dofs_offset);
|
313
|
+
|
314
|
+
memcpy(&uts, data, sizeof(uts));
|
315
|
+
|
316
|
+
rb_hash_aset(uts_data, ID2SYM(rb_intern("sysname")), rb_str_new2(uts.sysname));
|
317
|
+
rb_hash_aset(uts_data, ID2SYM(rb_intern("nodename")), rb_str_new2(uts.nodename));
|
318
|
+
rb_hash_aset(uts_data, ID2SYM(rb_intern("release")), rb_str_new2(uts.release));
|
319
|
+
rb_hash_aset(uts_data, ID2SYM(rb_intern("version")), rb_str_new2(uts.version));
|
320
|
+
rb_hash_aset(uts_data, ID2SYM(rb_intern("machine")), rb_str_new2(uts.machine));
|
321
|
+
|
322
|
+
return uts_data;
|
323
|
+
}
|
324
|
+
|
325
|
+
static VALUE
|
326
|
+
_dof_parse_unknown(VALUE self, char *dof, dof_sec_t *sec)
|
327
|
+
{
|
328
|
+
VALUE section_data = rb_hash_new();
|
329
|
+
return section_data;
|
330
|
+
}
|
331
|
+
|
332
|
+
/* Parse the given DOF */
|
333
|
+
VALUE dof_parse(VALUE self, VALUE rdof)
|
334
|
+
{
|
335
|
+
VALUE dof_data;
|
336
|
+
VALUE sec_data;
|
337
|
+
VALUE ctx;
|
338
|
+
VALUE sec;
|
339
|
+
char *dof;
|
340
|
+
char *pos;
|
341
|
+
dof_hdr_t dof_hdr;
|
342
|
+
dof_sec_t dof_sec;
|
343
|
+
int i;
|
344
|
+
|
345
|
+
ctx = rb_hash_new();
|
346
|
+
rb_cv_set(self, "@@ctx", ctx);
|
347
|
+
|
348
|
+
dof = STR2CSTR(rdof);
|
349
|
+
pos = dof;
|
350
|
+
memcpy(&dof_hdr, pos, sizeof(dof_hdr));
|
351
|
+
|
352
|
+
/* Check magic */
|
353
|
+
if (!(dof_hdr.dofh_ident[0] == DOF_MAG_MAG0 &&
|
354
|
+
dof_hdr.dofh_ident[1] == DOF_MAG_MAG1 &&
|
355
|
+
dof_hdr.dofh_ident[2] == DOF_MAG_MAG2 &&
|
356
|
+
dof_hdr.dofh_ident[3] == DOF_MAG_MAG3)) {
|
357
|
+
rb_raise(eDtraceDofException, "bad DOF header magic");
|
358
|
+
return Qnil;
|
359
|
+
}
|
360
|
+
pos += dof_hdr.dofh_hdrsize;
|
361
|
+
|
362
|
+
dof_data = rb_ary_new();
|
363
|
+
|
364
|
+
/* Walk section headers, parsing sections */
|
365
|
+
for (i = 0; i < dof_hdr.dofh_secnum; i++) {
|
366
|
+
memcpy(&dof_sec, pos, sizeof(struct dof_sec));
|
367
|
+
|
368
|
+
sec_data = rb_hash_new();
|
369
|
+
rb_hash_aset(sec_data, ID2SYM(rb_intern("index")), INT2FIX(i));
|
370
|
+
rb_hash_aset(sec_data, ID2SYM(rb_intern("type")), rb_str_new2(_dof_sec_type(dof_sec.dofs_type)));
|
371
|
+
rb_hash_aset(sec_data, ID2SYM(rb_intern("flags")), INT2FIX(dof_sec.dofs_flags));
|
372
|
+
|
373
|
+
sec = Qnil;
|
374
|
+
switch(dof_sec.dofs_type) {
|
375
|
+
case DOF_SECT_STRTAB:
|
376
|
+
sec = _dof_parse_string_table(self, dof, &dof_sec);
|
377
|
+
break;
|
378
|
+
case DOF_SECT_PROBES:
|
379
|
+
sec = _dof_parse_dof_probe_t_array(self, dof, &dof_sec);
|
380
|
+
break;
|
381
|
+
case DOF_SECT_PROVIDER:
|
382
|
+
sec = _dof_parse_dof_provider_t(self, dof, &dof_sec);
|
383
|
+
break;
|
384
|
+
case DOF_SECT_PRARGS:
|
385
|
+
sec = _dof_parse_uint8_t_array(self, dof, &dof_sec);
|
386
|
+
break;
|
387
|
+
case DOF_SECT_PRENOFFS:
|
388
|
+
case DOF_SECT_PROFFS:
|
389
|
+
sec = _dof_parse_uint32_t_array(self, dof, &dof_sec);
|
390
|
+
break;
|
391
|
+
case DOF_SECT_RELTAB:
|
392
|
+
sec = _dof_parse_dof_relodesc_t_array(self, dof, &dof_sec);
|
393
|
+
break;
|
394
|
+
case DOF_SECT_URELHDR:
|
395
|
+
sec = _dof_parse_dof_relohdr_t(self, dof, &dof_sec);
|
396
|
+
break;
|
397
|
+
case DOF_SECT_UTSNAME:
|
398
|
+
sec = _dof_parse_utsname(self, dof, &dof_sec);
|
399
|
+
break;
|
400
|
+
case DOF_SECT_COMMENTS:
|
401
|
+
sec = _dof_parse_comments(self, dof, &dof_sec);
|
402
|
+
break;
|
403
|
+
default:
|
404
|
+
sec = _dof_parse_unknown(self, dof, &dof_sec);
|
405
|
+
break;
|
406
|
+
}
|
407
|
+
rb_hash_aset(sec_data, ID2SYM(rb_intern("data")), sec);
|
408
|
+
|
409
|
+
rb_ary_push(dof_data, sec_data);
|
410
|
+
pos += dof_hdr.dofh_secsize;
|
411
|
+
}
|
412
|
+
|
413
|
+
return dof_data;
|
414
|
+
}
|
415
|
+
|
data/ext/dof/parser.h
ADDED
data/ext/dof/section.c
ADDED
@@ -0,0 +1,312 @@
|
|
1
|
+
/*
|
2
|
+
* Ruby-Dtrace
|
3
|
+
* (c) 2008 Chris Andrews <chris@nodnol.org>
|
4
|
+
*/
|
5
|
+
|
6
|
+
#include "dof.h"
|
7
|
+
#include <errno.h>
|
8
|
+
#include <string.h>
|
9
|
+
|
10
|
+
RUBY_EXTERN eDtraceDofException;
|
11
|
+
|
12
|
+
/* :nodoc: */
|
13
|
+
VALUE dof_generate_section_header(VALUE self) {
|
14
|
+
VALUE hdr_data;
|
15
|
+
dof_sec_t hdr;
|
16
|
+
uint32_t type;
|
17
|
+
uint64_t offset;
|
18
|
+
uint64_t size;
|
19
|
+
uint32_t entsize;
|
20
|
+
|
21
|
+
memset(&hdr, 0, sizeof(hdr));
|
22
|
+
hdr.dofs_flags = FIX2INT(rb_iv_get(self, "@flags"));
|
23
|
+
hdr.dofs_type = FIX2INT(rb_iv_get(self, "@section_type"));
|
24
|
+
hdr.dofs_offset = FIX2INT(rb_iv_get(self, "@offset"));
|
25
|
+
hdr.dofs_size = FIX2INT(rb_iv_get(self, "@size"));
|
26
|
+
hdr.dofs_entsize = FIX2INT(rb_iv_get(self, "@entsize"));
|
27
|
+
hdr.dofs_align = FIX2INT(rb_iv_get(self, "@align"));
|
28
|
+
|
29
|
+
hdr_data = rb_str_new((const char *)&hdr, sizeof(hdr));
|
30
|
+
return hdr_data;
|
31
|
+
}
|
32
|
+
|
33
|
+
/* :nodoc: */
|
34
|
+
VALUE dof_generate_comments(VALUE self) {
|
35
|
+
VALUE dof;
|
36
|
+
VALUE comments = rb_iv_get(self, "@data");
|
37
|
+
|
38
|
+
if (NIL_P(comments) ) {
|
39
|
+
rb_raise(eDtraceDofException, "no comments in dof_generate_comments");
|
40
|
+
return Qnil;
|
41
|
+
}
|
42
|
+
|
43
|
+
Check_Type(comments, T_STRING);
|
44
|
+
|
45
|
+
dof = rb_str_new(RSTRING(comments)->ptr, RSTRING(comments)->len + 1);
|
46
|
+
return dof;
|
47
|
+
}
|
48
|
+
|
49
|
+
/* :nodoc: */
|
50
|
+
VALUE dof_generate_probes(VALUE self) {
|
51
|
+
VALUE dof;
|
52
|
+
VALUE probes = rb_iv_get(self, "@data");
|
53
|
+
VALUE probe;
|
54
|
+
int i;
|
55
|
+
|
56
|
+
if (NIL_P(probes) ) {
|
57
|
+
rb_raise(eDtraceDofException, "no probes in dof_generate_probes");
|
58
|
+
return Qnil;
|
59
|
+
}
|
60
|
+
Check_Type(probes, T_ARRAY);
|
61
|
+
|
62
|
+
dof = rb_str_new2("");
|
63
|
+
|
64
|
+
for (i = 0; i < rb_ary_len(probes); i++) {
|
65
|
+
probe = rb_ary_entry(probes, i);
|
66
|
+
|
67
|
+
Check_Type(probe, T_HASH);
|
68
|
+
|
69
|
+
dof_probe_t p;
|
70
|
+
memset(&p, 0, sizeof(p));
|
71
|
+
|
72
|
+
p.dofpr_addr = (uint64_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("addr"))));
|
73
|
+
p.dofpr_func = (dof_stridx_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("func"))));
|
74
|
+
p.dofpr_name = (dof_stridx_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("name"))));
|
75
|
+
p.dofpr_nargv = (dof_stridx_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("nargv"))));
|
76
|
+
p.dofpr_xargv = (dof_stridx_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("xargv"))));
|
77
|
+
|
78
|
+
p.dofpr_argidx = (uint32_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("argidx"))));
|
79
|
+
p.dofpr_offidx = (uint32_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("offidx"))));
|
80
|
+
p.dofpr_nargc = (uint8_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("nargc"))));
|
81
|
+
p.dofpr_xargc = (uint8_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("xargc"))));
|
82
|
+
p.dofpr_noffs = (uint16_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("noffs"))));
|
83
|
+
p.dofpr_enoffidx = (uint32_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("enoffidx"))));
|
84
|
+
p.dofpr_nenoffs = (uint16_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("nenoffs"))));
|
85
|
+
|
86
|
+
VALUE p_dof = rb_str_new((const char *)&p, sizeof(p));
|
87
|
+
rb_str_concat(dof, p_dof);
|
88
|
+
}
|
89
|
+
|
90
|
+
return dof;
|
91
|
+
}
|
92
|
+
|
93
|
+
/* :nodoc: */
|
94
|
+
VALUE dof_generate_strtab(VALUE self) {
|
95
|
+
VALUE dof;
|
96
|
+
VALUE strings = rb_iv_get(self, "@data");
|
97
|
+
VALUE string;
|
98
|
+
int i;
|
99
|
+
|
100
|
+
if (NIL_P(strings) ) {
|
101
|
+
rb_raise(eDtraceDofException, "no strings in dof_generate_strtab");
|
102
|
+
return Qnil;
|
103
|
+
}
|
104
|
+
Check_Type(strings, T_ARRAY);
|
105
|
+
|
106
|
+
dof = rb_str_new("", 0);
|
107
|
+
rb_str_concat(dof, rb_str_new("\0", 1));
|
108
|
+
|
109
|
+
for (i = 0; i < rb_ary_len(strings); i++) {
|
110
|
+
string = rb_ary_entry(strings, i);
|
111
|
+
|
112
|
+
Check_Type(string, T_STRING);
|
113
|
+
|
114
|
+
rb_str_concat(dof, rb_str_new(RSTRING(string)->ptr, RSTRING(string)->len + 1));
|
115
|
+
}
|
116
|
+
|
117
|
+
return dof;
|
118
|
+
}
|
119
|
+
|
120
|
+
/* :nodoc: */
|
121
|
+
VALUE dof_generate_utsname(VALUE self) {
|
122
|
+
VALUE dof;
|
123
|
+
struct utsname u;
|
124
|
+
|
125
|
+
if (uname(&u) < 0) {
|
126
|
+
rb_raise(eDtraceDofException, "uname failed: %s", strerror(errno));
|
127
|
+
return Qnil;
|
128
|
+
}
|
129
|
+
|
130
|
+
dof = rb_str_new((const char *)&u, sizeof(struct utsname));
|
131
|
+
return dof;
|
132
|
+
}
|
133
|
+
|
134
|
+
/* :nodoc: */
|
135
|
+
VALUE dof_generate_prargs(VALUE self) {
|
136
|
+
VALUE dof;
|
137
|
+
VALUE args = rb_iv_get(self, "@data");
|
138
|
+
VALUE rarg;
|
139
|
+
uint8_t arg;
|
140
|
+
int i;
|
141
|
+
|
142
|
+
if (NIL_P(args) ) {
|
143
|
+
rb_raise(eDtraceDofException, "no args in dof_generate_prargs");
|
144
|
+
return Qnil;
|
145
|
+
}
|
146
|
+
Check_Type(args, T_ARRAY);
|
147
|
+
|
148
|
+
dof = rb_str_new("", 0);
|
149
|
+
|
150
|
+
for (i = 0; i < rb_ary_len(args); i++) {
|
151
|
+
rarg = rb_ary_entry(args, i);
|
152
|
+
Check_Type(rarg, T_FIXNUM);
|
153
|
+
if (FIX2INT(rarg) >= 0 && FIX2INT(rarg) < 256) {
|
154
|
+
arg = FIX2INT(rarg);
|
155
|
+
rb_str_concat(dof, rb_str_new((char *)&arg, 1));
|
156
|
+
}
|
157
|
+
}
|
158
|
+
|
159
|
+
return dof;
|
160
|
+
}
|
161
|
+
|
162
|
+
/* :nodoc: */
|
163
|
+
VALUE dof_generate_proffs(VALUE self) {
|
164
|
+
VALUE dof;
|
165
|
+
VALUE args = rb_iv_get(self, "@data");
|
166
|
+
VALUE rarg;
|
167
|
+
uint32_t arg;
|
168
|
+
int i;
|
169
|
+
|
170
|
+
if (NIL_P(args) ) {
|
171
|
+
rb_raise(eDtraceDofException, "no args in dof_generate_proffs");
|
172
|
+
return Qnil;
|
173
|
+
}
|
174
|
+
Check_Type(args, T_ARRAY);
|
175
|
+
|
176
|
+
dof = rb_str_new("", 0);
|
177
|
+
|
178
|
+
for (i = 0; i < rb_ary_len(args); i++) {
|
179
|
+
rarg = rb_ary_entry(args, i);
|
180
|
+
Check_Type(rarg, T_FIXNUM);
|
181
|
+
arg = FIX2INT(rarg);
|
182
|
+
rb_str_concat(dof, rb_str_new((char *)&arg, 4));
|
183
|
+
}
|
184
|
+
|
185
|
+
return dof;
|
186
|
+
}
|
187
|
+
|
188
|
+
/* :nodoc: */
|
189
|
+
VALUE dof_generate_prenoffs(VALUE self) {
|
190
|
+
VALUE dof;
|
191
|
+
VALUE args = rb_iv_get(self, "@data");
|
192
|
+
VALUE rarg;
|
193
|
+
uint32_t arg;
|
194
|
+
int i;
|
195
|
+
|
196
|
+
if (NIL_P(args) ) {
|
197
|
+
rb_raise(eDtraceDofException, "no args in dof_generate_prenoffs");
|
198
|
+
return Qnil;
|
199
|
+
}
|
200
|
+
Check_Type(args, T_ARRAY);
|
201
|
+
|
202
|
+
dof = rb_str_new("", 0);
|
203
|
+
|
204
|
+
for (i = 0; i < rb_ary_len(args); i++) {
|
205
|
+
rarg = rb_ary_entry(args, i);
|
206
|
+
Check_Type(rarg, T_FIXNUM);
|
207
|
+
arg = FIX2INT(rarg);
|
208
|
+
rb_str_concat(dof, rb_str_new((char *)&arg, 4));
|
209
|
+
}
|
210
|
+
|
211
|
+
return dof;
|
212
|
+
}
|
213
|
+
|
214
|
+
dof_attr_t _dof_generate_dof_attr_t(VALUE data) {
|
215
|
+
dof_attr_t attr = 0;
|
216
|
+
uint8_t n = 0;
|
217
|
+
uint8_t d = 0;
|
218
|
+
uint8_t c = 0;
|
219
|
+
|
220
|
+
Check_Type(data, T_HASH);
|
221
|
+
|
222
|
+
n = FIX2INT(rb_hash_aref(data, ID2SYM(rb_intern("name"))));
|
223
|
+
d = FIX2INT(rb_hash_aref(data, ID2SYM(rb_intern("data"))));
|
224
|
+
c = FIX2INT(rb_hash_aref(data, ID2SYM(rb_intern("class"))));
|
225
|
+
|
226
|
+
attr = DOF_ATTR(n, d, c);
|
227
|
+
return attr;
|
228
|
+
}
|
229
|
+
|
230
|
+
/* :nodoc: */
|
231
|
+
VALUE dof_generate_provider(VALUE self) {
|
232
|
+
VALUE dof;
|
233
|
+
VALUE provider = rb_iv_get(self, "@data");
|
234
|
+
dof_provider_t p;
|
235
|
+
|
236
|
+
if (NIL_P(provider) ) {
|
237
|
+
rb_raise(eDtraceDofException, "no data in dof_generate_provider");
|
238
|
+
return Qnil;
|
239
|
+
}
|
240
|
+
Check_Type(provider, T_HASH);
|
241
|
+
|
242
|
+
p.dofpv_strtab = (dof_secidx_t)FIX2INT(rb_hash_aref(provider, ID2SYM(rb_intern("strtab"))));
|
243
|
+
p.dofpv_probes = (dof_secidx_t)FIX2INT(rb_hash_aref(provider, ID2SYM(rb_intern("probes"))));
|
244
|
+
p.dofpv_prargs = (dof_secidx_t)FIX2INT(rb_hash_aref(provider, ID2SYM(rb_intern("prargs"))));
|
245
|
+
p.dofpv_proffs = (dof_secidx_t)FIX2INT(rb_hash_aref(provider, ID2SYM(rb_intern("proffs"))));
|
246
|
+
p.dofpv_name = (dof_stridx_t)FIX2INT(rb_hash_aref(provider, ID2SYM(rb_intern("name"))));
|
247
|
+
p.dofpv_provattr = _dof_generate_dof_attr_t(rb_hash_aref(provider, ID2SYM(rb_intern("provattr"))));
|
248
|
+
p.dofpv_modattr = _dof_generate_dof_attr_t(rb_hash_aref(provider, ID2SYM(rb_intern("modattr"))));
|
249
|
+
p.dofpv_funcattr = _dof_generate_dof_attr_t(rb_hash_aref(provider, ID2SYM(rb_intern("funcattr"))));
|
250
|
+
p.dofpv_nameattr = _dof_generate_dof_attr_t(rb_hash_aref(provider, ID2SYM(rb_intern("nameattr"))));
|
251
|
+
p.dofpv_argsattr = _dof_generate_dof_attr_t(rb_hash_aref(provider, ID2SYM(rb_intern("argsattr"))));
|
252
|
+
p.dofpv_prenoffs = (dof_secidx_t)FIX2INT(rb_hash_aref(provider, ID2SYM(rb_intern("prenoffs"))));
|
253
|
+
|
254
|
+
dof = rb_str_new((const char *)&p, sizeof(p));
|
255
|
+
return dof;
|
256
|
+
}
|
257
|
+
|
258
|
+
/* :nodoc: */
|
259
|
+
VALUE dof_generate_reltab(VALUE self) {
|
260
|
+
VALUE dof;
|
261
|
+
VALUE relos = rb_iv_get(self, "@data");
|
262
|
+
VALUE relo;
|
263
|
+
int i;
|
264
|
+
|
265
|
+
if (NIL_P(relos) ) {
|
266
|
+
rb_raise(eDtraceDofException, "no relos in dof_generate_reltab");
|
267
|
+
return Qnil;
|
268
|
+
}
|
269
|
+
Check_Type(relos, T_ARRAY);
|
270
|
+
|
271
|
+
dof = rb_str_new2("");
|
272
|
+
|
273
|
+
for (i = 0; i < rb_ary_len(relos); i++) {
|
274
|
+
relo = rb_ary_entry(relos, i);
|
275
|
+
|
276
|
+
Check_Type(relo, T_HASH);
|
277
|
+
|
278
|
+
dof_relodesc_t r;
|
279
|
+
memset(&r, 0, sizeof(r));
|
280
|
+
|
281
|
+
r.dofr_name = (dof_stridx_t)FIX2INT(rb_hash_aref(relo, ID2SYM(rb_intern("name"))));
|
282
|
+
r.dofr_type = (uint32_t)FIX2INT(rb_hash_aref(relo, ID2SYM(rb_intern("type"))));
|
283
|
+
r.dofr_offset = (uint64_t)FIX2INT(rb_hash_aref(relo, ID2SYM(rb_intern("offset"))));
|
284
|
+
r.dofr_data = (uint64_t)FIX2INT(rb_hash_aref(relo, ID2SYM(rb_intern("data"))));
|
285
|
+
|
286
|
+
VALUE r_dof = rb_str_new((const char *)&r, sizeof(r));
|
287
|
+
rb_str_concat(dof, r_dof);
|
288
|
+
}
|
289
|
+
|
290
|
+
return dof;
|
291
|
+
}
|
292
|
+
|
293
|
+
/* :nodoc: */
|
294
|
+
VALUE dof_generate_relhdr(VALUE self) {
|
295
|
+
VALUE dof;
|
296
|
+
VALUE relhdr = rb_iv_get(self, "@data");
|
297
|
+
dof_relohdr_t r;
|
298
|
+
|
299
|
+
if (NIL_P(relhdr) ) {
|
300
|
+
rb_raise(eDtraceDofException, "no data in dof_generate_relhdr");
|
301
|
+
return Qnil;
|
302
|
+
}
|
303
|
+
Check_Type(relhdr, T_HASH);
|
304
|
+
|
305
|
+
r.dofr_strtab = (dof_secidx_t)FIX2INT(rb_hash_aref(relhdr, ID2SYM(rb_intern("strtab"))));
|
306
|
+
r.dofr_relsec = (dof_secidx_t)FIX2INT(rb_hash_aref(relhdr, ID2SYM(rb_intern("relsec"))));
|
307
|
+
r.dofr_tgtsec = (dof_secidx_t)FIX2INT(rb_hash_aref(relhdr, ID2SYM(rb_intern("tgtsec"))));
|
308
|
+
|
309
|
+
dof = rb_str_new((const char *)&r, sizeof(r));
|
310
|
+
return dof;
|
311
|
+
}
|
312
|
+
|