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.
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