ruby-dtrace 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +6 -1
- data/Manifest.txt +6 -0
- data/ext/dtrace_util.c +1 -0
- data/lib/dtrace.rb +1 -1
- data/lib/dtrace/probe.rb +49 -0
- data/lib/dtrace/provider.rb +236 -0
- data/lib/dtrace/provider/osx.rb +25 -0
- data/lib/dtrace/provider/solaris.rb +29 -0
- data/lib/dtrace/tracer.rb +35 -0
- data/plugin/dtrace/lib/dtrace_report.rb +15 -10
- data/test/test_dynusdt.rb +135 -0
- metadata +9 -2
data/History.txt
CHANGED
@@ -1,4 +1,9 @@
|
|
1
|
-
== 0.0.
|
1
|
+
== 0.0.6 / 2008-02-17
|
2
|
+
|
3
|
+
* Add Dtrace::Provider, which allows creation of USDT providers from
|
4
|
+
Ruby, without the need to patch the interpreter.
|
5
|
+
|
6
|
+
== 0.0.5 / 2008-01-24
|
2
7
|
|
3
8
|
* Add DtraceErrData and DtraceDropData for access to error
|
4
9
|
and drop information
|
data/Manifest.txt
CHANGED
@@ -19,6 +19,11 @@ ext/dtrace_recdesc.c
|
|
19
19
|
ext/dtrace_util.c
|
20
20
|
ext/extconf.rb
|
21
21
|
lib/dtrace.rb
|
22
|
+
lib/dtrace/probe.rb
|
23
|
+
lib/dtrace/provider.rb
|
24
|
+
lib/dtrace/provider/osx.rb
|
25
|
+
lib/dtrace/provider/solaris.rb
|
26
|
+
lib/dtrace/tracer.rb
|
22
27
|
lib/dtraceaggregate.rb
|
23
28
|
lib/dtraceaggregateset.rb
|
24
29
|
lib/dtraceconsumer.rb
|
@@ -50,3 +55,4 @@ test/test_dtrace_profile.rb
|
|
50
55
|
test/test_dtrace_repeat.rb
|
51
56
|
test/test_dtrace_rubyprobe.rb
|
52
57
|
test/test_dtrace_typefilter.rb
|
58
|
+
test/test_dynusdt.rb
|
data/ext/dtrace_util.c
CHANGED
data/lib/dtrace.rb
CHANGED
data/lib/dtrace/probe.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
#
|
2
|
+
# Ruby-Dtrace
|
3
|
+
# (c) 2007 Chris Andrews <chris@nodnol.org>
|
4
|
+
#
|
5
|
+
|
6
|
+
class Dtrace
|
7
|
+
# DTrace::Probe - Using dynamically created USDT probes in Ruby
|
8
|
+
# programs:
|
9
|
+
#
|
10
|
+
# Having created the following probes with Dtrace::Provider:
|
11
|
+
#
|
12
|
+
# 74777 action_controller12297 action_controller.so process_finish process-finish
|
13
|
+
# 74778 action_controller12297 action_controller.so process_start process-start
|
14
|
+
#
|
15
|
+
# you can fire them with the following Ruby statements:
|
16
|
+
#
|
17
|
+
# Dtrace::Probe::ActionController.process_start do |p|
|
18
|
+
# p.fire(request.url)
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# Note that the generated class corresponding to the provider is
|
22
|
+
# simply the provider class, camelized.
|
23
|
+
#
|
24
|
+
# The generated method corresponding to the probe name (with -
|
25
|
+
# replaced by _) yields a probe object, on which you can call fire(),
|
26
|
+
# passing arguments of the appropriate types -- you are responsible
|
27
|
+
# for any type conversions necessary.
|
28
|
+
#
|
29
|
+
# fire() takes as many arguments as you defined for the probe: if
|
30
|
+
# you have generated a list of arguments to pass to fire(), use the
|
31
|
+
# splat operator to expand the list:
|
32
|
+
#
|
33
|
+
# Dtrace::Probe::MyProvider.my_probe do |p|
|
34
|
+
# args_list = [ some operation to get a list ]
|
35
|
+
# p.fire(*args_list)
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# This yield/fire() syntax exposes the is-enabled feature of the
|
39
|
+
# generated USDT probes: if the probe is not enabled, then the yield
|
40
|
+
# does not happen: this allows you to put relatively expensive work
|
41
|
+
# in the block, and know it is only called if the probe is enabled.
|
42
|
+
# This way, the probe-disabled overhead of these providers is
|
43
|
+
# reduced to a single method call, to a C-implemented method which
|
44
|
+
# simply wraps the DTrace IS_ENABLED() macro for the probe.
|
45
|
+
#
|
46
|
+
class Probe
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
@@ -0,0 +1,236 @@
|
|
1
|
+
#
|
2
|
+
# Ruby-Dtrace
|
3
|
+
# (c) 2007 Chris Andrews <chris@nodnol.org>
|
4
|
+
#
|
5
|
+
|
6
|
+
require 'dtrace/probe'
|
7
|
+
require 'dtrace/provider/solaris'
|
8
|
+
require 'dtrace/provider/osx'
|
9
|
+
require 'pathname'
|
10
|
+
require 'tempfile'
|
11
|
+
|
12
|
+
DTRACE = '/usr/sbin/dtrace'
|
13
|
+
|
14
|
+
class Dtrace
|
15
|
+
|
16
|
+
# A DTrace provider. Allows creation of USDT probes on a running
|
17
|
+
# Ruby program, by dynamically creating an extension module
|
18
|
+
# implementing the probes, and compiling and loading it. You can use
|
19
|
+
# this with a Ruby interpreter compiled with the core DTrace probes,
|
20
|
+
# but you don't have to.
|
21
|
+
#
|
22
|
+
# This requires the DTrace and Ruby toolchains to be available:
|
23
|
+
# dtrace(1M), and the compiler and linker used to build Ruby. The
|
24
|
+
# process is similar to RubyInline, but the actual RubyInline
|
25
|
+
# library is not required (the build process for DTrace USDT probes
|
26
|
+
# is sufficiently differnent to a standard Ruby extension that it's
|
27
|
+
# not worth using it).
|
28
|
+
#
|
29
|
+
# Both Solaris and OSX 10.5 are supported. Other DTrace-supporting
|
30
|
+
# platforms can be added by creating a new class under
|
31
|
+
# Dtrace::Provider and implementing or overriding the required steps
|
32
|
+
# in the build process.
|
33
|
+
#
|
34
|
+
# Firing probes is explained in Dtrace::Probe.
|
35
|
+
#
|
36
|
+
# There are some limitations:
|
37
|
+
#
|
38
|
+
# You cannot choose all the components of the probe name: you can
|
39
|
+
# choose the provider and probe name, but the module and function
|
40
|
+
# components will be derived by DTrace, and won't be meaningful
|
41
|
+
# (they'll refer to the shim extension that gets created, not to
|
42
|
+
# anything in your Ruby program). It seems unlikely it's possible to
|
43
|
+
# change this.
|
44
|
+
#
|
45
|
+
# You cannot currently set D attributes: they're hardcoded to a
|
46
|
+
# default set. This will change.
|
47
|
+
#
|
48
|
+
# The extension will currently be rebuilt every time the provider is
|
49
|
+
# created, as there's not yet any support for packaging the provider
|
50
|
+
# in some way. This will change, to something along the lines of
|
51
|
+
# what RubyInline does to allow a pre-built extension to be used.
|
52
|
+
#
|
53
|
+
class Provider
|
54
|
+
|
55
|
+
class BuildError < StandardError; end
|
56
|
+
|
57
|
+
# Creates a DTrace provider. Causes a shim extension to be built
|
58
|
+
# and loaded, implementing the probes.
|
59
|
+
#
|
60
|
+
# Example:
|
61
|
+
#
|
62
|
+
# Dtrace::Provider.create :action_controller do |p|
|
63
|
+
# p.probe :process_start, :string
|
64
|
+
# p.probe :process_finish, :string, :integer
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
# The symbol passed to create becomes the name of the provider,
|
68
|
+
# and the class exposed under Dtrace::Probe in Ruby (camelized, so
|
69
|
+
# the above statement creates Dtrace::Probe::ActionController).
|
70
|
+
#
|
71
|
+
# create yields a Provider for the current platform, on which you
|
72
|
+
# can call probe, to create the individual probes.
|
73
|
+
#
|
74
|
+
def self.create(name)
|
75
|
+
if RUBY_PLATFORM =~ /darwin/
|
76
|
+
provider = Dtrace::Provider::OSX.new(name)
|
77
|
+
else
|
78
|
+
provider = Dtrace::Provider::Solaris.new(name)
|
79
|
+
end
|
80
|
+
yield provider
|
81
|
+
provider.enable
|
82
|
+
end
|
83
|
+
|
84
|
+
# Creates a DTrace USDT probe. Arguments are the probe name, and
|
85
|
+
# then the argument types it will accept. The following argument
|
86
|
+
# types are supported:
|
87
|
+
#
|
88
|
+
# :string (char *)
|
89
|
+
# :integer (int)
|
90
|
+
#
|
91
|
+
# The probe will be named based on the provider name and the
|
92
|
+
# probe's name:
|
93
|
+
#
|
94
|
+
# provider_name:provider_name.so:probe_name:probe-name
|
95
|
+
#
|
96
|
+
# See the limitations explained elsewhere for an explanation of
|
97
|
+
# this redundancy in probe names.
|
98
|
+
#
|
99
|
+
def probe(name, *types)
|
100
|
+
typemap = { :string => 'char *', :integer => 'int' }
|
101
|
+
@probes[name] = types.map {|t| typemap[t]}
|
102
|
+
end
|
103
|
+
|
104
|
+
def initialize(name)
|
105
|
+
@name = name.to_s
|
106
|
+
@class = camelize(name)
|
107
|
+
@probes = {}
|
108
|
+
end
|
109
|
+
|
110
|
+
def enable
|
111
|
+
Tempfile.open("dtrace_probe_#{@name}") do |f|
|
112
|
+
p = Pathname.new(f.path)
|
113
|
+
@tempdir = "#{p.dirname}/#{@name}"
|
114
|
+
begin
|
115
|
+
Dir.mkdir @tempdir
|
116
|
+
rescue Errno::EEXIST
|
117
|
+
nil
|
118
|
+
end
|
119
|
+
|
120
|
+
# Probe setup is split up for easy overriding
|
121
|
+
definition
|
122
|
+
header
|
123
|
+
source
|
124
|
+
ruby_object
|
125
|
+
dtrace_object
|
126
|
+
link
|
127
|
+
load
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
protected
|
132
|
+
|
133
|
+
def run(cmd)
|
134
|
+
result = `#{cmd}`
|
135
|
+
if $? != 0
|
136
|
+
raise BuildError.new("Error running:\n#{cmd}\n\n#{result}")
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def hdrdir
|
141
|
+
%w(srcdir archdir).map { |name|
|
142
|
+
dir = Config::CONFIG[name]
|
143
|
+
}.find { |dir|
|
144
|
+
dir and File.exist? File.join(dir, "/ruby.h")
|
145
|
+
} or abort "ERROR: Can't find header dir for ruby. Exiting..."
|
146
|
+
end
|
147
|
+
|
148
|
+
private
|
149
|
+
|
150
|
+
def camelize(lower_case_and_underscored_word)
|
151
|
+
# Pinched from ActiveSupport's Inflector
|
152
|
+
lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
|
153
|
+
end
|
154
|
+
|
155
|
+
# compose provider definition .d file
|
156
|
+
def definition
|
157
|
+
stability = <<EOS
|
158
|
+
#pragma D attributes Evolving/Evolving/Common provider #{@name} provider
|
159
|
+
#pragma D attributes Private/Private/Common provider #{@name} module
|
160
|
+
#pragma D attributes Private/Private/Common provider #{@name} function
|
161
|
+
#pragma D attributes Evolving/Evolving/Common provider #{@name} name
|
162
|
+
#pragma D attributes Evolving/Evolving/Common provider #{@name} args
|
163
|
+
EOS
|
164
|
+
File.open("#{@tempdir}/probes.d", 'w') do |io|
|
165
|
+
io << "provider #{@name} {\n"
|
166
|
+
@probes.each_pair do |name, types|
|
167
|
+
probename = name.to_s.gsub(/_/, '__')
|
168
|
+
typesdesc = types.join(', ')
|
169
|
+
probedesc = " probe #{probename}(#{typesdesc});\n"
|
170
|
+
io << probedesc
|
171
|
+
end
|
172
|
+
io << "\n};\n\n#{stability}"
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def header
|
177
|
+
run "#{DTRACE} -h -s #{@tempdir}/probes.d -o #{@tempdir}/probes.h"
|
178
|
+
end
|
179
|
+
|
180
|
+
# Generate the C source for the provider class
|
181
|
+
def source
|
182
|
+
rb2c = { 'char *' => 'STR2CSTR', 'int' => 'FIX2INT' }
|
183
|
+
|
184
|
+
File.open("#{@tempdir}/probes.c", 'w') do |io|
|
185
|
+
io.puts '#include "ruby.h"'
|
186
|
+
io.puts "#include \"#{@tempdir}/probes.h\""
|
187
|
+
|
188
|
+
@probes.each_pair do |name, types|
|
189
|
+
defn_args = []
|
190
|
+
call_args = []
|
191
|
+
types.each_with_index { |type, i| defn_args << "#{type} arg#{i}" }
|
192
|
+
types.each_with_index { |type, i| call_args << "#{rb2c[type]}(rb_ary_entry(args, #{i}))" }
|
193
|
+
|
194
|
+
io.puts <<EOC
|
195
|
+
static VALUE #{name}(VALUE self) {
|
196
|
+
if (#{@name.upcase}_#{name.to_s.upcase}_ENABLED()) {
|
197
|
+
VALUE args = rb_yield(self);
|
198
|
+
#{@name.upcase}_#{name.to_s.upcase}(#{call_args.join(', ')});
|
199
|
+
}
|
200
|
+
return Qnil;
|
201
|
+
}
|
202
|
+
EOC
|
203
|
+
end
|
204
|
+
io.puts <<EOC
|
205
|
+
static VALUE fire(VALUE self, VALUE args) {
|
206
|
+
return args;
|
207
|
+
}
|
208
|
+
|
209
|
+
void Init_#{@name}() {
|
210
|
+
VALUE c = rb_cObject;
|
211
|
+
rb_define_method(c, "fire", (VALUE(*)(ANYARGS))fire, -2);
|
212
|
+
EOC
|
213
|
+
|
214
|
+
@probes.each_pair do |name, types|
|
215
|
+
io.puts " rb_define_singleton_method(c, \"#{name}\", (VALUE(*)(ANYARGS))#{name}, 0);"
|
216
|
+
end
|
217
|
+
|
218
|
+
io.puts '}'
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def load
|
223
|
+
# Load the generated extension with a full path (saves adjusting
|
224
|
+
# $:) Done in the context of an anonymous class, since the
|
225
|
+
# module does not itself define a class. TODO: find a way of
|
226
|
+
# doing this without string eval...
|
227
|
+
lib = "#{@tempdir}/#{@name}"
|
228
|
+
c = Class.new
|
229
|
+
c.module_eval do
|
230
|
+
require lib
|
231
|
+
end
|
232
|
+
eval "Dtrace::Probe::#{@class} = c"
|
233
|
+
end
|
234
|
+
|
235
|
+
end
|
236
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#
|
2
|
+
# Ruby-Dtrace
|
3
|
+
# (c) 2007 Chris Andrews <chris@nodnol.org>
|
4
|
+
#
|
5
|
+
|
6
|
+
class Dtrace
|
7
|
+
class Provider
|
8
|
+
class OSX < Provider
|
9
|
+
|
10
|
+
# build the .bundle
|
11
|
+
def ruby_object
|
12
|
+
run "#{Config::CONFIG['LDSHARED']} -I #{hdrdir} -o #{@tempdir}/#{@name}.bundle #{@tempdir}/probes.c"
|
13
|
+
end
|
14
|
+
|
15
|
+
def dtrace_object
|
16
|
+
# no-op on OSX
|
17
|
+
end
|
18
|
+
|
19
|
+
def link
|
20
|
+
# no-op on OSX
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#
|
2
|
+
# Ruby-Dtrace
|
3
|
+
# (c) 2007 Chris Andrews <chris@nodnol.org>
|
4
|
+
#
|
5
|
+
|
6
|
+
require 'rbconfig'
|
7
|
+
|
8
|
+
class Dtrace
|
9
|
+
class Provider
|
10
|
+
class Solaris < Provider
|
11
|
+
|
12
|
+
# build the .o
|
13
|
+
def ruby_object
|
14
|
+
run "#{Config::CONFIG['CC']} -I#{hdrdir} -o #{@tempdir}/#{@name}.o -c #{@tempdir}/probes.c"
|
15
|
+
end
|
16
|
+
|
17
|
+
# build the dtrace.o (dtrace -G)
|
18
|
+
def dtrace_object
|
19
|
+
run "/usr/sbin/dtrace -G -s #{@tempdir}/probes.d -o #{@tempdir}/probes.o #{@tempdir}/#{@name}.o"
|
20
|
+
end
|
21
|
+
|
22
|
+
# build the .so
|
23
|
+
def link
|
24
|
+
run "#{Config::CONFIG['CC']} -shared -o #{@tempdir}/#{@name}.so #{@tempdir}/#{@name}.o #{@tempdir}/probes.o"
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
#
|
2
|
+
# Ruby-Dtrace
|
3
|
+
# (c) 2007 Chris Andrews <chris@nodnol.org>
|
4
|
+
#
|
5
|
+
|
6
|
+
# Leopard's ruby-probe is DTracer, Solaris's is Tracer.
|
7
|
+
|
8
|
+
class Dtrace
|
9
|
+
class Tracer
|
10
|
+
|
11
|
+
class NullTracer
|
12
|
+
def self.fire(arg0, arg1)
|
13
|
+
puts "NullTracer: #{arg0} #{arg1}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
@@tracer = nil
|
18
|
+
def self.fire(*args)
|
19
|
+
if @@tracer == nil
|
20
|
+
begin
|
21
|
+
# Avoid getting ourselves here:
|
22
|
+
@@tracer = Module.const_get('Tracer')
|
23
|
+
rescue NameError
|
24
|
+
begin
|
25
|
+
@@tracer = DTracer
|
26
|
+
rescue NameError
|
27
|
+
@@tracer = Dtrace::Tracer::NullTracer
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
@@tracer.fire(*args)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -5,6 +5,7 @@ module DtraceReport
|
|
5
5
|
|
6
6
|
def self.included(base)
|
7
7
|
base.extend DtraceMacro
|
8
|
+
@@tracer = nil
|
8
9
|
end
|
9
10
|
|
10
11
|
module DtraceMacro
|
@@ -43,19 +44,23 @@ module DtraceReport
|
|
43
44
|
end
|
44
45
|
|
45
46
|
def enable_dtrace
|
46
|
-
@@tracer
|
47
|
+
if @@tracer
|
48
|
+
@@tracer.start_dtrace($$)
|
49
|
+
end
|
47
50
|
end
|
48
51
|
|
49
52
|
def append_dtrace_report
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
53
|
+
if @@tracer
|
54
|
+
@dtrace_script = @@tracer.script
|
55
|
+
@dtrace_report = @@tracer.end_dtrace
|
56
|
+
# yuck!
|
57
|
+
old_template_root = @template.base_path
|
58
|
+
begin
|
59
|
+
@template.view_paths = File.expand_path(File.dirname(__FILE__) + '/../views')
|
60
|
+
response.body.gsub!(/<\/body/, @template.render(:partial => 'dtrace/report') + '</body')
|
61
|
+
ensure
|
62
|
+
@template.view_paths = old_template_root
|
63
|
+
end
|
59
64
|
end
|
60
65
|
end
|
61
66
|
|
@@ -0,0 +1,135 @@
|
|
1
|
+
#
|
2
|
+
# Ruby-Dtrace
|
3
|
+
# (c) 2007 Chris Andrews <chris@nodnol.org>
|
4
|
+
#
|
5
|
+
|
6
|
+
require 'dtrace'
|
7
|
+
require 'dtrace/provider'
|
8
|
+
require 'test/unit'
|
9
|
+
require 'rbconfig'
|
10
|
+
|
11
|
+
# Tests for the Dtrace "dynamic USDT" library
|
12
|
+
|
13
|
+
class TestDynUsdt < Test::Unit::TestCase
|
14
|
+
|
15
|
+
def test_create_usdt
|
16
|
+
Dtrace::Provider.create :test_provider_create_usdt do |p|
|
17
|
+
p.probe :test_probe, :string
|
18
|
+
end
|
19
|
+
|
20
|
+
t = Dtrace.new
|
21
|
+
t.setopt("bufsize", "4m")
|
22
|
+
|
23
|
+
progtext = 'test_provider_create_usdt*:::test-probe { trace(copyinstr(arg0)); }'
|
24
|
+
|
25
|
+
prog = t.compile progtext
|
26
|
+
prog.execute
|
27
|
+
t.go
|
28
|
+
|
29
|
+
c = DtraceConsumer.new(t)
|
30
|
+
|
31
|
+
Dtrace::Probe::TestProviderCreateUsdt.test_probe do |p|
|
32
|
+
p.fire "test_argument"
|
33
|
+
end
|
34
|
+
|
35
|
+
i = 0
|
36
|
+
c.consume_once do |d|
|
37
|
+
i = i + 1
|
38
|
+
assert d
|
39
|
+
assert_not_nil d.probe
|
40
|
+
assert_equal "test_provider_create_usdt#{$$.to_s}:test_provider_create_usdt.#{Config::CONFIG['DLEXT']}:test_probe:test-probe", d.probe.to_s
|
41
|
+
assert_equal 1, d.data.length
|
42
|
+
assert_equal "test_argument", d.data[0].value
|
43
|
+
end
|
44
|
+
assert_equal 1, i
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_create_usdt_argtypes
|
48
|
+
Dtrace::Provider.create :test_provider_create_usdt_argtypes do |p|
|
49
|
+
p.probe :test_probe_string, :string
|
50
|
+
p.probe :test_probe_int, :integer
|
51
|
+
end
|
52
|
+
|
53
|
+
t = Dtrace.new
|
54
|
+
t.setopt("bufsize", "4m")
|
55
|
+
|
56
|
+
progtext = <<EOD
|
57
|
+
test_provider_create_usdt_argtypes*:::test-probe-string { trace(copyinstr(arg0)); }
|
58
|
+
test_provider_create_usdt_argtypes*:::test-probe-int { trace(arg0); }
|
59
|
+
EOD
|
60
|
+
|
61
|
+
prog = t.compile progtext
|
62
|
+
prog.execute
|
63
|
+
t.go
|
64
|
+
|
65
|
+
c = DtraceConsumer.new(t)
|
66
|
+
|
67
|
+
Dtrace::Probe::TestProviderCreateUsdtArgtypes.test_probe_string do |p|
|
68
|
+
p.fire "test_argument"
|
69
|
+
end
|
70
|
+
|
71
|
+
Dtrace::Probe::TestProviderCreateUsdtArgtypes.test_probe_int do |p|
|
72
|
+
p.fire 42
|
73
|
+
end
|
74
|
+
|
75
|
+
i = 0
|
76
|
+
c.consume_once do |d|
|
77
|
+
assert d
|
78
|
+
assert_not_nil d.probe
|
79
|
+
if d.probe.name == 'test-probe-string'
|
80
|
+
assert_equal "test_argument", d.data[0].value
|
81
|
+
i = i + 1
|
82
|
+
elsif d.probe.name == 'test-probe-int'
|
83
|
+
assert_equal 42, d.data[0].value
|
84
|
+
i = i + 1
|
85
|
+
end
|
86
|
+
end
|
87
|
+
assert_equal 2, i
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_create_usdt_manyargs
|
91
|
+
Dtrace::Provider.create :test_provider_create_usdt_manyargs do |p|
|
92
|
+
p.probe :test_probe, :string, :string, :string, :string, :string, :string, :string, :string
|
93
|
+
end
|
94
|
+
|
95
|
+
t = Dtrace.new
|
96
|
+
t.setopt("bufsize", "4m")
|
97
|
+
|
98
|
+
progtext = <<EOD
|
99
|
+
test_provider_create_usdt_manyargs*:::test-probe
|
100
|
+
{
|
101
|
+
trace(copyinstr(arg0));
|
102
|
+
trace(copyinstr(arg1));
|
103
|
+
trace(copyinstr(arg2));
|
104
|
+
trace(copyinstr(arg3));
|
105
|
+
trace(copyinstr(arg4));
|
106
|
+
trace(copyinstr(arg5));
|
107
|
+
trace(copyinstr(arg6));
|
108
|
+
trace(copyinstr(arg7));
|
109
|
+
}
|
110
|
+
EOD
|
111
|
+
|
112
|
+
prog = t.compile progtext
|
113
|
+
prog.execute
|
114
|
+
t.go
|
115
|
+
|
116
|
+
c = DtraceConsumer.new(t)
|
117
|
+
|
118
|
+
Dtrace::Probe::TestProviderCreateUsdtManyargs.test_probe do |p|
|
119
|
+
values_list = (0..7).map {|i| "value #{i.to_s}" }
|
120
|
+
p.fire(*values_list)
|
121
|
+
end
|
122
|
+
|
123
|
+
i = 0
|
124
|
+
c.consume_once do |d|
|
125
|
+
i = i + 1
|
126
|
+
assert_equal 8, d.data.length
|
127
|
+
(0..7).each do |j|
|
128
|
+
assert_equal "value #{j.to_s}", d.data[j].value
|
129
|
+
end
|
130
|
+
end
|
131
|
+
assert_equal 1, i
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
|
|
3
3
|
specification_version: 1
|
4
4
|
name: ruby-dtrace
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.0.
|
7
|
-
date: 2008-
|
6
|
+
version: 0.0.6
|
7
|
+
date: 2008-02-17 00:00:00 +00:00
|
8
8
|
summary: Ruby bindings for libdtrace
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -51,6 +51,11 @@ files:
|
|
51
51
|
- ext/dtrace_util.c
|
52
52
|
- ext/extconf.rb
|
53
53
|
- lib/dtrace.rb
|
54
|
+
- lib/dtrace/probe.rb
|
55
|
+
- lib/dtrace/provider.rb
|
56
|
+
- lib/dtrace/provider/osx.rb
|
57
|
+
- lib/dtrace/provider/solaris.rb
|
58
|
+
- lib/dtrace/tracer.rb
|
54
59
|
- lib/dtraceaggregate.rb
|
55
60
|
- lib/dtraceaggregateset.rb
|
56
61
|
- lib/dtraceconsumer.rb
|
@@ -82,6 +87,7 @@ files:
|
|
82
87
|
- test/test_dtrace_repeat.rb
|
83
88
|
- test/test_dtrace_rubyprobe.rb
|
84
89
|
- test/test_dtrace_typefilter.rb
|
90
|
+
- test/test_dynusdt.rb
|
85
91
|
test_files:
|
86
92
|
- test/test_dtrace.rb
|
87
93
|
- test/test_dtrace_aggregates.rb
|
@@ -91,6 +97,7 @@ test_files:
|
|
91
97
|
- test/test_dtrace_repeat.rb
|
92
98
|
- test/test_dtrace_rubyprobe.rb
|
93
99
|
- test/test_dtrace_typefilter.rb
|
100
|
+
- test/test_dynusdt.rb
|
94
101
|
rdoc_options:
|
95
102
|
- --main
|
96
103
|
- README.txt
|