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.
Files changed (88) hide show
  1. data/History.txt +34 -0
  2. data/Manifest.txt +58 -0
  3. data/README.txt +88 -0
  4. data/Rakefile +73 -0
  5. data/examples/scsi.rb +442 -0
  6. data/ext/dof/constants.c +49 -0
  7. data/ext/dof/dof.h +55 -0
  8. data/ext/dof/dof_api.c +57 -0
  9. data/ext/dof/dof_helper.c +82 -0
  10. data/ext/dof/extconf.rb +4 -0
  11. data/ext/dof/file.c +56 -0
  12. data/ext/dof/generator.c +9 -0
  13. data/ext/dof/header.c +80 -0
  14. data/ext/dof/parser.c +415 -0
  15. data/ext/dof/parser.h +10 -0
  16. data/ext/dof/section.c +302 -0
  17. data/ext/dtrace_aggdata.c +142 -0
  18. data/ext/dtrace_api.c +119 -0
  19. data/ext/dtrace_api.h +150 -0
  20. data/ext/dtrace_bufdata.c +139 -0
  21. data/ext/dtrace_dropdata.c +131 -0
  22. data/ext/dtrace_errdata.c +110 -0
  23. data/ext/dtrace_hdl.c +577 -0
  24. data/ext/dtrace_probedata.c +267 -0
  25. data/ext/dtrace_probedesc.c +78 -0
  26. data/ext/dtrace_process.c +37 -0
  27. data/ext/dtrace_program.c +62 -0
  28. data/ext/dtrace_programinfo.c +60 -0
  29. data/ext/dtrace_recdesc.c +46 -0
  30. data/ext/dtrace_util.c +92 -0
  31. data/ext/extconf.rb +28 -0
  32. data/ext/stubs.txt +78 -0
  33. data/lib/dtrace/aggregate.rb +40 -0
  34. data/lib/dtrace/aggregateset.rb +19 -0
  35. data/lib/dtrace/consumer.rb +174 -0
  36. data/lib/dtrace/data.rb +82 -0
  37. data/lib/dtrace/dof/file.rb +63 -0
  38. data/lib/dtrace/dof/section/strtab.rb +21 -0
  39. data/lib/dtrace/dof/section.rb +69 -0
  40. data/lib/dtrace/dof.rb +8 -0
  41. data/lib/dtrace/printfrecord.rb +10 -0
  42. data/lib/dtrace/probe.rb +46 -0
  43. data/lib/dtrace/probedata.rb +23 -0
  44. data/lib/dtrace/probedesc.rb +15 -0
  45. data/lib/dtrace/provider/probedef.rb +24 -0
  46. data/lib/dtrace/provider.rb +231 -0
  47. data/lib/dtrace/record.rb +11 -0
  48. data/lib/dtrace/stackrecord.rb +31 -0
  49. data/lib/dtrace/tracer.rb +35 -0
  50. data/lib/dtrace.rb +74 -0
  51. data/lib/dtraceconsumer.rb +9 -0
  52. data/plugin/dtrace/README +81 -0
  53. data/plugin/dtrace/Rakefile +22 -0
  54. data/plugin/dtrace/bin/dtracer.rb +29 -0
  55. data/plugin/dtrace/init.rb +7 -0
  56. data/plugin/dtrace/lib/dtrace_helper.rb +2 -0
  57. data/plugin/dtrace/lib/dtrace_report.rb +67 -0
  58. data/plugin/dtrace/lib/dtracer.rb +52 -0
  59. data/plugin/dtrace/lib/dtracer_client.rb +26 -0
  60. data/plugin/dtrace/public/stylesheets/dtrace.css +48 -0
  61. data/plugin/dtrace/scripts/default.d +11 -0
  62. data/plugin/dtrace/scripts/rails_mysql.d +29 -0
  63. data/plugin/dtrace/tasks/dtrace.rake +52 -0
  64. data/plugin/dtrace/test/dtrace_test.rb +8 -0
  65. data/plugin/dtrace/views/dtrace/_report.rhtml +26 -0
  66. data/test/apple-dof +0 -0
  67. data/test/disabled_probe_effect.txt +19 -0
  68. data/test/dof +0 -0
  69. data/test/dof2 +0 -0
  70. data/test/test_disabled_probe_effect.rb +60 -0
  71. data/test/test_dof_generator.rb +142 -0
  72. data/test/test_dof_helper.rb +106 -0
  73. data/test/test_dof_parser.rb +25 -0
  74. data/test/test_dof_providers.rb +282 -0
  75. data/test/test_dof_strtabs.rb +92 -0
  76. data/test/test_dtrace.rb +111 -0
  77. data/test/test_dtrace_aggregates.rb +56 -0
  78. data/test/test_dtrace_drops_errors.rb +183 -0
  79. data/test/test_dtrace_probe.rb +383 -0
  80. data/test/test_dtrace_probes.rb +400 -0
  81. data/test/test_dtrace_processes.rb +83 -0
  82. data/test/test_dtrace_profile.rb +232 -0
  83. data/test/test_dtrace_provider.rb +153 -0
  84. data/test/test_dtrace_repeat.rb +51 -0
  85. data/test/test_dtrace_rubyprobe.rb +52 -0
  86. data/test/test_dtrace_typefilter.rb +108 -0
  87. data/test/test_legacy_consumer.rb +56 -0
  88. metadata +165 -0
data/ext/stubs.txt ADDED
@@ -0,0 +1,78 @@
1
+ disassembly of C probe stub:
2
+
3
+ /* 3. void probe8(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) { */
4
+ /* <Function: probe8> */
5
+ /* [ 3] 805133c: pushl %ebp */
6
+ /* [ 3] 805133d: movl %esp,%ebp */
7
+ /* [ 3] 805133f: subl $8,%esp */
8
+ /* 4. TEST_TEST_INT_INT_INT_INT_INT_INT_INT_INT_PROBE(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); */
9
+ /* [ 4] 8051342: pushl 0x24(%ebp) */
10
+ /* [ 4] 8051345: pushl 0x20(%ebp) */
11
+ /* [ 4] 8051348: pushl 0x1c(%ebp) */
12
+ /* [ 4] 805134b: pushl 0x18(%ebp) */
13
+ /* [ 4] 805134e: pushl 0x14(%ebp) */
14
+ /* [ 4] 8051351: pushl 0x10(%ebp) */
15
+ /* [ 4] 8051354: pushl 0xc(%ebp) */
16
+ /* [ 4] 8051357: pushl 8(%ebp) */
17
+ /* [ 4] 805135a: nop */
18
+ /* [ 4] 805135b: nop */
19
+ /* [ 4] 805135c: nop */
20
+ /* [ 4] 805135d: nop */
21
+ /* [ 4] 805135e: nop */
22
+ /* [ 4] 805135f: addl $0x20,%esp */
23
+ /* 5. } */
24
+ /* [ 5] 8051362: leave */
25
+ /* [ 5] 8051363: ret */
26
+
27
+ Corresponding binary:
28
+
29
+ /* 1330 55 89 e5 83 .....^[. ....U... */
30
+ /* 1340 ec 08 ff 75 24 ff 75 20 ff 75 1c ff 75 18 ff 75 ...u$.u .u..u..u */
31
+ /* 1350 14 ff 75 10 ff 75 0c ff 75 08 90 90 90 90 90 83 ..u..u.. u....... */
32
+ /* 1360 c4 20 c9 c3 */
33
+
34
+ Hand-built 8-arg stub:
35
+
36
+ /* char insns[FUNC_SIZE] = */
37
+ /* { */
38
+ /* 0x55, 0x89, 0xe5, 0x83, 0xec, 0x08, */
39
+ /* 0xff, 0x75, 0x24, */
40
+ /* 0xff, 0x75, 0x20, */
41
+ /* 0xff, 0x75, 0x1c, */
42
+ /* 0xff, 0x75, 0x18, */
43
+ /* 0xff, 0x75, 0x14, */
44
+ /* 0xff, 0x75, 0x10, */
45
+ /* 0xff, 0x75, 0x0c, */
46
+ /* 0xff, 0x75, 0x08, */
47
+ /* 0x90, 0x90, 0x90, 0x90, 0x90, */
48
+ /* 0x83, 0xc4, 0x20, */
49
+ /* 0xc9, 0xc3 */
50
+ /* }; */
51
+
52
+ disassembly of is_enabled function:
53
+
54
+ 21. int is_enabled(void) {
55
+ <Function: is_enabled>
56
+ [21] 805142a: pushl %ebp
57
+ [21] 805142b: movl %esp,%ebp
58
+ [21] 805142d: subl $8,%esp
59
+ 22. return TEST_TEST_PROBE_ENABLED() ? 1 : 0;
60
+ [22] 8051430: xorl %eax,%eax
61
+ [22] 8051432: nop
62
+ [22] 8051433: nop
63
+ [22] 8051434: nop
64
+ [22] 8051435: movl %eax,-4(%ebp)
65
+ [22] 8051438: cmpl $0,-4(%ebp)
66
+ [22] 805143c: setne %al
67
+ [22] 805143f: movzbl %al,%eax
68
+ [22] 8051442: movl %eax,-4(%ebp)
69
+ [22] 8051445: movl -4(%ebp),%eax
70
+ 23. }
71
+ [23] 8051448: leave
72
+ [23] 8051449: ret
73
+
74
+ Binary:
75
+
76
+ 55 89 e5 83 ec 08 ....... ..U.....
77
+ 1430 33 c0 90 90 90 89 45 fc 83 7d fc 00 0f 95 c0 0f 3.....E. .}......
78
+ 1440 b6 c0 89 45 fc 8b 45 fc c9 c3
@@ -0,0 +1,40 @@
1
+ #
2
+ # Ruby-Dtrace
3
+ # (c) 2007 Chris Andrews <chris@nodnol.org>
4
+ #
5
+
6
+ # Represents an aggregation record built from a series of
7
+ # DtraceAggData records.
8
+ #
9
+ # Intended to to built up by calling +add_record+ repeatedly with
10
+ # Dtrace::AggData objects until a completed Dtrace::Aggregate is
11
+ # returned. (until a complete record is available, +add_record+
12
+ # returns nil).
13
+ #
14
+ # See consumer.rb for an example of this.
15
+ class Dtrace
16
+ class Aggregate
17
+ attr_reader :value, :tuple
18
+
19
+ # Create an empty Dtrace::Aggregate: use +add_record+ to add data.
20
+ def initialize
21
+ @tuple = Array.new
22
+ end
23
+
24
+ # Add a Dtrace::AggData record to this aggregate. Returns nil until it
25
+ # receives a record of aggtype "last", when it returns the complete
26
+ # Dtrace::Aggregate.
27
+ def add_record(r)
28
+ case r.aggtype
29
+ when "tuple"
30
+ @tuple << r.value
31
+ when "value"
32
+ @value = r.value
33
+ when "last"
34
+ return self
35
+ end
36
+ nil
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,19 @@
1
+ #
2
+ # Ruby-Dtrace
3
+ # (c) 2007 Chris Andrews <chris@nodnol.org>
4
+ #
5
+
6
+ class Dtrace
7
+ class AggregateSet
8
+ attr_reader :data
9
+
10
+ def initialize
11
+ @data = Array.new
12
+ end
13
+
14
+ def add_aggregate(agg)
15
+ @data << agg
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,174 @@
1
+ #
2
+ # Ruby-Dtrace
3
+ # (c) 2007 Chris Andrews <chris@nodnol.org>
4
+ #
5
+
6
+ # A Dtrace::Consumer provides access to the data produced by the running
7
+ # D program. Having compiled and executed a D program, you typically
8
+ # create a Dtrace::Consumer, and wait for data.
9
+ #
10
+ # You can either wait indefinitely for data, or consume all the data
11
+ # waiting and then stop: if your D program consists of only of
12
+ # aggregations, returned by printa() actions in the END block, this
13
+ # will be the best approach. If you have a mix of trace() and printf()
14
+ # actions elsewhere, you'll probably want to wait until interrupted,
15
+ # the D program itself exits, or your program decides it has collected
16
+ # enough data.
17
+ #
18
+ # The two approaches are implemented by the +consume+ and
19
+ # +consume_once+ methods.
20
+ #
21
+ # The +consume+ and +consume_once+ methods accept a block to which is
22
+ # yielded complete Dtrace::Data objects, one for each probe which fires.
23
+ #
24
+ # You must have already started tracing when you call +consume+ or
25
+ # +consume_once+, so the general structure will look like:
26
+ #
27
+ # t = Dtrace.new
28
+ # progtext = "..."
29
+ # prog = t.compile progtext
30
+ # prog.execute
31
+ # t.go
32
+ # c = Dtrace::Consumer.new(t)
33
+ # c.consume_once do |d|
34
+ # # handle Dtrace::Data objects
35
+ # # ...
36
+ # # get bored:
37
+ # c.finish
38
+ # end
39
+
40
+ class Dtrace
41
+ class Consumer
42
+
43
+ def initialize(t)
44
+ @t = t
45
+ @done = false
46
+ @types = []
47
+
48
+ @drophandler = nil
49
+ @errhandler = nil
50
+ end
51
+
52
+ private
53
+
54
+ # The consumer callbacks:
55
+ #
56
+ # DtraceRecDesc -> rec_consumer
57
+ # DtraceProbeData -> probe_consumer
58
+ # DtraceBufData -> buf_consumer
59
+ #
60
+ # We expect a sequence of calls to these procs, and we accumulate
61
+ # data in the @curr Dtrace::Data based on this:
62
+ #
63
+ # Dtrace::ProbeData (initial callback for a probe firing)
64
+ # Dtrace::RecDesc
65
+ # ...
66
+ # Dtrace::RecDesc = nil (end of data)
67
+ #
68
+
69
+ def rec_consumer(block)
70
+ proc do |rec|
71
+ if rec
72
+ @curr.add_recdata(rec)
73
+ else
74
+ @curr.finish
75
+ block.call(@curr)
76
+ @curr = Dtrace::Data.new(@types)
77
+ end
78
+ end
79
+ end
80
+
81
+ def probe_consumer
82
+ proc do |probe|
83
+ @curr.add_probedata(probe)
84
+ end
85
+ end
86
+
87
+ def buf_consumer
88
+ proc do |buf|
89
+ @curr.add_bufdata(buf)
90
+ end
91
+ end
92
+
93
+ def filter_types(types)
94
+ @types = types
95
+ @curr = Dtrace::Data.new(types)
96
+ end
97
+
98
+ public
99
+
100
+ # Provide a proc which will be executed when a drop record is
101
+ # received.
102
+ def drophandler(&block)
103
+ @drophandler = block
104
+ @t.drop_consumer(proc do |drop|
105
+ if @drophandler
106
+ @drophandler.call(drop)
107
+ end
108
+ end)
109
+ end
110
+
111
+ # Provide a proc which will be executed when an error record is
112
+ # received.
113
+ def errhandler(&block)
114
+ @errhandler = block
115
+ @t.err_consumer(proc do |err|
116
+ if @errhandler
117
+ @errhandler.call(err)
118
+ end
119
+ end)
120
+ end
121
+
122
+ # Signals that the client wishes to stop consuming trace data.
123
+ def finish
124
+ @t.stop
125
+ @done = true
126
+ end
127
+
128
+ # Waits for data from the D program, and yields the records returned
129
+ # to the block given. Returns when the D program exits.
130
+ #
131
+ # Pass a list of classes to restrict the types of data returned,
132
+ # from:
133
+ #
134
+ # * DtraceRecord
135
+ # * DtracePrintfRecord
136
+ # * DtraceAggregateSet
137
+ # * DtraceStackRecord
138
+ #
139
+ def consume(*types, &block)
140
+ filter_types(types)
141
+ @t.buf_consumer(buf_consumer)
142
+ begin
143
+ while(true) do
144
+ @t.sleep
145
+ work = @t.work(probe_consumer, rec_consumer(block))
146
+ if (@done || work > 0)
147
+ break
148
+ end
149
+ end
150
+ ensure
151
+ @t.stop
152
+ @t.work(probe_consumer)
153
+ end
154
+ end
155
+
156
+ # Yields the data waiting from the current program, then returns.
157
+ #
158
+ # Pass a list of classes to restrict the types of data returned,
159
+ # from:
160
+ #
161
+ # * DtraceRecord
162
+ # * DtracePrintfRecord
163
+ # * DtraceAggregateSet
164
+ # * DtraceStackRecord
165
+ #
166
+ def consume_once(*types, &block)
167
+ filter_types(types)
168
+ @t.buf_consumer(buf_consumer)
169
+ @t.stop
170
+ @t.work(probe_consumer, rec_consumer(block))
171
+ end
172
+
173
+ end
174
+ end
@@ -0,0 +1,82 @@
1
+ #
2
+ # Ruby-Dtrace
3
+ # (c) 2007 Chris Andrews <chris@nodnol.org>
4
+ #
5
+ # The object returned from a consumer when a probe fires. Accumulates
6
+ # records from the callbacks, and is yielded when the data is complete.
7
+ class Dtrace
8
+ class Data
9
+ attr_reader :data
10
+ attr_reader :probe
11
+ attr_reader :cpu, :indent, :prefix, :flow
12
+
13
+ def initialize(types)
14
+ @types = types
15
+ @data = []
16
+ @curraggset = nil
17
+ @curragg = nil
18
+ end
19
+
20
+ def add_data(d)
21
+ if @types.length == 0 || @types.include?(d.class)
22
+ @data << d
23
+ end
24
+ end
25
+
26
+ def finish
27
+ if @curraggset
28
+ add_data(@curraggset)
29
+ @curraggset = nil
30
+ end
31
+ end
32
+
33
+ def add_recdata(rec)
34
+ if @curraggset
35
+ add_data(@curraggset)
36
+ @curraggset = nil
37
+ end
38
+ if rec.action == "printa"
39
+ @curraggset = Dtrace::AggregateSet.new
40
+ end
41
+ end
42
+
43
+ def add_probedata(probedata)
44
+ probedata.each_record do |p|
45
+ add_data(p)
46
+ end
47
+
48
+ # Record the probe that fired, and CPU/indent/prefix/flow
49
+ @probe = probedata.probe
50
+ @cpu = probedata.cpu
51
+ @indent = probedata.indent
52
+ @prefix = probedata.prefix
53
+ @flow = probedata.flow
54
+ end
55
+
56
+ def add_bufdata(buf)
57
+ r = buf.record
58
+ # buf records can be empty (trace();)
59
+ if r
60
+ case r.class.to_s
61
+ when Dtrace::StackRecord.to_s
62
+ add_data(r)
63
+ when Dtrace::Record.to_s
64
+ add_data(r)
65
+ when Dtrace::PrintfRecord.to_s
66
+ add_data(r)
67
+ when Dtrace::AggData.to_s
68
+ if @curragg == nil
69
+ @curragg = Dtrace::Aggregate.new
70
+ end
71
+ if agg = @curragg.add_record(r)
72
+ if @curraggset
73
+ @curraggset.add_aggregate(@curragg)
74
+ end
75
+ @curragg = nil
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ end
82
+ end
@@ -0,0 +1,63 @@
1
+ #
2
+ # Ruby-Dtrace
3
+ # (c) 2008 Chris Andrews <chris@nodnol.org>
4
+ #
5
+
6
+ class Dtrace::Dof::File
7
+ include Dtrace::Dof::Constants
8
+ attr_accessor :sections
9
+
10
+ def initialize
11
+ @sections = []
12
+ end
13
+
14
+ def generate
15
+ hdr = Dtrace::Dof::Header.new
16
+ hdr.secnum = @sections.length
17
+ filesz = hdr.hdrlen
18
+ loadsz = filesz
19
+ dof_version = 1
20
+
21
+ @sections.each do |s|
22
+ # Presence of is_enabled probes forces DOF version 2.
23
+ if s.section_type == DOF_SECT_PRENOFFS
24
+ dof_version = 2
25
+ end
26
+
27
+ length = s.generate
28
+ s.offset = filesz
29
+
30
+ pad = 0
31
+ if s.align > 1
32
+ i = s.offset.to_f % s.align
33
+ if i > 0
34
+ pad = (s.align - i).to_i
35
+ s.offset = pad + s.offset
36
+ s.pad = "\000" * pad
37
+ end
38
+ end
39
+
40
+ s.size = length + pad
41
+
42
+ loadsz += s.size if (s.flags & 1) == 1 # DOF_SECF_LOAD
43
+ filesz += s.size
44
+
45
+ end
46
+
47
+ hdr.loadsz = loadsz
48
+ hdr.filesz = filesz
49
+ hdr.dof_version = dof_version
50
+
51
+ self << hdr.generate
52
+
53
+ @sections.each do |s|
54
+ self << s.generate_header
55
+ end
56
+
57
+ @sections.each do |s|
58
+ self << s.pad if s.pad
59
+ self << s.dof
60
+ end
61
+ end
62
+ end
63
+
@@ -0,0 +1,21 @@
1
+ #
2
+ # Ruby-Dtrace
3
+ # (c) 2008 Chris Andrews <chris@nodnol.org>
4
+ #
5
+
6
+ class Dtrace::Dof::Section::Strtab < Dtrace::Dof::Section
7
+ def initialize(index)
8
+ super(DOF_SECT_STRTAB, index)
9
+ self.data = []
10
+ @idx = 1
11
+ end
12
+
13
+ def add(string)
14
+ idx = @idx
15
+ string = string.to_s
16
+ @idx += (string.length + 1)
17
+ self.data << string
18
+ return idx
19
+ end
20
+
21
+ end
@@ -0,0 +1,69 @@
1
+ #
2
+ # Ruby-Dtrace
3
+ # (c) 2008 Chris Andrews <chris@nodnol.org>
4
+ #
5
+
6
+ require 'dtrace/dof/section/strtab'
7
+
8
+ class Dtrace::Dof::Section
9
+ include Dtrace::Dof::Constants
10
+ attr_writer :entsize
11
+ attr_accessor :flags, :data, :offset, :align, :pad, :size
12
+ attr_reader :section_type, :dof
13
+
14
+ def initialize(type, index)
15
+ @section_type = type
16
+ @index = index
17
+ @flags = 1 # DOF_SECF_LOAD
18
+ @data = {}
19
+ end
20
+
21
+ def generate
22
+ case @section_type
23
+ when DOF_SECT_COMMENTS
24
+ @align = 1
25
+ @dof = dof_generate_comments
26
+ when DOF_SECT_STRTAB
27
+ @align = 1
28
+ @dof = dof_generate_strtab
29
+ when DOF_SECT_PROBES
30
+ @align = 8
31
+ @dof = dof_generate_probes
32
+ when DOF_SECT_PRARGS
33
+ @align = 1
34
+ @dof = dof_generate_prargs
35
+ when DOF_SECT_PROFFS
36
+ @align = 4
37
+ @dof = dof_generate_proffs
38
+ when DOF_SECT_PRENOFFS
39
+ @align = 4
40
+ @dof = dof_generate_prenoffs
41
+ when DOF_SECT_PROVIDER
42
+ @align = 4
43
+ @dof = dof_generate_provider
44
+ when DOF_SECT_RELTAB
45
+ @align = 8
46
+ @dof = dof_generate_reltab
47
+ when DOF_SECT_URELHDR
48
+ @align = 4
49
+ @dof = dof_generate_relhdr
50
+ when DOF_SECT_UTSNAME
51
+ @align = 1
52
+ @dof = dof_generate_utsname
53
+ else
54
+ @dof = ''
55
+ end
56
+
57
+ begin
58
+ if @data.class == Array
59
+ @entsize = @dof.length / @data.length
60
+ else
61
+ @entsize = 0
62
+ end
63
+ rescue ZeroDivisionError
64
+ @entsize = 0
65
+ end
66
+
67
+ return @dof.length
68
+ end
69
+ end
data/lib/dtrace/dof.rb ADDED
@@ -0,0 +1,8 @@
1
+ #
2
+ # Ruby-Dtrace
3
+ # (c) 2008 Chris Andrews <chris@nodnol.org>
4
+ #
5
+
6
+ require 'dof/dof_api'
7
+ require 'dtrace/dof/section'
8
+ require 'dtrace/dof/file'
@@ -0,0 +1,10 @@
1
+ #
2
+ # Ruby-Dtrace
3
+ # (c) 2007 Chris Andrews <chris@nodnol.org>
4
+ #
5
+ # A DTrace record for the formatted part of a printf() action.
6
+ class Dtrace
7
+ class PrintfRecord
8
+ attr_accessor :value
9
+ end
10
+ end
@@ -0,0 +1,46 @@
1
+ #
2
+ # Ruby-Dtrace
3
+ # (c) 2008 Chris Andrews <chris@nodnol.org>
4
+
5
+ class Dtrace
6
+ # Using dynamically created USDT probes in Ruby programs.
7
+ #
8
+ # Having created the following probes with Dtrace::Provider:
9
+ #
10
+ # 74777 action_controller12297 action_controller.so process_finish process-finish
11
+ # 74778 action_controller12297 action_controller.so process_start process-start
12
+ #
13
+ # you can fire them with the following Ruby statements:
14
+ #
15
+ # Dtrace::Probe::ActionController.process_start do |p|
16
+ # p.fire(request.url)
17
+ # end
18
+ #
19
+ # Note that the generated class corresponding to the provider is
20
+ # simply the provider class, camelized.
21
+ #
22
+ # The generated method corresponding to the probe name (with -
23
+ # replaced by _) yields a probe object, on which you can call fire(),
24
+ # passing arguments of the appropriate types -- you are responsible
25
+ # for any type conversions necessary.
26
+ #
27
+ # fire() takes as many arguments as you defined for the probe: if
28
+ # you have generated a list of arguments to pass to fire(), use the
29
+ # splat operator to expand the list:
30
+ #
31
+ # Dtrace::Probe::MyProvider.my_probe do |p|
32
+ # args_list = [ some operation to get a list ]
33
+ # p.fire(*args_list)
34
+ # end
35
+ #
36
+ # This yield/fire() syntax exposes the is-enabled feature of the
37
+ # generated USDT probes: if the probe is not enabled, then the yield
38
+ # does not happen: this allows you to put relatively expensive work
39
+ # in the block, and know it is only called if the probe is enabled.
40
+ # This way, the probe-disabled overhead of these providers is
41
+ # reduced to a single method call, to a C-implemented method which
42
+ # simply wraps the DTrace IS_ENABLED() macro for the probe.
43
+ #
44
+ class Probe
45
+ end
46
+ end
@@ -0,0 +1,23 @@
1
+ #
2
+ # Ruby-Dtrace
3
+ # (c) 2007 Chris Andrews <chris@nodnol.org>
4
+ #
5
+
6
+ class Dtrace
7
+ class ProbeData
8
+
9
+ def records
10
+ records = Array.new
11
+ self.each_record do |rec|
12
+ records << rec
13
+ end
14
+ records
15
+ end
16
+
17
+ def to_s
18
+ rs = self.records
19
+ rs.map {|r| r.value }.join ', '
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ #
2
+ # Ruby-Dtrace
3
+ # (c) 2007 Chris Andrews <chris@nodnol.org>
4
+ #
5
+
6
+ class Dtrace
7
+ class ProbeDesc
8
+
9
+ def to_s
10
+ "#{provider}:#{mod}:#{func}:#{name}"
11
+ end
12
+
13
+ end
14
+ end
15
+
@@ -0,0 +1,24 @@
1
+ #
2
+ # Ruby-Dtrace
3
+ # (c) 2008 Chris Andrews <chris@nodnol.org>
4
+ #
5
+
6
+ class Dtrace
7
+ class Provider
8
+ class ProbeDef
9
+ attr_reader :name, :function
10
+ attr_accessor :args
11
+
12
+ def initialize(name, function)
13
+ @name = name.to_s
14
+ @function = function.to_s
15
+ @args = []
16
+ end
17
+
18
+ def argc
19
+ @args.length
20
+ end
21
+
22
+ end
23
+ end
24
+ end