ruby-usdt 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 32ca9d27b82e9e04dc7c82c91841ba967dea40d8
4
+ data.tar.gz: 90ea9c2c69fbc5311ea9da9992d0f7339ee5d9c6
5
+ SHA512:
6
+ metadata.gz: 27df55c3cafad792beaa5f0858a6abd624d6c57708f79efb41d4ab2fe422429ac928dc18f234b4fce44b2ced1086021990b2ea7d55fe0f4a750827aa56a02a70
7
+ data.tar.gz: a909999ff4e99cca642386a96388f2838edeb5c4765176280734e9aedca964c41eb22a8d66d4331ca979e0403e749144d35d81ad49e5057e6df8865d3a84b4b4
data/README.md CHANGED
@@ -10,47 +10,65 @@ providers at runtime for instrumentation and analysis by the
10
10
 
11
11
  ### Install
12
12
 
13
- gem install ruby-usdt
13
+ ```ruby
14
+ gem install ruby-usdt
15
+ ```
14
16
 
15
17
  When using Bundler to integrate ruby-usdt into a Ruby or Rails project,
16
18
  you will need to specify that there are git submodule dependencies:
17
19
 
18
- gem "ruby-usdt", :submodules => true
20
+ ```ruby
21
+ gem "ruby-usdt", :submodules => true
22
+ ```
19
23
 
20
24
  ### Usage
21
25
 
22
- # Provider.create <provider>, <module>
23
- #
24
- # Creates a probe
25
- #
26
- # returns USDT::Provider object
27
- provider = USDT::Provider.create :ruby, :mymod
28
-
29
- # Provider#probe *args
30
- #
31
- # args must be either :integer, or :string
32
- # max 6 args (dtrace provides this many), additional args will be ignored
33
- # returns USDT::Probe object
34
- p = provider.probe(:myfn, :probe, :string, :string, :integer)
35
-
36
- # Provider#enable
37
- # enables the probes defined with #probe
38
- provider.enable
39
-
40
- while true
41
- if p.enabled?
42
- p.fire("omg", "probe!!", 12345)
43
- end
44
- sleep 0.5
45
- end
46
-
47
- # see the probes in action with:
48
- # you should see continious output of the fire args above
49
- sudo dtrace -n 'ruby*:mymod:myfn:probe { printf("%s %s %d",
50
- copyinstr(arg0),
51
- copyinstr(arg1),
52
- args[2])
53
- }'
26
+ ```ruby
27
+ # Provider.create <provider>, <module>
28
+ #
29
+ # Creates a probe
30
+ #
31
+ # returns USDT::Provider object
32
+ provider = USDT::Provider.create :ruby, :mymod
33
+
34
+ # Provider#probe *args
35
+ #
36
+ # args must be either :integer, or :string
37
+ # max 6 args (dtrace provides this many), additional args will be ignored
38
+ # returns USDT::Probe object
39
+ probe = provider.probe(:myfn, :probe, :string, :string, :integer)
40
+
41
+ # Provider#enable
42
+ # enables the probes defined with #probe
43
+ provider.enable
44
+
45
+ while true
46
+ if probe.enabled?
47
+ probe.fire("omg", "probe!!", 12345)
48
+ end
49
+ sleep 0.5
50
+ end
51
+ ```
52
+
53
+ To see the above probe working, the following dtrace script can be used:
54
+ ```bash
55
+ sudo dtrace -n 'ruby*:mymod:myfn:probe { printf("%s %s %d",
56
+ copyinstr(arg0),
57
+ copyinstr(arg1),
58
+ args[2])
59
+ }'
60
+ ```
61
+
62
+ ### Probes in Ruby
63
+
64
+ Introspection can be done on a probe from within Ruby using the
65
+ following commands:
66
+
67
+ ```ruby
68
+ probe.function => :myfn
69
+ probe.name => :probe
70
+ probe.arguments => [:string, :string, :integer]
71
+ ```
54
72
 
55
73
  ## Additional Resources
56
74
 
data/ext/usdt/test.rb CHANGED
@@ -1,12 +1,29 @@
1
1
  require File.expand_path(File.dirname(__FILE__)) + '/usdt'
2
2
 
3
+ puts "## Provider"
3
4
  provider = USDT::Provider.create :ruby, :test
4
5
  puts provider
5
- p = provider.probe(:myfn, :probe,
6
+
7
+ puts
8
+ puts "## Probe with sym definition"
9
+ probe = provider.probe(:myfn, :probe,
6
10
  :string, :string, :integer)
11
+ puts probe
12
+ puts "probe.function: #{probe.function.inspect}"
13
+ puts "probe.name: #{probe.name.inspect}"
14
+ puts "probe.arguments: #{probe.arguments.inspect}"
15
+
16
+ puts
17
+ puts "## Probe with string definition"
18
+ probe_str = provider.probe('myfn', 'str', :string)
19
+ puts probe_str
20
+ puts "probe.function: #{probe_str.function.inspect}"
21
+ puts "probe.name: #{probe_str.name.inspect}"
22
+ puts "probe.arguments: #{probe_str.arguments.inspect}"
7
23
 
8
24
  provider.enable
9
25
 
26
+ puts
10
27
  puts "run:\nsudo dtrace -n 'ruby*:test:myfn:probe { printf(\"%s %s %d\",
11
28
  copyinstr(arg0),
12
29
  copyinstr(arg1),
@@ -14,8 +31,8 @@ puts "run:\nsudo dtrace -n 'ruby*:test:myfn:probe { printf(\"%s %s %d\",
14
31
  }'"
15
32
 
16
33
  while true
17
- if p.enabled?
18
- p.fire("one", "two", 3)
34
+ if probe.enabled?
35
+ probe.fire("one", "two", 3)
19
36
  puts("Fired!")
20
37
  end
21
38
  sleep 0.5
data/ext/usdt/usdt.c CHANGED
@@ -13,6 +13,9 @@ static VALUE provider_enable(VALUE self);
13
13
  static VALUE provider_disable(VALUE self);
14
14
  static VALUE probe_enabled(VALUE self);
15
15
  static VALUE probe_fire(int argc, VALUE *argv, VALUE self);
16
+ static VALUE probe_function(VALUE self);
17
+ static VALUE probe_name(VALUE self);
18
+ static VALUE probe_args(VALUE self);
16
19
 
17
20
  void Init_usdt() {
18
21
  USDT = rb_define_module("USDT");
@@ -29,6 +32,9 @@ void Init_usdt() {
29
32
  USDT_Probe = rb_define_class_under(USDT, "Probe", rb_cObject);
30
33
  rb_define_method(USDT_Probe, "enabled?", probe_enabled, 0);
31
34
  rb_define_method(USDT_Probe, "fire", probe_fire, -1);
35
+ rb_define_method(USDT_Probe, "function", probe_function, 0);
36
+ rb_define_method(USDT_Probe, "name", probe_name, 0);
37
+ rb_define_method(USDT_Probe, "arguments", probe_args, 0);
32
38
  }
33
39
 
34
40
  /**
@@ -177,3 +183,43 @@ static VALUE probe_fire(int argc, VALUE *argv, VALUE self) {
177
183
  usdt_fire_probe(probedef->probe, probedef->argc, pargs);
178
184
  return Qtrue;
179
185
  }
186
+
187
+ /**
188
+ * USDT::Probe#function
189
+ */
190
+ static VALUE probe_function(VALUE self) {
191
+ usdt_probedef_t **p = DATA_PTR(self);
192
+ usdt_probedef_t *probedef = *p;
193
+ return ID2SYM(rb_intern(probedef->function));
194
+ }
195
+
196
+ /**
197
+ * USDT::Probe#name
198
+ */
199
+ static VALUE probe_name(VALUE self) {
200
+ usdt_probedef_t **p = DATA_PTR(self);
201
+ usdt_probedef_t *probedef = *p;
202
+ return ID2SYM(rb_intern(probedef->name));
203
+ }
204
+
205
+ /**
206
+ * USDT::Probe#arguments
207
+ */
208
+ static VALUE probe_args(VALUE self) {
209
+ usdt_probedef_t **p = DATA_PTR(self);
210
+ usdt_probedef_t *probedef = *p;
211
+
212
+ VALUE args = rb_ary_new();
213
+ size_t i;
214
+
215
+ for (i = 0; i < probedef->argc; i++) {
216
+ if (probedef->types[i] == USDT_ARGTYPE_STRING) {
217
+ rb_ary_push(args, ID2SYM(rb_intern("string")));
218
+ } else if (probedef->types[i] == USDT_ARGTYPE_INTEGER) {
219
+ rb_ary_push(args, ID2SYM(rb_intern("integer")));
220
+ } else {
221
+ rb_ary_push(args, Qnil);
222
+ }
223
+ }
224
+ return args;
225
+ }
data/lib/usdt/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module USDT
2
- VERSION = '0.1.2'
2
+ VERSION = '0.2.0'
3
3
  end
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-usdt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
5
- prerelease:
4
+ version: 0.2.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Kevin Chan
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-12-13 00:00:00.000000000 Z
11
+ date: 2013-11-08 00:00:00.000000000 Z
13
12
  dependencies: []
14
13
  description:
15
14
  email:
@@ -21,51 +20,34 @@ extra_rdoc_files: []
21
20
  files:
22
21
  - lib/usdt/version.rb
23
22
  - lib/usdt.rb
24
- - ext/libusdt/LICENCE
25
- - ext/libusdt/Makefile
26
- - ext/libusdt/README.md
27
- - ext/libusdt/test.pl
28
- - ext/libusdt/test_mem_usage.c
29
- - ext/libusdt/test_usdt.c
30
- - ext/libusdt/usdt.c
31
- - ext/libusdt/usdt.h
32
- - ext/libusdt/usdt_dof.c
33
- - ext/libusdt/usdt_dof_file.c
34
- - ext/libusdt/usdt_dof_sections.c
35
- - ext/libusdt/usdt_internal.h
36
- - ext/libusdt/usdt_probe.c
37
- - ext/libusdt/usdt_tracepoints_i386.s
38
- - ext/libusdt/usdt_tracepoints_x86_64.s
39
23
  - ext/usdt/extconf.rb
40
- - ext/usdt/Makefile
41
24
  - ext/usdt/test.rb
42
25
  - ext/usdt/usdt.c
43
- - ext/usdt/usdt.h
44
26
  - README.md
45
27
  - LICENSE.md
46
28
  homepage: http://github.com/kevinykchan/ruby-usdt
47
29
  licenses: []
30
+ metadata: {}
48
31
  post_install_message:
49
32
  rdoc_options: []
50
33
  require_paths:
51
34
  - lib
52
35
  - ext
53
36
  required_ruby_version: !ruby/object:Gem::Requirement
54
- none: false
55
37
  requirements:
56
- - - ! '>='
38
+ - - '>='
57
39
  - !ruby/object:Gem::Version
58
40
  version: '0'
59
41
  required_rubygems_version: !ruby/object:Gem::Requirement
60
- none: false
61
42
  requirements:
62
- - - ! '>='
43
+ - - '>='
63
44
  - !ruby/object:Gem::Version
64
45
  version: '0'
65
46
  requirements: []
66
47
  rubyforge_project:
67
- rubygems_version: 1.8.21
48
+ rubygems_version: 2.0.5
68
49
  signing_key:
69
- specification_version: 3
50
+ specification_version: 4
70
51
  summary: Native DTrace probes for ruby.
71
52
  test_files: []
53
+ has_rdoc:
data/ext/libusdt/LICENCE DELETED
@@ -1,21 +0,0 @@
1
- Copyright 2012 Chris Andrews. All rights reserved.
2
-
3
- Redistribution and use in source and binary forms, with or without modification, are
4
- permitted provided that the following conditions are met:
5
-
6
- 1. Redistributions of source code must retain the above copyright notice, this list of
7
- conditions and the following disclaimer.
8
-
9
- 2. Redistributions in binary form must reproduce the above copyright notice, this list
10
- of conditions and the following disclaimer in the documentation and/or other materials
11
- provided with the distribution.
12
-
13
- THIS SOFTWARE IS PROVIDED BY CHRIS ANDREWS ``AS IS'' AND ANY EXPRESS OR IMPLIED
14
- WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
15
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CHRIS ANDREWS OR
16
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
18
- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
19
- ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
20
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
21
- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/ext/libusdt/Makefile DELETED
@@ -1,148 +0,0 @@
1
- CC = gcc
2
- CFLAGS = -O2
3
-
4
- # MAC_BUILD - set this to "universal" to build a 2-way fat library
5
- MAC_BUILD = universal
6
-
7
- # if ARCH set, disable universal build on the mac
8
- ifdef ARCH
9
- MAC_BUILD =
10
- else
11
- ARCH = $(shell uname -m)
12
- endif
13
-
14
- UNAME = $(shell uname -s)
15
-
16
- ifeq ($(UNAME), SunOS)
17
- RANLIB=/bin/true
18
- PATH +=:/usr/perl5/5.10.0/bin:/usr/perl5/5.12/bin
19
- CFLAGS += -fPIC
20
-
21
- ifeq ($(ARCH), i86pc)
22
- ARCH = $(shell isainfo -k)
23
- ifeq ($(ARCH), amd64)
24
- ARCH = x86_64
25
- else
26
- ARCH = i386
27
- endif
28
- endif
29
- ifeq ($(ARCH), x86_64)
30
- CFLAGS += -m64
31
- endif
32
- endif
33
-
34
- ifeq ($(UNAME), FreeBSD)
35
- RANLIB=ranlib
36
- CFLAGS += -Wno-error=unknown-pragmas -I/usr/src/sys/cddl/compat/opensolaris -I/usr/src/sys/cddl/contrib/opensolaris/uts/common
37
- ifeq ($(ARCH), i386)
38
- CFLAGS += -m32
39
- endif
40
- endif
41
-
42
- ifeq ($(UNAME), Darwin)
43
- RANLIB=ranlib
44
- ifeq ($(MAC_BUILD), universal)
45
- CFLAGS += -arch i386 -arch x86_64
46
- else
47
- CFLAGS += -arch $(ARCH)
48
- endif
49
- endif
50
-
51
- # main library build
52
- objects = usdt.o usdt_dof_file.o usdt_tracepoints.o usdt_probe.o usdt_dof.o usdt_dof_sections.o
53
- headers = usdt.h usdt_internal.h
54
-
55
- .c.o: $(headers)
56
-
57
- all: libusdt.a
58
-
59
- libusdt.a: $(objects) $(headers)
60
- rm -f libusdt.a
61
- $(AR) cru libusdt.a $(objects)
62
- $(RANLIB) libusdt.a
63
-
64
- # Tracepoints build.
65
- #
66
- # If on Darwin and building a universal library, manually assemble a
67
- # two-way fat object file from both the 32 and 64 bit tracepoint asm
68
- # files.
69
- #
70
- # Otherwise, just choose the appropriate asm file based on the build
71
- # architecture.
72
-
73
- ifeq ($(UNAME), Darwin)
74
- ifeq ($(MAC_BUILD), universal)
75
-
76
- usdt_tracepoints_i386.o: usdt_tracepoints_i386.s
77
- $(CC) -arch i386 -o usdt_tracepoints_i386.o -c usdt_tracepoints_i386.s
78
-
79
- usdt_tracepoints_x86_64.o: usdt_tracepoints_x86_64.s
80
- $(CC) -arch x86_64 -o usdt_tracepoints_x86_64.o -c usdt_tracepoints_x86_64.s
81
-
82
- usdt_tracepoints.o: usdt_tracepoints_i386.o usdt_tracepoints_x86_64.o
83
- lipo -create -output usdt_tracepoints.o usdt_tracepoints_i386.o \
84
- usdt_tracepoints_x86_64.o
85
-
86
- else # Darwin, not universal
87
- usdt_tracepoints.o: usdt_tracepoints_$(ARCH).s
88
- $(CC) -arch $(ARCH) -o usdt_tracepoints.o -c usdt_tracepoints_$(ARCH).s
89
- endif
90
-
91
- else # not Darwin; FreeBSD and Illumos
92
-
93
- ifeq ($(ARCH), x86_64)
94
- usdt_tracepoints.o: usdt_tracepoints_x86_64.s
95
- $(CC) $(CFLAGS) -o usdt_tracepoints.o -c usdt_tracepoints_x86_64.s
96
- endif
97
- ifeq ($(ARCH), i386)
98
- usdt_tracepoints.o: usdt_tracepoints_i386.s
99
- $(CC) $(CFLAGS) -o usdt_tracepoints.o -c usdt_tracepoints_i386.s
100
- endif
101
-
102
- endif
103
-
104
- clean:
105
- rm -f *.gch
106
- rm -f *.o
107
- rm -f libusdt.a
108
- rm -f test_usdt
109
- rm -f test_usdt32
110
- rm -f test_usdt64
111
- rm -f test_mem_usage
112
-
113
- .PHONY: clean test
114
-
115
- # testing
116
-
117
- test_mem_usage: libusdt.a test_mem_usage.o
118
- $(CC) $(CFLAGS) -o test_mem_usage test_mem_usage.o libusdt.a
119
-
120
- ifeq ($(UNAME), Darwin)
121
- ifeq ($(MAC_BUILD), universal)
122
- test_usdt64: libusdt.a test_usdt.o
123
- $(CC) -arch x86_64 -o test_usdt64 test_usdt.o libusdt.a
124
- test_usdt32: libusdt.a test_usdt.o
125
- $(CC) -arch i386 -o test_usdt32 test_usdt.o libusdt.a
126
- else
127
- test_usdt: libusdt.a test_usdt.o
128
- $(CC) $(CFLAGS) -o test_usdt test_usdt.o libusdt.a
129
- endif
130
- else
131
- test_usdt: libusdt.a test_usdt.o
132
- $(CC) $(CFLAGS) -o test_usdt test_usdt.o libusdt.a
133
- endif
134
-
135
- ifeq ($(UNAME), Darwin)
136
- ifeq ($(MAC_BUILD), universal)
137
- test: test_usdt32 test_usdt64
138
- sudo prove test.pl :: 64
139
- sudo prove test.pl :: 32
140
- else
141
- test: test_usdt
142
- sudo prove test.pl
143
- endif
144
- else
145
- test: test_usdt
146
- sudo prove test.pl
147
- endif
148
-
@@ -1,81 +0,0 @@
1
- libusdt
2
- =======
3
-
4
- This is "libusdt", an extraction into a C library of the common parts
5
- of ruby-dtrace[1], perl-dtrace[2] and node-dtrace-provider[3].
6
-
7
- Those individual language-specific implementations will then become
8
- bindings to this library, rather than containing their own
9
- implementations of DOF generation and probe creation. Other dynamic
10
- language bindings could then easily follow.
11
-
12
- The idea here is to allow the specification of a DTrace provider
13
- dynamically in code and then create the provider at runtime. This
14
- allows providers to be specified in dynamic languages, given suitable
15
- bindings.
16
-
17
- The general approach is to create two stub functions for each probe,
18
- one for the is-enabled check and one for the probe itself. These
19
- contain the appropriate instruction sequences to appear to DTrace as
20
- compiled-in tracepoints. A minimal DOF document is built describing
21
- the provider and indicating these stub functions as the tracepoints,
22
- then submitted to the kernel, creating the provider. The API then
23
- exposes the stubs, through which the probes may be fired.
24
-
25
- Status
26
- ------
27
-
28
- The implementation here works as shown in test_usdt.c on Mac OS X,
29
- i386 and x86_64, on Solaris-like systems, i386 and x86_64 and on
30
- FreeBSD, x86_64 only (so far).
31
-
32
- Is-enabled probes are supported and exposed in the API.
33
-
34
- There is a "test" target which runs a number of tests of the library,
35
- for which perl is required.
36
-
37
- OS X builds are Universal by default, and on Solaris, the ARCH
38
- variable may be set to either i386 or x86_64 to force a particular
39
- build.
40
-
41
- FreeBSD builds suffer from broken argument handling; this is a known
42
- issue with the current state of DTrace generally on FreeBSD: only the
43
- first four arguments work reliably. See:
44
-
45
- http://wiki.freebsd.org/DTraceTODO
46
-
47
- See Also
48
- --------
49
-
50
- There are experimental Lua bindings available, which are a thin
51
- layer over this library, and should serve as an example of typical use
52
- as a dynamic language extension:
53
-
54
- https://github.com/chrisa/lua-usdt
55
-
56
- There are also Ruby bindings by Kevin Chan, replacing the provider
57
- implementation in ruby-dtrace:
58
-
59
- https://github.com/kevinykchan/ruby-usdt
60
-
61
- To Do
62
- -----
63
-
64
- Platform support:
65
-
66
- * add support for FreeBSD 9.0 i386
67
- * add support for Mac OS X PowerPC
68
- * add support for Solaris SPARC
69
-
70
- Features:
71
-
72
- * add a "low level" API, allowing alternative provision of
73
- tracepoints for closer integration with language VMs.
74
-
75
- * support structured types, with close integration with the host
76
- DTrace system.
77
-
78
-
79
- [1] https://github.com/chrisa/ruby-dtrace
80
- [2] https://github.com/chrisa/perl-dtrace
81
- [3] https://github.com/chrisa/node-dtrace-provider
data/ext/libusdt/test.pl DELETED
@@ -1,112 +0,0 @@
1
- #!/usr/bin/perl
2
- use strict;
3
- use warnings;
4
- use IPC::Open3;
5
- use Symbol 'gensym';
6
- use IO::Handle;
7
- use Test::More qw/ no_plan /;
8
-
9
- my $USDT_ARG_MAX = 32;
10
-
11
- my $arch;
12
- if (scalar @ARGV == 1) {
13
- $arch = $ARGV[0];
14
- }
15
-
16
- my $user_t = ($^O eq 'solaris') ? 'uintptr_t' : 'user_addr_t';
17
-
18
- run_tests('c', 'A');
19
- run_tests('i', 1);
20
-
21
- sub run_tests {
22
- my ($type, $start_arg) = @_;
23
-
24
- for my $i (0..$USDT_ARG_MAX) {
25
- my ($t_status, $d_status, $output) = run_dtrace('func', 'name', split(//, $type x $i));
26
- is($t_status, 0, 'test exit status is 0');
27
- is($d_status, 0, 'dtrace exit status is 0');
28
- like($output, qr/func:name/, 'function and name match');
29
-
30
- my $arg = $start_arg;
31
- for my $j (0..$i - 1) {
32
- like($output, qr/arg$j:'\Q$arg\E'/, "type '$type' arg $j is $arg");
33
- if ($type eq 'i') {
34
- $arg++;
35
- }
36
- else {
37
- $arg = chr(ord($arg) + 1);
38
- }
39
- }
40
- }
41
- }
42
-
43
- # --------------------------------------------------------------------------
44
-
45
- sub gen_d {
46
- my (@types) = @_;
47
-
48
- my $d = 'testlibusdt*:::{ ';
49
- my $i = 0;
50
- for my $type (@types) {
51
- if ($type eq 'i') {
52
- $d .= "printf(\"arg$i:'%i' \", args[$i]); ";
53
- }
54
- if ($type eq 'c') {
55
- $d .= "printf(\"arg$i:'%s' \", copyinstr(($user_t)args[$i])); ";
56
- }
57
- $i++;
58
- }
59
- $d .= '}';
60
-
61
- return $d;
62
- }
63
-
64
- sub run_dtrace {
65
- my ($func, $name, @types) = @_;
66
- my $d = gen_d(@types);
67
-
68
- my @t_cmd;
69
- if (defined $arch) {
70
- @t_cmd = ("./test_usdt$arch", $func, $name, @types);
71
- }
72
- else {
73
- @t_cmd = ("./test_usdt", $func, $name, @types);
74
- }
75
-
76
- my ($d_wtr, $d_rdr, $d_err);
77
- my ($t_wtr, $t_rdr, $t_err);
78
-
79
- $d_err = gensym;
80
- $t_err = gensym;
81
-
82
- #diag(join(' ', @t_cmd));
83
- my $t_pid = open3($t_wtr, $t_rdr, $t_err, @t_cmd);
84
- my $enabled = $t_rdr->getline;
85
-
86
- my @d_cmd = ('/usr/sbin/dtrace', '-p', $t_pid, '-n', $d);
87
-
88
- #diag(join(' ', @d_cmd));
89
- my $d_pid = open3($d_wtr, $d_rdr, $d_err, @d_cmd);
90
- my $matched = $d_err->getline; # expect "matched 1 probe"
91
-
92
- $t_wtr->print("go\n");
93
- $t_wtr->flush;
94
- waitpid( $t_pid, 0 );
95
- my $t_status = $? >> 8;
96
-
97
- my ($header, $output) = ($d_rdr->getline, $d_rdr->getline);
98
- chomp $header;
99
- chomp $output;
100
- #diag("DTrace header: $header\n");
101
- #diag("DTrace output: $output\n");
102
- waitpid( $d_pid, 0 );
103
-
104
- my $d_status = $? >> 8;
105
- while (!$d_err->eof) {
106
- my $error = $d_err->getline;
107
- chomp $error;
108
- #diag "DTrace error: $error";
109
- }
110
-
111
- return ($t_status, $d_status, $output || '');
112
- }