chrisa-ruby-dtrace 0.2.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.
- data/History.txt +34 -0
- data/Manifest.txt +58 -0
- data/README.txt +88 -0
- data/Rakefile +73 -0
- data/examples/scsi.rb +442 -0
- data/ext/dof/constants.c +49 -0
- data/ext/dof/dof.h +55 -0
- data/ext/dof/dof_api.c +57 -0
- data/ext/dof/dof_helper.c +82 -0
- data/ext/dof/extconf.rb +4 -0
- data/ext/dof/file.c +56 -0
- data/ext/dof/generator.c +9 -0
- data/ext/dof/header.c +80 -0
- data/ext/dof/parser.c +415 -0
- data/ext/dof/parser.h +10 -0
- data/ext/dof/section.c +302 -0
- data/ext/dtrace_aggdata.c +142 -0
- data/ext/dtrace_api.c +119 -0
- data/ext/dtrace_api.h +150 -0
- data/ext/dtrace_bufdata.c +139 -0
- data/ext/dtrace_dropdata.c +131 -0
- data/ext/dtrace_errdata.c +110 -0
- data/ext/dtrace_hdl.c +577 -0
- data/ext/dtrace_probedata.c +267 -0
- data/ext/dtrace_probedesc.c +78 -0
- data/ext/dtrace_process.c +37 -0
- data/ext/dtrace_program.c +62 -0
- data/ext/dtrace_programinfo.c +60 -0
- data/ext/dtrace_recdesc.c +46 -0
- data/ext/dtrace_util.c +92 -0
- data/ext/extconf.rb +28 -0
- data/ext/stubs.txt +78 -0
- 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/file.rb +63 -0
- data/lib/dtrace/dof/section/strtab.rb +21 -0
- data/lib/dtrace/dof/section.rb +69 -0
- data/lib/dtrace/dof.rb +8 -0
- data/lib/dtrace/printfrecord.rb +10 -0
- data/lib/dtrace/probe.rb +46 -0
- data/lib/dtrace/probedata.rb +23 -0
- data/lib/dtrace/probedesc.rb +15 -0
- data/lib/dtrace/provider/probedef.rb +24 -0
- data/lib/dtrace/provider.rb +231 -0
- data/lib/dtrace/record.rb +11 -0
- data/lib/dtrace/stackrecord.rb +31 -0
- data/lib/dtrace/tracer.rb +35 -0
- data/lib/dtrace.rb +74 -0
- data/lib/dtraceconsumer.rb +9 -0
- data/plugin/dtrace/README +81 -0
- data/plugin/dtrace/Rakefile +22 -0
- data/plugin/dtrace/bin/dtracer.rb +29 -0
- data/plugin/dtrace/init.rb +7 -0
- data/plugin/dtrace/lib/dtrace_helper.rb +2 -0
- data/plugin/dtrace/lib/dtrace_report.rb +67 -0
- data/plugin/dtrace/lib/dtracer.rb +52 -0
- data/plugin/dtrace/lib/dtracer_client.rb +26 -0
- data/plugin/dtrace/public/stylesheets/dtrace.css +48 -0
- data/plugin/dtrace/scripts/default.d +11 -0
- data/plugin/dtrace/scripts/rails_mysql.d +29 -0
- data/plugin/dtrace/tasks/dtrace.rake +52 -0
- data/plugin/dtrace/test/dtrace_test.rb +8 -0
- data/plugin/dtrace/views/dtrace/_report.rhtml +26 -0
- 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 +60 -0
- data/test/test_dof_generator.rb +142 -0
- data/test/test_dof_helper.rb +106 -0
- data/test/test_dof_parser.rb +25 -0
- data/test/test_dof_providers.rb +282 -0
- data/test/test_dof_strtabs.rb +92 -0
- data/test/test_dtrace.rb +111 -0
- data/test/test_dtrace_aggregates.rb +56 -0
- data/test/test_dtrace_drops_errors.rb +183 -0
- data/test/test_dtrace_probe.rb +383 -0
- data/test/test_dtrace_probes.rb +400 -0
- data/test/test_dtrace_processes.rb +83 -0
- data/test/test_dtrace_profile.rb +232 -0
- data/test/test_dtrace_provider.rb +153 -0
- data/test/test_dtrace_repeat.rb +51 -0
- data/test/test_dtrace_rubyprobe.rb +52 -0
- data/test/test_dtrace_typefilter.rb +108 -0
- data/test/test_legacy_consumer.rb +56 -0
- metadata +165 -0
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
|
+
|