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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 32ca9d27b82e9e04dc7c82c91841ba967dea40d8
4
- data.tar.gz: 90ea9c2c69fbc5311ea9da9992d0f7339ee5d9c6
3
+ metadata.gz: 465f1aa47fc3e1464824f95cec1bfc9ffab8fd29
4
+ data.tar.gz: af101a5e965a3aa2f235b5fe7f95eff573e6d622
5
5
  SHA512:
6
- metadata.gz: 27df55c3cafad792beaa5f0858a6abd624d6c57708f79efb41d4ab2fe422429ac928dc18f234b4fce44b2ced1086021990b2ea7d55fe0f4a750827aa56a02a70
7
- data.tar.gz: a909999ff4e99cca642386a96388f2838edeb5c4765176280734e9aedca964c41eb22a8d66d4331ca979e0403e749144d35d81ad49e5057e6df8865d3a84b4b4
6
+ metadata.gz: 836df20d76b44ae9e03952af0016e08bd1fbfbb46ca72624e29a9f73120499c59785b700eb900a33f8d45aa625772f9f6bb376aa7858c5a896cea8e193ace051
7
+ data.tar.gz: 6844f06f4be41aa88d9b3901f3fd0b2cfe1e9ceb4e021d4edd240183512f8110239fe4d84a8dd620f89e33b4a7382bd88725824f4483e9858835422d5b669650
@@ -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
@@ -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
+ }