ruby-usdt 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/libusdt/LICENCE +21 -0
- data/ext/libusdt/Makefile +148 -0
- data/ext/libusdt/README.md +81 -0
- data/ext/libusdt/test.pl +112 -0
- data/ext/libusdt/test_mem_usage.c +77 -0
- data/ext/libusdt/test_usdt.c +87 -0
- data/ext/libusdt/usdt.c +296 -0
- data/ext/libusdt/usdt.h +66 -0
- data/ext/libusdt/usdt_dof.c +128 -0
- data/ext/libusdt/usdt_dof_file.c +277 -0
- data/ext/libusdt/usdt_dof_sections.c +190 -0
- data/ext/libusdt/usdt_internal.h +95 -0
- data/ext/libusdt/usdt_probe.c +74 -0
- data/ext/libusdt/usdt_tracepoints_i386.s +69 -0
- data/ext/libusdt/usdt_tracepoints_x86_64.s +123 -0
- data/lib/usdt/version.rb +1 -1
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 465f1aa47fc3e1464824f95cec1bfc9ffab8fd29
|
4
|
+
data.tar.gz: af101a5e965a3aa2f235b5fe7f95eff573e6d622
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 836df20d76b44ae9e03952af0016e08bd1fbfbb46ca72624e29a9f73120499c59785b700eb900a33f8d45aa625772f9f6bb376aa7858c5a896cea8e193ace051
|
7
|
+
data.tar.gz: 6844f06f4be41aa88d9b3901f3fd0b2cfe1e9ceb4e021d4edd240183512f8110239fe4d84a8dd620f89e33b4a7382bd88725824f4483e9858835422d5b669650
|
data/ext/libusdt/LICENCE
ADDED
@@ -0,0 +1,21 @@
|
|
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.
|
@@ -0,0 +1,148 @@
|
|
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
|
+
|
@@ -0,0 +1,81 @@
|
|
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
ADDED
@@ -0,0 +1,112 @@
|
|
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
|
+
}
|
@@ -0,0 +1,77 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2012, Chris Andrews. All rights reserved.
|
3
|
+
*/
|
4
|
+
|
5
|
+
#include "usdt.h"
|
6
|
+
|
7
|
+
#include <stdio.h>
|
8
|
+
#include <stdlib.h>
|
9
|
+
#include <string.h>
|
10
|
+
|
11
|
+
static void
|
12
|
+
create_and_free_provider(int argc, char **argv)
|
13
|
+
{
|
14
|
+
usdt_provider_t *provider;
|
15
|
+
usdt_probedef_t *probedef;
|
16
|
+
|
17
|
+
if ((provider = usdt_create_provider("testlibusdt", "modname")) == NULL) {
|
18
|
+
fprintf(stderr, "unable to create provider\n");
|
19
|
+
exit (1);
|
20
|
+
}
|
21
|
+
if ((probedef = usdt_create_probe((const char *)argv[1],
|
22
|
+
(const char *)argv[2],
|
23
|
+
(argc-3), (const char **)&argv[3])) == NULL)
|
24
|
+
{
|
25
|
+
fprintf(stderr, "unable to create probe\n");
|
26
|
+
exit (1);
|
27
|
+
}
|
28
|
+
usdt_provider_add_probe(provider, probedef);
|
29
|
+
|
30
|
+
if ((usdt_provider_enable(provider)) < 0) {
|
31
|
+
fprintf(stderr, "unable to enable provider: %s\n", usdt_errstr(provider));
|
32
|
+
exit (1);
|
33
|
+
}
|
34
|
+
|
35
|
+
if ((usdt_provider_disable(provider)) < 0) {
|
36
|
+
fprintf(stderr, "unable to disable provider: %s\n", usdt_errstr(provider));
|
37
|
+
exit (1);
|
38
|
+
}
|
39
|
+
|
40
|
+
usdt_probe_release(probedef);
|
41
|
+
usdt_provider_free(provider);
|
42
|
+
}
|
43
|
+
|
44
|
+
int
|
45
|
+
main(int argc, char **argv)
|
46
|
+
{
|
47
|
+
char char_argv[USDT_ARG_MAX];
|
48
|
+
int int_argv[USDT_ARG_MAX * 2];
|
49
|
+
int i;
|
50
|
+
char buf[255];
|
51
|
+
|
52
|
+
for (i = 0; i < USDT_ARG_MAX; i++)
|
53
|
+
int_argv[i] = i + 1;
|
54
|
+
for (i = 0; i < USDT_ARG_MAX; i++)
|
55
|
+
char_argv[i] = (char) i + 65;
|
56
|
+
|
57
|
+
if (argc < 3) {
|
58
|
+
fprintf(stderr, "usage: %s func name [types ...]\n", argv[0]);
|
59
|
+
return(1);
|
60
|
+
}
|
61
|
+
|
62
|
+
for (i = 0; i < USDT_ARG_MAX; i++) {
|
63
|
+
if (argv[i+3] != NULL && i+3 < argc) {
|
64
|
+
if (strncmp("c", argv[i+3], 1) == 0) {
|
65
|
+
argv[i+3] = strdup("char *");
|
66
|
+
}
|
67
|
+
if (strncmp("i", argv[i+3], 1) == 0) {
|
68
|
+
argv[i+3] = strdup("int");
|
69
|
+
}
|
70
|
+
}
|
71
|
+
}
|
72
|
+
|
73
|
+
for (i = 0; i < 100000; i++)
|
74
|
+
create_and_free_provider(argc, argv);
|
75
|
+
|
76
|
+
return 0;
|
77
|
+
}
|