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.
Files changed (81) hide show
  1. data/History.txt +21 -0
  2. data/Manifest.txt +86 -19
  3. data/README.txt +48 -6
  4. data/Rakefile +61 -20
  5. data/examples/scsi.rb +1 -1
  6. data/ext/dof/Makefile +154 -0
  7. data/ext/dof/constants.c +57 -0
  8. data/ext/dof/dof.h +56 -0
  9. data/ext/dof/dof_api.c +58 -0
  10. data/ext/dof/dof_helper.c +82 -0
  11. data/ext/dof/extconf.rb +4 -0
  12. data/ext/dof/file.c +90 -0
  13. data/ext/dof/generator.c +9 -0
  14. data/ext/dof/header.c +79 -0
  15. data/ext/dof/mkmf.log +10 -0
  16. data/ext/dof/parser.c +415 -0
  17. data/ext/dof/parser.h +10 -0
  18. data/ext/dof/section.c +312 -0
  19. data/ext/dtrace_aggdata.c +2 -2
  20. data/ext/dtrace_api.c +46 -34
  21. data/ext/dtrace_api.h +31 -7
  22. data/ext/dtrace_bufdata.c +3 -3
  23. data/ext/dtrace_hdl.c +66 -3
  24. data/ext/dtrace_probedata.c +4 -4
  25. data/ext/{dtrace_probe.c → dtrace_probedesc.c} +7 -7
  26. data/ext/extconf.rb +25 -0
  27. data/ext/i386-darwin/dtrace_probe.c +278 -0
  28. data/ext/i386-solaris/dtrace_probe.c +225 -0
  29. data/ext/stubs.txt +78 -0
  30. data/lib/dtrace.rb +34 -13
  31. data/lib/dtrace/aggregate.rb +40 -0
  32. data/lib/dtrace/aggregateset.rb +19 -0
  33. data/lib/dtrace/consumer.rb +174 -0
  34. data/lib/dtrace/data.rb +82 -0
  35. data/lib/dtrace/dof.rb +8 -0
  36. data/lib/dtrace/dof/file.rb +64 -0
  37. data/lib/dtrace/dof/section.rb +75 -0
  38. data/lib/dtrace/dof/section/strtab.rb +28 -0
  39. data/lib/{dtraceprintfrecord.rb → dtrace/printfrecord.rb} +4 -2
  40. data/lib/dtrace/probe.rb +3 -6
  41. data/lib/dtrace/probedata.rb +23 -0
  42. data/lib/dtrace/probedesc.rb +15 -0
  43. data/lib/dtrace/provider.rb +190 -169
  44. data/lib/dtrace/provider/klass.rb +33 -0
  45. data/lib/dtrace/provider/probedef.rb +24 -0
  46. data/lib/{dtracerecord.rb → dtrace/record.rb} +4 -2
  47. data/lib/{dtracestackrecord.rb → dtrace/stackrecord.rb} +10 -8
  48. data/lib/dtrace/version.rb +9 -0
  49. data/lib/dtraceconsumer.rb +3 -167
  50. data/plugin/dtrace/lib/dtracer.rb +4 -4
  51. data/test/apple-dof +0 -0
  52. data/test/disabled_probe_effect.txt +19 -0
  53. data/test/dof +0 -0
  54. data/test/dof2 +0 -0
  55. data/test/test_disabled_probe_effect.rb +56 -0
  56. data/test/test_dof_generator.rb +142 -0
  57. data/test/test_dof_helper.rb +106 -0
  58. data/test/test_dof_parser.rb +27 -0
  59. data/test/test_dof_providers.rb +278 -0
  60. data/test/test_dof_strtabs.rb +98 -0
  61. data/test/test_dtrace.rb +67 -1
  62. data/test/test_dtrace_aggregates.rb +5 -5
  63. data/test/test_dtrace_drops_errors.rb +5 -5
  64. data/test/test_dtrace_probe.rb +385 -0
  65. data/test/test_dtrace_probes.rb +414 -0
  66. data/test/test_dtrace_processes.rb +2 -2
  67. data/test/test_dtrace_profile.rb +12 -12
  68. data/test/test_dtrace_provider.rb +138 -0
  69. data/test/test_dtrace_repeat.rb +1 -1
  70. data/test/test_dtrace_rubyprobe.rb +3 -1
  71. data/test/test_dtrace_typefilter.rb +9 -9
  72. data/test/test_legacy_consumer.rb +56 -0
  73. metadata +112 -71
  74. data/lib/dtrace/provider/osx.rb +0 -25
  75. data/lib/dtrace/provider/solaris.rb +0 -29
  76. data/lib/dtraceaggregate.rb +0 -37
  77. data/lib/dtraceaggregateset.rb +0 -17
  78. data/lib/dtracedata.rb +0 -80
  79. data/lib/dtraceprobe.rb +0 -13
  80. data/lib/dtraceprobedata.rb +0 -21
  81. data/test/test_dynusdt.rb +0 -135
@@ -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
+
@@ -0,0 +1,10 @@
1
+ /*
2
+ * Ruby-Dtrace
3
+ * (c) 2008 Chris Andrews <chris@nodnol.org>
4
+ */
5
+
6
+ #include <ruby.h>
7
+ #include <sys/dtrace.h>
8
+ #include <sys/utsname.h>
9
+
10
+ static VALUE dof_parse(VALUE self, VALUE dof);
@@ -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
+