ruby-dtrace 0.0.6 → 0.2.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|