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
@@ -28,6 +28,72 @@ class TestDtrace < Test::Unit::TestCase
28
28
  assert probe_count
29
29
  end
30
30
 
31
+ def test_list_probes_match
32
+ t = Dtrace.new
33
+ probe_count = 0
34
+ t.each_probe('syscall:::') do |probe|
35
+ assert probe.provider
36
+ assert probe.mod
37
+ assert probe.func
38
+ assert probe.name
39
+ probe_count += 1
40
+ end
41
+ assert probe_count
42
+ end
43
+
44
+ def test_list_probes_match_usdt
45
+ t = Dtrace.new
46
+ probe_count = 0
47
+ t.each_probe("pid#{$$}:::return") do |probe|
48
+ puts probe
49
+ assert probe.provider
50
+ assert probe.mod
51
+ assert probe.func
52
+ assert probe.name
53
+ probe_count += 1
54
+ end
55
+ assert probe_count
56
+ end
57
+
58
+ def test_list_probes_match_prog
59
+ t = Dtrace.new
60
+
61
+ progtext = "syscall:::return
62
+ {
63
+ @calls[execname] = count();
64
+ @fcalls[probefunc] = count();
65
+ }
66
+
67
+ syscall:::entry
68
+ /pid == $1/
69
+ {
70
+ @calls[execname] = count();
71
+ @fcalls[probefunc] = count();
72
+ }"
73
+ prog = t.compile(progtext, $$.to_s)
74
+ prog.execute
75
+
76
+ probe_count = 0
77
+ t.each_probe_prog(prog) do |probe|
78
+ assert probe.provider
79
+ assert probe.mod
80
+ assert probe.func
81
+ assert probe.name
82
+ probe_count += 1
83
+ end
84
+ assert probe_count
85
+ end
86
+
87
+ def test_list_probes_match_badpattern
88
+ t = Dtrace.new
89
+ probe_count = 0
90
+ assert_raises Dtrace::Exception do
91
+ t.each_probe('syscall') do |probe|
92
+ nil
93
+ end
94
+ end
95
+ end
96
+
31
97
  def test_compile
32
98
  t = Dtrace.new
33
99
 
@@ -102,7 +168,7 @@ class TestDtrace < Test::Unit::TestCase
102
168
  def test_bad_program
103
169
  t = Dtrace.new
104
170
  progtext = "blah blahb albhacasfas"
105
- e = assert_raise DtraceException do
171
+ e = assert_raise Dtrace::Exception do
106
172
  prog = t.compile progtext
107
173
  end
108
174
  assert_equal "probe description :::blah does not match any probes", e.message
@@ -21,7 +21,7 @@ profile-1000
21
21
  @b[execname] = count();
22
22
  }
23
23
 
24
- profile-10
24
+ profile-1
25
25
  {
26
26
  printa(@a);
27
27
  printa(@b);
@@ -32,9 +32,9 @@ EOD
32
32
  prog.execute
33
33
  t.go
34
34
 
35
- sleep 1
35
+ sleep 3
36
36
 
37
- c = DtraceConsumer.new(t)
37
+ c = Dtrace::Consumer.new(t)
38
38
  assert c
39
39
 
40
40
  data = []
@@ -45,9 +45,9 @@ EOD
45
45
  assert data.length > 0
46
46
  data.each do |d|
47
47
  assert d
48
- assert_equal DtraceData, d.class
48
+ assert_equal Dtrace::Data, d.class
49
49
  d.data.each do |agg|
50
- assert_equal DtraceAggregateSet, agg.class
50
+ assert_equal Dtrace::AggregateSet, agg.class
51
51
  end
52
52
  end
53
53
 
@@ -34,7 +34,7 @@ EOD
34
34
  prog = t.compile progtext
35
35
  prog.execute
36
36
 
37
- c = DtraceConsumer.new(t)
37
+ c = Dtrace::Consumer.new(t)
38
38
  assert c
39
39
 
40
40
  i = 0
@@ -70,12 +70,12 @@ EOD
70
70
  prog.execute
71
71
  t.go
72
72
 
73
- c = DtraceConsumer.new(t)
73
+ c = Dtrace::Consumer.new(t)
74
74
  assert c
75
75
 
76
76
  # since we've already said "go", we now can't apply an error
77
77
  # handler (DTrace will let us, but won't call it).
78
- assert_raise(DtraceException) do
78
+ assert_raise(Dtrace::Exception) do
79
79
  c.errhandler do |d|
80
80
  # nothing
81
81
  end
@@ -98,7 +98,7 @@ EOD
98
98
  prog = t.compile progtext
99
99
  prog.execute
100
100
 
101
- c = DtraceConsumer.new(t)
101
+ c = Dtrace::Consumer.new(t)
102
102
  assert c
103
103
 
104
104
  i = 0
@@ -148,7 +148,7 @@ EOD
148
148
  prog = t.compile progtext
149
149
  prog.execute
150
150
 
151
- c = DtraceConsumer.new(t)
151
+ c = Dtrace::Consumer.new(t)
152
152
  assert c
153
153
 
154
154
  errors = 0
@@ -0,0 +1,385 @@
1
+ #
2
+ # Ruby-Dtrace
3
+ # (c) 2008 Chris Andrews <chris@nodnol.org>
4
+ #
5
+
6
+ require 'dtrace'
7
+ require 'dtrace/dof'
8
+ require 'test/unit'
9
+
10
+ class TestDtraceProbe < Test::Unit::TestCase
11
+ include Dtrace::Dof::Constants
12
+
13
+ def test_probe
14
+ p = Dtrace::Probe.new(0)
15
+ end
16
+
17
+ def test_fire_probe
18
+ p = Dtrace::Probe.new(0)
19
+ p.fire
20
+ end
21
+
22
+ def test_is_probe_not_enabled
23
+ p = Dtrace::Probe.new(0)
24
+ assert !p.is_enabled?
25
+ end
26
+
27
+ def test_fire_probe_no_args
28
+ probe = Dtrace::Probe.new(0)
29
+ addr = probe.addr
30
+
31
+ f = Dtrace::Dof::File.new
32
+ f.allocate(4096)
33
+
34
+ s = Dtrace::Dof::Section.new(DOF_SECT_STRTAB, 0)
35
+ s.data = ['args', 'main', 'testprobe']
36
+ f.sections << s
37
+
38
+ s = Dtrace::Dof::Section.new(DOF_SECT_PROBES, 1)
39
+ s.data = [
40
+ {
41
+ :noffs => 1,
42
+ :enoffidx => 0,
43
+ :argidx => 0,
44
+ :name => 1,
45
+ :nenoffs => 1,
46
+ :offidx => 0,
47
+ :addr => addr,
48
+ :nargc => 0,
49
+ :func => 6,
50
+ :xargc => 0
51
+ },
52
+ ]
53
+ f.sections << s
54
+
55
+ s = Dtrace::Dof::Section.new(DOF_SECT_PRARGS, 2)
56
+ s.data = [ 0 ]
57
+ f.sections << s
58
+
59
+ s = Dtrace::Dof::Section.new(DOF_SECT_PROFFS, 3)
60
+ s.data = [ probe.probe_offset(f.addr, 0) ]
61
+ f.sections << s
62
+
63
+ s = Dtrace::Dof::Section.new(DOF_SECT_PRENOFFS, 4)
64
+ s.data = [ probe.is_enabled_offset(f.addr) ]
65
+ f.sections << s
66
+
67
+ s = Dtrace::Dof::Section.new(DOF_SECT_PROVIDER, 5)
68
+ s.data = {
69
+ :strtab => 0,
70
+ :probes => 1,
71
+ :prargs => 2,
72
+ :proffs => 3,
73
+ :prenoffs => 4,
74
+ :name => 11,
75
+ :provattr => { :name => 5, :data => 5, :class => 5 },
76
+ :modattr => { :name => 1, :data => 1, :class => 5 },
77
+ :funcattr => { :name => 1, :data => 1, :class => 5 },
78
+ :nameattr => { :name => 5, :data => 5, :class => 5 },
79
+ :argsattr => { :name => 5, :data => 5, :class => 5 }
80
+ }
81
+ f.sections << s
82
+
83
+ f.generate
84
+ Dtrace::Dof.loaddof(f, 'testmodule')
85
+
86
+ t = Dtrace.new
87
+ t.setopt("bufsize", "4m")
88
+
89
+ matches = 0
90
+ t.each_probe("testprobe#{$$}:testmodule:main:args") do |p|
91
+ matches += 1
92
+ end
93
+ assert_equal 1, matches
94
+
95
+ progtext = <<EOD
96
+ test*:testmodule:main:args
97
+ {
98
+ trace("fired!");
99
+ }
100
+ EOD
101
+
102
+ prog = t.compile progtext
103
+ prog.execute
104
+ t.go
105
+ c = Dtrace::Consumer.new(t)
106
+
107
+ probe.fire
108
+
109
+ data = []
110
+ c.consume_once do |d|
111
+ data << d
112
+ end
113
+
114
+ assert_equal 1, data.length
115
+ assert_equal 'fired!', data[0].data[0].value
116
+ end
117
+
118
+ def test_fire_probe_two_int_args
119
+ probe = Dtrace::Probe.new(2)
120
+ addr = probe.addr
121
+
122
+ f = Dtrace::Dof::File.new
123
+ f.allocate(4096)
124
+
125
+ s = Dtrace::Dof::Section.new(DOF_SECT_STRTAB, 0)
126
+ s.data = ['test', 'main', 'tes2', 'int', 'int', 'int', 'int']
127
+ f.sections << s
128
+
129
+ s = Dtrace::Dof::Section.new(DOF_SECT_PROBES, 1)
130
+ s.data = [
131
+ {
132
+ :nargv => 16,
133
+ :noffs => 1,
134
+ :xargv => 24,
135
+ :enoffidx => 0,
136
+ :argidx => 0,
137
+ :name => 1,
138
+ :nenoffs => 1,
139
+ :offidx => 0,
140
+ :addr => addr,
141
+ :nargc => 2,
142
+ :func => 6,
143
+ :xargc => 2
144
+ },
145
+ ]
146
+ f.sections << s
147
+
148
+ s = Dtrace::Dof::Section.new(DOF_SECT_PRARGS, 2)
149
+ s.data = [ 0, 1 ]
150
+ f.sections << s
151
+
152
+ s = Dtrace::Dof::Section.new(DOF_SECT_PROFFS, 3)
153
+ s.data = [ probe.probe_offset(f.addr, 2) ]
154
+ f.sections << s
155
+
156
+ s = Dtrace::Dof::Section.new(DOF_SECT_PRENOFFS, 4)
157
+ s.data = [ probe.is_enabled_offset(f.addr) ]
158
+ f.sections << s
159
+
160
+ s = Dtrace::Dof::Section.new(DOF_SECT_PROVIDER, 5)
161
+ s.data = {
162
+ :strtab => 0,
163
+ :probes => 1,
164
+ :prargs => 2,
165
+ :proffs => 3,
166
+ :prenoffs => 4,
167
+ :name => 11,
168
+ :provattr => { :name => 5, :data => 5, :class => 5 },
169
+ :modattr => { :name => 1, :data => 1, :class => 5 },
170
+ :funcattr => { :name => 1, :data => 1, :class => 5 },
171
+ :nameattr => { :name => 5, :data => 5, :class => 5 },
172
+ :argsattr => { :name => 5, :data => 5, :class => 5 }
173
+ }
174
+ f.sections << s
175
+
176
+ f.generate
177
+ Dtrace::Dof.loaddof(f, 'testmodule')
178
+
179
+ t = Dtrace.new
180
+ t.setopt("bufsize", "4m")
181
+
182
+ progtext = <<EOD
183
+ tes2*:testmodule:main:test
184
+ {
185
+ trace(arg0);
186
+ trace(arg1);
187
+ }
188
+ EOD
189
+
190
+ prog = t.compile progtext
191
+ prog.execute
192
+ t.go
193
+ c = Dtrace::Consumer.new(t)
194
+
195
+ probe.fire(41, 42)
196
+
197
+ data = []
198
+ c.consume_once do |d|
199
+ data << d
200
+ end
201
+
202
+ assert_equal 1, data.length
203
+ assert_equal 41, data[0].data[0].value
204
+ assert_equal 42, data[0].data[1].value
205
+ end
206
+
207
+ def test_fire_probe_two_charstar_args
208
+ probe = Dtrace::Probe.new(2)
209
+ addr = probe.addr
210
+
211
+ f = Dtrace::Dof::File.new
212
+ f.allocate(4096)
213
+
214
+ s = Dtrace::Dof::Section.new(DOF_SECT_STRTAB, 0)
215
+ s.data = ['test', 'main', 'tes3', 'char *', 'char *', 'char *', 'char *']
216
+ f.sections << s
217
+
218
+ s = Dtrace::Dof::Section.new(DOF_SECT_PROBES, 1)
219
+ s.data = [
220
+ {
221
+ :nargv => 16,
222
+ :noffs => 1,
223
+ :xargv => 30,
224
+ :enoffidx => 0,
225
+ :argidx => 0,
226
+ :name => 1,
227
+ :nenoffs => 1,
228
+ :offidx => 0,
229
+ :addr => addr,
230
+ :nargc => 2,
231
+ :func => 6,
232
+ :xargc => 2
233
+ },
234
+ ]
235
+ f.sections << s
236
+
237
+ s = Dtrace::Dof::Section.new(DOF_SECT_PRARGS, 2)
238
+ s.data = [ 0, 1 ]
239
+ f.sections << s
240
+
241
+ s = Dtrace::Dof::Section.new(DOF_SECT_PROFFS, 3)
242
+ s.data = [ probe.probe_offset(f.addr, 2) ]
243
+ f.sections << s
244
+
245
+ s = Dtrace::Dof::Section.new(DOF_SECT_PRENOFFS, 4)
246
+ s.data = [ probe.is_enabled_offset(f.addr) ]
247
+ f.sections << s
248
+
249
+ s = Dtrace::Dof::Section.new(DOF_SECT_PROVIDER, 5)
250
+ s.data = {
251
+ :strtab => 0,
252
+ :probes => 1,
253
+ :prargs => 2,
254
+ :proffs => 3,
255
+ :prenoffs => 4,
256
+ :name => 11,
257
+ :provattr => { :name => 5, :data => 5, :class => 5 },
258
+ :modattr => { :name => 1, :data => 1, :class => 5 },
259
+ :funcattr => { :name => 1, :data => 1, :class => 5 },
260
+ :nameattr => { :name => 5, :data => 5, :class => 5 },
261
+ :argsattr => { :name => 5, :data => 5, :class => 5 }
262
+ }
263
+ f.sections << s
264
+
265
+ f.generate
266
+ Dtrace::Dof.loaddof(f, 'testmodule')
267
+
268
+ t = Dtrace.new
269
+ t.setopt("bufsize", "4m")
270
+
271
+ progtext = <<EOD
272
+ tes3*:testmodule:main:test
273
+ {
274
+ trace(copyinstr(arg0));
275
+ trace(copyinstr(arg1));
276
+ }
277
+ EOD
278
+
279
+ prog = t.compile progtext
280
+ prog.execute
281
+ t.go
282
+ c = Dtrace::Consumer.new(t)
283
+
284
+ probe.fire('foo', 'bar')
285
+
286
+ data = []
287
+ c.consume_once do |d|
288
+ data << d
289
+ end
290
+
291
+ assert_equal 1, data.length
292
+ assert_equal 'foo', data[0].data[0].value
293
+ assert_equal 'bar', data[0].data[1].value
294
+ end
295
+
296
+ def test_probe_is_enabled
297
+ probe = Dtrace::Probe.new(0)
298
+ addr = probe.addr
299
+
300
+ f = Dtrace::Dof::File.new
301
+ f.allocate(4096)
302
+
303
+ s = Dtrace::Dof::Section.new(DOF_SECT_STRTAB, 0)
304
+ s.data = ['test', 'main', 'tes4']
305
+ f.sections << s
306
+
307
+ s = Dtrace::Dof::Section.new(DOF_SECT_PROBES, 1)
308
+ s.data = [
309
+ {
310
+ :noffs => 1,
311
+ :enoffidx => 0,
312
+ :argidx => 0,
313
+ :name => 1,
314
+ :nenoffs => 1,
315
+ :offidx => 0,
316
+ :addr => addr,
317
+ :nargc => 0,
318
+ :func => 6,
319
+ :xargc => 0
320
+ },
321
+ ]
322
+ f.sections << s
323
+
324
+ s = Dtrace::Dof::Section.new(DOF_SECT_PRARGS, 2)
325
+ s.data = [ 0 ]
326
+ f.sections << s
327
+
328
+ s = Dtrace::Dof::Section.new(DOF_SECT_PROFFS, 3)
329
+ s.data = [ probe.probe_offset(f.addr, 0) ]
330
+ f.sections << s
331
+
332
+ s = Dtrace::Dof::Section.new(DOF_SECT_PRENOFFS, 4)
333
+ s.data = [ probe.is_enabled_offset(f.addr) ]
334
+ f.sections << s
335
+
336
+ s = Dtrace::Dof::Section.new(DOF_SECT_PROVIDER, 5)
337
+ s.data = {
338
+ :strtab => 0,
339
+ :probes => 1,
340
+ :prargs => 2,
341
+ :proffs => 3,
342
+ :prenoffs => 4,
343
+ :name => 11,
344
+ :provattr => { :name => 5, :data => 5, :class => 5 },
345
+ :modattr => { :name => 1, :data => 1, :class => 5 },
346
+ :funcattr => { :name => 1, :data => 1, :class => 5 },
347
+ :nameattr => { :name => 5, :data => 5, :class => 5 },
348
+ :argsattr => { :name => 5, :data => 5, :class => 5 }
349
+ }
350
+ f.sections << s
351
+
352
+ f.generate
353
+ Dtrace::Dof.loaddof(f, 'testmodule')
354
+
355
+ assert !probe.is_enabled?
356
+
357
+ t = Dtrace.new
358
+ t.setopt("bufsize", "4m")
359
+
360
+ progtext = <<EOD
361
+ tes4*:testmodule:main:test
362
+ {
363
+ trace("fired!");
364
+ }
365
+ EOD
366
+
367
+ prog = t.compile progtext
368
+ prog.execute
369
+ t.go
370
+
371
+ assert probe.is_enabled?
372
+
373
+ probe.fire
374
+
375
+ c = Dtrace::Consumer.new(t)
376
+ data = []
377
+ c.consume_once do |d|
378
+ data << d
379
+ end
380
+
381
+ assert_equal 1, data.length
382
+ assert_equal 'fired!', data[0].data[0].value
383
+ end
384
+
385
+ end