ruby-usdt 0.2.0 → 0.2.1

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.
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
+ }