ruby-dtrace 0.0.1 → 0.0.2
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 +7 -0
- data/Manifest.txt +10 -1
- data/Rakefile +3 -1
- data/ext/dtrace_aggdata.c +139 -0
- data/ext/dtrace_api.c +17 -9
- data/ext/dtrace_api.h +15 -7
- data/ext/dtrace_bufdata.c +91 -0
- data/ext/dtrace_hdl.c +101 -0
- data/ext/dtrace_probedata.c +129 -0
- data/ext/dtrace_recdesc.c +0 -23
- data/ext/dtrace_util.c +91 -0
- data/ext/extconf.rb +1 -1
- data/lib/dtrace.rb +6 -1
- data/lib/dtraceaggregate.rb +13 -0
- data/lib/dtraceconsumer.rb +99 -0
- data/lib/dtraceprobe.rb +13 -0
- data/lib/dtraceprobedata.rb +16 -0
- data/lib/dtracerecord.rb +8 -0
- data/plugin/dtrace/lib/dtracer.rb +6 -5
- data/test/test_dtrace.rb +0 -306
- data/test/test_dtrace_workapi.rb +142 -0
- metadata +13 -3
- data/ext/dtrace_aggregate.c +0 -150
data/test/test_dtrace.rb
CHANGED
@@ -97,126 +97,6 @@ class TestDtrace < Test::Unit::TestCase
|
|
97
97
|
assert_equal 4, t.status # stopped
|
98
98
|
end
|
99
99
|
|
100
|
-
def test_aggregate_print
|
101
|
-
t = Dtrace.new
|
102
|
-
|
103
|
-
t.setopt("aggsize", "4m")
|
104
|
-
t.setopt("bufsize", "4m")
|
105
|
-
|
106
|
-
progtext = "syscall:::entry
|
107
|
-
{
|
108
|
-
@calls[execname] = count();
|
109
|
-
@fcalls[probefunc] = count();
|
110
|
-
}"
|
111
|
-
|
112
|
-
prog = t.compile progtext
|
113
|
-
assert prog
|
114
|
-
prog.execute
|
115
|
-
|
116
|
-
t.go
|
117
|
-
sleep 1
|
118
|
-
t.stop
|
119
|
-
|
120
|
-
t.aggregate_snap
|
121
|
-
t.aggregate_print
|
122
|
-
end
|
123
|
-
|
124
|
-
def test_aggregate_walk
|
125
|
-
t = Dtrace.new
|
126
|
-
|
127
|
-
t.setopt("aggsize", "4m")
|
128
|
-
t.setopt("bufsize", "4m")
|
129
|
-
|
130
|
-
progtext = "syscall:::entry
|
131
|
-
{
|
132
|
-
@fcalls[probefunc] = count();
|
133
|
-
@calls[execname] = count();
|
134
|
-
}"
|
135
|
-
|
136
|
-
prog = t.compile progtext
|
137
|
-
assert prog
|
138
|
-
prog.execute
|
139
|
-
|
140
|
-
t.go
|
141
|
-
sleep 1
|
142
|
-
t.stop
|
143
|
-
|
144
|
-
t.aggregate_snap
|
145
|
-
|
146
|
-
t.each_aggregate do |agg|
|
147
|
-
agg.each_record do |rec|
|
148
|
-
assert rec
|
149
|
-
assert rec.data
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
def test_aggregate_record_array
|
155
|
-
t = Dtrace.new
|
156
|
-
|
157
|
-
t.setopt("aggsize", "4m")
|
158
|
-
t.setopt("bufsize", "4m")
|
159
|
-
|
160
|
-
progtext = "syscall:::entry
|
161
|
-
{
|
162
|
-
@calls[execname] = count();
|
163
|
-
}"
|
164
|
-
|
165
|
-
prog = t.compile progtext
|
166
|
-
assert prog
|
167
|
-
prog.execute
|
168
|
-
|
169
|
-
t.go
|
170
|
-
sleep 1
|
171
|
-
t.stop
|
172
|
-
|
173
|
-
t.aggregate_snap
|
174
|
-
|
175
|
-
t.each_aggregate do |agg|
|
176
|
-
assert agg
|
177
|
-
assert agg.num_records
|
178
|
-
(0..(agg.num_records - 1)).each do |i|
|
179
|
-
rec = agg[i]
|
180
|
-
assert rec.data
|
181
|
-
end
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
def test_aggregate_record_array_continuous
|
186
|
-
t = Dtrace.new
|
187
|
-
|
188
|
-
t.setopt("aggsize", "4m")
|
189
|
-
t.setopt("bufsize", "4m")
|
190
|
-
|
191
|
-
progtext = "syscall:::entry
|
192
|
-
{
|
193
|
-
@calls[execname] = count();
|
194
|
-
}"
|
195
|
-
|
196
|
-
prog = t.compile progtext
|
197
|
-
assert prog
|
198
|
-
prog.execute
|
199
|
-
|
200
|
-
t.go
|
201
|
-
|
202
|
-
(1..10).each do
|
203
|
-
sleep 1
|
204
|
-
t.aggregate_snap
|
205
|
-
|
206
|
-
t.each_aggregate do |agg|
|
207
|
-
assert agg
|
208
|
-
assert agg.num_records
|
209
|
-
(0..(agg.num_records - 1)).each do |i|
|
210
|
-
rec = agg[i]
|
211
|
-
assert rec.data
|
212
|
-
end
|
213
|
-
end
|
214
|
-
t.aggregate_clear
|
215
|
-
end
|
216
|
-
|
217
|
-
t.stop
|
218
|
-
end
|
219
|
-
|
220
100
|
def test_bad_program
|
221
101
|
t = Dtrace.new
|
222
102
|
progtext = "blah blahb albhacasfas"
|
@@ -225,191 +105,5 @@ class TestDtrace < Test::Unit::TestCase
|
|
225
105
|
end
|
226
106
|
assert_equal "probe description :::blah does not match any probes", e.message
|
227
107
|
end
|
228
|
-
|
229
|
-
def test_rubys_own_dtrace
|
230
|
-
t = Dtrace.new
|
231
|
-
|
232
|
-
t.setopt("aggsize", "4m")
|
233
|
-
t.setopt("bufsize", "4m")
|
234
|
-
|
235
|
-
progtext = "ruby*:::function-entry{ @[copyinstr(arg1)] = count(); }"
|
236
|
-
|
237
|
-
prog = t.compile progtext
|
238
|
-
assert prog
|
239
|
-
prog.execute
|
240
|
-
|
241
|
-
t.go
|
242
|
-
|
243
|
-
foo = 0
|
244
|
-
(1..1000).each do |i|
|
245
|
-
foo = foo + i
|
246
|
-
end
|
247
|
-
|
248
|
-
t.stop
|
249
|
-
t.aggregate_snap
|
250
|
-
|
251
|
-
t.each_aggregate do |agg|
|
252
|
-
assert agg
|
253
|
-
assert agg.num_records
|
254
|
-
(0..(agg.num_records - 1)).each do |i|
|
255
|
-
rec = agg[i]
|
256
|
-
assert rec.data
|
257
|
-
end
|
258
|
-
end
|
259
|
-
end
|
260
|
-
|
261
|
-
def test_multiple_programs
|
262
|
-
t = Dtrace.new
|
263
|
-
|
264
|
-
t.setopt("aggsize", "4m")
|
265
|
-
t.setopt("bufsize", "4m")
|
266
|
-
|
267
|
-
progtext = "syscall:::entry
|
268
|
-
{
|
269
|
-
@calls[execname] = count();
|
270
|
-
}"
|
271
|
-
|
272
|
-
prog1 = t.compile progtext
|
273
|
-
assert prog1
|
274
|
-
|
275
|
-
progtext = "syscall:::entry
|
276
|
-
{
|
277
|
-
@fcalls[probefunc] = count();
|
278
|
-
}"
|
279
|
-
|
280
|
-
prog2 = t.compile progtext
|
281
|
-
assert prog2
|
282
|
-
|
283
|
-
prog1.execute
|
284
|
-
prog2.execute
|
285
|
-
|
286
|
-
info1 = prog1.info
|
287
|
-
assert info1
|
288
|
-
assert_equal 1, info1.aggregates_count
|
289
|
-
assert_equal 0, info1.speculations_count
|
290
|
-
assert_equal 2, info1.recgens_count
|
291
|
-
assert info1.matches_count
|
292
|
-
|
293
|
-
info2 = prog2.info
|
294
|
-
assert info2
|
295
|
-
assert_equal 1, info2.aggregates_count
|
296
|
-
assert_equal 0, info2.speculations_count
|
297
|
-
assert_equal 2, info2.recgens_count
|
298
|
-
assert info2.matches_count
|
299
|
-
|
300
|
-
t.go
|
301
|
-
sleep 2
|
302
|
-
t.stop
|
303
|
-
t.aggregate_snap
|
304
|
-
|
305
|
-
t.each_aggregate do |agg|
|
306
|
-
assert agg
|
307
|
-
assert agg.num_records
|
308
|
-
(0..(agg.num_records - 1)).each do |i|
|
309
|
-
rec = agg[i]
|
310
|
-
assert rec.data
|
311
|
-
end
|
312
|
-
end
|
313
|
-
end
|
314
|
-
|
315
|
-
def test_multiple_runs
|
316
|
-
t = Dtrace.new
|
317
|
-
t.setopt("aggsize", "4m")
|
318
|
-
t.setopt("bufsize", "4m")
|
319
|
-
|
320
|
-
progtext = "ruby*:::function-entry{ @[copyinstr(arg1)] = count(); }"
|
321
|
-
|
322
|
-
prog = t.compile progtext
|
323
|
-
assert prog
|
324
|
-
prog.execute
|
325
|
-
|
326
|
-
t.go
|
327
|
-
|
328
|
-
foo = 0
|
329
|
-
(1..1000).each do |i|
|
330
|
-
foo = foo + i
|
331
|
-
end
|
332
|
-
|
333
|
-
t.stop
|
334
|
-
t.aggregate_snap
|
335
|
-
|
336
|
-
t.each_aggregate do |agg|
|
337
|
-
assert agg
|
338
|
-
assert agg.num_records
|
339
|
-
(0..(agg.num_records - 1)).each do |i|
|
340
|
-
rec = agg[i]
|
341
|
-
assert rec.data
|
342
|
-
end
|
343
|
-
end
|
344
|
-
|
345
|
-
t = Dtrace.new
|
346
|
-
t.setopt("aggsize", "4m")
|
347
|
-
t.setopt("bufsize", "4m")
|
348
|
-
|
349
|
-
prog = t.compile progtext
|
350
|
-
assert prog
|
351
|
-
|
352
|
-
prog.execute
|
353
|
-
|
354
|
-
t.go
|
355
|
-
|
356
|
-
foo = 0
|
357
|
-
(1..1000).each do |i|
|
358
|
-
foo = foo + i
|
359
|
-
end
|
360
|
-
|
361
|
-
t.stop
|
362
|
-
t.aggregate_snap
|
363
|
-
|
364
|
-
t.each_aggregate do |agg|
|
365
|
-
assert agg
|
366
|
-
assert agg.num_records
|
367
|
-
(0..(agg.num_records - 1)).each do |i|
|
368
|
-
rec = agg[i]
|
369
|
-
assert rec.data
|
370
|
-
end
|
371
|
-
end
|
372
|
-
|
373
|
-
end
|
374
|
-
|
375
|
-
def test_aggdata_probe
|
376
|
-
t = Dtrace.new
|
377
|
-
|
378
|
-
t.setopt("aggsize", "4m")
|
379
|
-
t.setopt("bufsize", "4m")
|
380
|
-
|
381
|
-
progtext = "ruby*:::function-entry{ @[copyinstr(arg1)] = count(); }"
|
382
|
-
|
383
|
-
prog = t.compile progtext
|
384
|
-
assert prog
|
385
|
-
prog.execute
|
386
|
-
|
387
|
-
t.go
|
388
|
-
|
389
|
-
foo = 0
|
390
|
-
(1..1000).each do |i|
|
391
|
-
foo = foo + i
|
392
|
-
end
|
393
|
-
|
394
|
-
t.stop
|
395
|
-
|
396
|
-
t.aggregate_snap
|
397
|
-
|
398
|
-
t.each_aggregate do |agg|
|
399
|
-
|
400
|
-
probe = agg.probe
|
401
|
-
assert probe.provider
|
402
|
-
assert probe.mod
|
403
|
-
assert probe.func
|
404
|
-
assert probe.name
|
405
|
-
|
406
|
-
agg.each_record do |rec|
|
407
|
-
assert rec
|
408
|
-
assert rec.data
|
409
|
-
end
|
410
|
-
end
|
411
|
-
|
412
|
-
|
413
|
-
end
|
414
108
|
|
415
109
|
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'dtrace'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
class TestDtrace < Test::Unit::TestCase
|
5
|
+
def test_dtrace
|
6
|
+
t = Dtrace.new
|
7
|
+
assert t
|
8
|
+
assert_equal Object, Dtrace.superclass
|
9
|
+
assert_equal Dtrace, t.class
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_work_dprogram_compile
|
13
|
+
t = Dtrace.new
|
14
|
+
assert t
|
15
|
+
|
16
|
+
progtext = "syscall::select:entry { trace(probefunc); trace(execname); }"
|
17
|
+
|
18
|
+
prog = t.compile progtext
|
19
|
+
assert prog
|
20
|
+
prog.execute
|
21
|
+
|
22
|
+
info = prog.info
|
23
|
+
assert info
|
24
|
+
assert_equal 1, info.matches_count
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_work_dprogram_run
|
28
|
+
t = Dtrace.new
|
29
|
+
t.setopt("bufsize", "4m")
|
30
|
+
t.setopt("aggsize", "4m")
|
31
|
+
|
32
|
+
progtext = "syscall:::entry { trace(probefunc); trace(execname); }"
|
33
|
+
|
34
|
+
prog = t.compile progtext
|
35
|
+
prog.execute
|
36
|
+
|
37
|
+
c = DtraceConsumer.new(t)
|
38
|
+
assert c
|
39
|
+
|
40
|
+
begin
|
41
|
+
i = 0
|
42
|
+
c.consume do |e|
|
43
|
+
assert e
|
44
|
+
assert e.probedesc
|
45
|
+
assert_equal 'syscall', e.probedesc.provider
|
46
|
+
assert_equal 'entry', e.probedesc.name
|
47
|
+
records = e.records
|
48
|
+
assert records
|
49
|
+
assert_equal 2, records.length
|
50
|
+
assert_equal DtraceRecord, records[0].class
|
51
|
+
assert_equal DtraceRecord, records[1].class
|
52
|
+
|
53
|
+
i = i + 1
|
54
|
+
if i > 10
|
55
|
+
break
|
56
|
+
end
|
57
|
+
end
|
58
|
+
rescue Interrupt
|
59
|
+
puts "interrupted"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_work_dprogram_aggregates
|
64
|
+
t = Dtrace.new
|
65
|
+
t.setopt("bufsize", "4m")
|
66
|
+
t.setopt("aggsize", "4m")
|
67
|
+
|
68
|
+
progtext = <<EOD
|
69
|
+
ruby*:::function-entry
|
70
|
+
{
|
71
|
+
@a[execname, copyinstr(arg1), copyinstr(arg2)] = count();
|
72
|
+
printf("foo");
|
73
|
+
}
|
74
|
+
|
75
|
+
profile-10
|
76
|
+
{
|
77
|
+
printa(@a)
|
78
|
+
}
|
79
|
+
EOD
|
80
|
+
|
81
|
+
prog = t.compile progtext
|
82
|
+
prog.execute
|
83
|
+
|
84
|
+
c = DtraceConsumer.new(t)
|
85
|
+
|
86
|
+
begin
|
87
|
+
i = 0
|
88
|
+
c.consume do |e|
|
89
|
+
assert e
|
90
|
+
case e.class.to_s
|
91
|
+
when "DtraceProbeData"
|
92
|
+
assert e.probedesc
|
93
|
+
e.each_record do |r|
|
94
|
+
assert r.value
|
95
|
+
end
|
96
|
+
when "DtraceRecord"
|
97
|
+
assert e.value
|
98
|
+
when "DtraceAggregate"
|
99
|
+
assert e.value
|
100
|
+
assert e.tuple
|
101
|
+
assert_equal 3, e.tuple.length
|
102
|
+
end
|
103
|
+
|
104
|
+
i = i + 1
|
105
|
+
if i > 100
|
106
|
+
break
|
107
|
+
end
|
108
|
+
end
|
109
|
+
rescue Interrupt
|
110
|
+
puts "interrupted"
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_work_dprogram_once
|
116
|
+
t = Dtrace.new
|
117
|
+
t.setopt("bufsize", "4m")
|
118
|
+
t.setopt("aggsize", "4m")
|
119
|
+
|
120
|
+
progtext = "ruby*:::function-entry{ @a[execname, copyinstr(arg1), copyinstr(arg2)] = count(); } END { printa(@a); }"
|
121
|
+
|
122
|
+
prog = t.compile progtext
|
123
|
+
prog.execute
|
124
|
+
|
125
|
+
t.go
|
126
|
+
|
127
|
+
foo = 0
|
128
|
+
(1..1000).each do |i|
|
129
|
+
foo = foo + i
|
130
|
+
end
|
131
|
+
|
132
|
+
c = DtraceConsumer.new(t)
|
133
|
+
c.consume_once do |e|
|
134
|
+
if e && e.class == DtraceAggregate
|
135
|
+
assert e.value
|
136
|
+
assert e.tuple
|
137
|
+
assert_equal 3, e.tuple.length
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|