ruby-usdt 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/libusdt/Makefile +77 -47
- data/ext/libusdt/test.pl +1 -1
- data/ext/libusdt/test_mem_usage.c +77 -0
- data/ext/libusdt/test_usdt.c +10 -3
- data/ext/libusdt/usdt.c +118 -3
- data/ext/libusdt/usdt.h +11 -2
- data/ext/libusdt/usdt_dof.c +8 -2
- data/ext/libusdt/usdt_dof_file.c +32 -2
- data/ext/libusdt/usdt_dof_sections.c +5 -2
- data/ext/libusdt/usdt_internal.h +1 -0
- data/ext/libusdt/usdt_probe.c +13 -9
- data/ext/libusdt/usdt_tracepoints_x86_64.s +1 -0
- data/lib/usdt/version.rb +1 -1
- metadata +2 -1
data/ext/libusdt/Makefile
CHANGED
@@ -1,25 +1,54 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
CC = gcc
|
2
|
+
CFLAGS = -O2
|
3
3
|
|
4
|
-
MAC_BUILD
|
5
|
-
|
6
|
-
|
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)
|
7
15
|
|
8
16
|
ifeq ($(UNAME), SunOS)
|
9
|
-
|
10
|
-
|
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
|
11
29
|
ifeq ($(ARCH), x86_64)
|
12
30
|
CFLAGS += -m64
|
13
31
|
endif
|
14
32
|
endif
|
15
33
|
|
16
34
|
ifeq ($(UNAME), FreeBSD)
|
17
|
-
|
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
|
18
37
|
ifeq ($(ARCH), i386)
|
19
38
|
CFLAGS += -m32
|
20
39
|
endif
|
21
40
|
endif
|
22
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
|
23
52
|
objects = usdt.o usdt_dof_file.o usdt_tracepoints.o usdt_probe.o usdt_dof.o usdt_dof_sections.o
|
24
53
|
headers = usdt.h usdt_internal.h
|
25
54
|
|
@@ -27,55 +56,66 @@ headers = usdt.h usdt_internal.h
|
|
27
56
|
|
28
57
|
all: libusdt.a
|
29
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
|
+
|
30
73
|
ifeq ($(UNAME), Darwin)
|
31
74
|
ifeq ($(MAC_BUILD), universal)
|
32
|
-
CFLAGS+= -arch i386 -arch x86_64
|
33
75
|
|
34
76
|
usdt_tracepoints_i386.o: usdt_tracepoints_i386.s
|
35
|
-
|
77
|
+
$(CC) -arch i386 -o usdt_tracepoints_i386.o -c usdt_tracepoints_i386.s
|
36
78
|
|
37
79
|
usdt_tracepoints_x86_64.o: usdt_tracepoints_x86_64.s
|
38
|
-
|
80
|
+
$(CC) -arch x86_64 -o usdt_tracepoints_x86_64.o -c usdt_tracepoints_x86_64.s
|
39
81
|
|
40
82
|
usdt_tracepoints.o: usdt_tracepoints_i386.o usdt_tracepoints_x86_64.o
|
41
83
|
lipo -create -output usdt_tracepoints.o usdt_tracepoints_i386.o \
|
42
84
|
usdt_tracepoints_x86_64.o
|
43
|
-
else
|
44
|
-
|
45
|
-
ifeq ($(ARCH), x86_64)
|
46
|
-
usdt_tracepoints.o: usdt_tracepoints_x86_64.s
|
47
|
-
as -o usdt_tracepoints.o usdt_tracepoints_x86_64.s
|
48
|
-
else
|
49
|
-
usdt_tracepoints.o: usdt_tracepoints_i386.s
|
50
|
-
as -o usdt_tracepoints.o usdt_tracepoints_i386.s
|
51
|
-
endif
|
52
85
|
|
53
|
-
|
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
|
54
89
|
endif
|
55
90
|
|
56
|
-
|
57
|
-
ifeq ($(ARCH), amd64)
|
58
|
-
usdt_tracepoints.o: usdt_tracepoints_x86_64.s
|
59
|
-
as --64 -o usdt_tracepoints.o usdt_tracepoints_x86_64.s
|
60
|
-
else
|
61
|
-
usdt_tracepoints.o: usdt_tracepoints_i386.s
|
62
|
-
as --32 -o usdt_tracepoints.o usdt_tracepoints_i386.s
|
63
|
-
endif
|
64
|
-
endif
|
91
|
+
else # not Darwin; FreeBSD and Illumos
|
65
92
|
|
66
|
-
ifeq ($(UNAME), SunOS)
|
67
93
|
ifeq ($(ARCH), x86_64)
|
68
94
|
usdt_tracepoints.o: usdt_tracepoints_x86_64.s
|
69
|
-
|
70
|
-
|
95
|
+
$(CC) $(CFLAGS) -o usdt_tracepoints.o -c usdt_tracepoints_x86_64.s
|
96
|
+
endif
|
97
|
+
ifeq ($(ARCH), i386)
|
71
98
|
usdt_tracepoints.o: usdt_tracepoints_i386.s
|
72
|
-
|
99
|
+
$(CC) $(CFLAGS) -o usdt_tracepoints.o -c usdt_tracepoints_i386.s
|
73
100
|
endif
|
101
|
+
|
74
102
|
endif
|
75
103
|
|
76
|
-
|
77
|
-
|
78
|
-
|
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
|
79
119
|
|
80
120
|
ifeq ($(UNAME), Darwin)
|
81
121
|
ifeq ($(MAC_BUILD), universal)
|
@@ -92,15 +132,6 @@ test_usdt: libusdt.a test_usdt.o
|
|
92
132
|
$(CC) $(CFLAGS) -o test_usdt test_usdt.o libusdt.a
|
93
133
|
endif
|
94
134
|
|
95
|
-
clean:
|
96
|
-
rm -f *.gch
|
97
|
-
rm -f *.o
|
98
|
-
rm -f libusdt.a
|
99
|
-
rm -f fat_libusdt.a
|
100
|
-
rm -f test_usdt
|
101
|
-
rm -f test_usdt32
|
102
|
-
rm -f test_usdt64
|
103
|
-
|
104
135
|
ifeq ($(UNAME), Darwin)
|
105
136
|
ifeq ($(MAC_BUILD), universal)
|
106
137
|
test: test_usdt32 test_usdt64
|
@@ -115,4 +146,3 @@ test: test_usdt
|
|
115
146
|
sudo prove test.pl
|
116
147
|
endif
|
117
148
|
|
118
|
-
.PHONY: clean test
|
data/ext/libusdt/test.pl
CHANGED
@@ -83,7 +83,7 @@ sub run_dtrace {
|
|
83
83
|
my $t_pid = open3($t_wtr, $t_rdr, $t_err, @t_cmd);
|
84
84
|
my $enabled = $t_rdr->getline;
|
85
85
|
|
86
|
-
my @d_cmd = ('dtrace', '-p', $t_pid, '-n', $d);
|
86
|
+
my @d_cmd = ('/usr/sbin/dtrace', '-p', $t_pid, '-n', $d);
|
87
87
|
|
88
88
|
#diag(join(' ', @d_cmd));
|
89
89
|
my $d_pid = open3($d_wtr, $d_rdr, $d_err, @d_cmd);
|
@@ -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
|
+
}
|
data/ext/libusdt/test_usdt.c
CHANGED
@@ -11,9 +11,8 @@
|
|
11
11
|
static void
|
12
12
|
fire_probe(usdt_probedef_t *probedef, int argc, void **argv)
|
13
13
|
{
|
14
|
-
if (usdt_is_enabled(probedef->probe))
|
14
|
+
if (usdt_is_enabled(probedef->probe))
|
15
15
|
usdt_fire_probe(probedef->probe, argc, argv);
|
16
|
-
}
|
17
16
|
}
|
18
17
|
|
19
18
|
int main(int argc, char **argv) {
|
@@ -21,7 +20,7 @@ int main(int argc, char **argv) {
|
|
21
20
|
usdt_probedef_t *probedef;
|
22
21
|
char char_argv[USDT_ARG_MAX];
|
23
22
|
int int_argv[USDT_ARG_MAX * 2];
|
24
|
-
void **args;
|
23
|
+
void **args = NULL;
|
25
24
|
int i;
|
26
25
|
char buf[255];
|
27
26
|
|
@@ -75,6 +74,14 @@ int main(int argc, char **argv) {
|
|
75
74
|
fgets(buf, 255, stdin);
|
76
75
|
|
77
76
|
fire_probe(probedef, (argc-3), (void **)args);
|
77
|
+
usdt_probe_release(probedef);
|
78
|
+
|
79
|
+
if ((usdt_provider_disable(provider)) < 0) {
|
80
|
+
fprintf(stderr, "unable to disable provider: %s\n", usdt_errstr(provider));
|
81
|
+
exit (1);
|
82
|
+
}
|
83
|
+
|
84
|
+
usdt_provider_free(provider);
|
78
85
|
|
79
86
|
return 0;
|
80
87
|
}
|
data/ext/libusdt/usdt.c
CHANGED
@@ -15,9 +15,33 @@ char *usdt_errors[] = {
|
|
15
15
|
"failed to allocate page-aligned memory",
|
16
16
|
"no probes defined",
|
17
17
|
"failed to load DOF: %s",
|
18
|
-
"provider is already enabled"
|
18
|
+
"provider is already enabled",
|
19
|
+
"failed to unload DOF: %s",
|
20
|
+
"probe named %s:%s:%s:%s already exists",
|
21
|
+
"failed to remove probe %s:%s:%s:%s"
|
19
22
|
};
|
20
23
|
|
24
|
+
static void
|
25
|
+
free_probedef(usdt_probedef_t *pd)
|
26
|
+
{
|
27
|
+
switch (pd->refcnt) {
|
28
|
+
case 1:
|
29
|
+
free((char *)pd->function);
|
30
|
+
free((char *)pd->name);
|
31
|
+
if (pd->probe) {
|
32
|
+
free(pd->probe->isenabled_addr);
|
33
|
+
free(pd->probe);
|
34
|
+
}
|
35
|
+
free(pd);
|
36
|
+
break;
|
37
|
+
case 2:
|
38
|
+
pd->refcnt = 1;
|
39
|
+
break;
|
40
|
+
default:
|
41
|
+
break;
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
21
45
|
usdt_provider_t *
|
22
46
|
usdt_create_provider(const char *name, const char *module)
|
23
47
|
{
|
@@ -46,6 +70,7 @@ usdt_create_probe(const char *func, const char *name, size_t argc, const char **
|
|
46
70
|
if ((p = malloc(sizeof *p)) == NULL)
|
47
71
|
return (NULL);
|
48
72
|
|
73
|
+
p->refcnt = 2;
|
49
74
|
p->function = strdup(func);
|
50
75
|
p->name = strdup(name);
|
51
76
|
p->argc = argc;
|
@@ -62,10 +87,28 @@ usdt_create_probe(const char *func, const char *name, size_t argc, const char **
|
|
62
87
|
}
|
63
88
|
|
64
89
|
void
|
90
|
+
usdt_probe_release(usdt_probedef_t *probedef)
|
91
|
+
{
|
92
|
+
free_probedef(probedef);
|
93
|
+
}
|
94
|
+
|
95
|
+
int
|
65
96
|
usdt_provider_add_probe(usdt_provider_t *provider, usdt_probedef_t *probedef)
|
66
97
|
{
|
67
98
|
usdt_probedef_t *pd;
|
68
99
|
|
100
|
+
if (provider->probedefs != NULL) {
|
101
|
+
for (pd = provider->probedefs; (pd != NULL); pd = pd->next) {
|
102
|
+
if ((strcmp(pd->name, probedef->name) == 0) &&
|
103
|
+
(strcmp(pd->function, probedef->function) == 0)) {
|
104
|
+
usdt_error(provider, USDT_ERROR_DUP_PROBE,
|
105
|
+
provider->name, provider->module,
|
106
|
+
probedef->function, probedef->name);
|
107
|
+
return (-1);
|
108
|
+
}
|
109
|
+
}
|
110
|
+
}
|
111
|
+
|
69
112
|
probedef->next = NULL;
|
70
113
|
if (provider->probedefs == NULL)
|
71
114
|
provider->probedefs = probedef;
|
@@ -73,6 +116,39 @@ usdt_provider_add_probe(usdt_provider_t *provider, usdt_probedef_t *probedef)
|
|
73
116
|
for (pd = provider->probedefs; (pd->next != NULL); pd = pd->next) ;
|
74
117
|
pd->next = probedef;
|
75
118
|
}
|
119
|
+
|
120
|
+
return (0);
|
121
|
+
}
|
122
|
+
|
123
|
+
int
|
124
|
+
usdt_provider_remove_probe(usdt_provider_t *provider, usdt_probedef_t *probedef)
|
125
|
+
{
|
126
|
+
usdt_probedef_t *pd, *prev_pd = NULL;
|
127
|
+
|
128
|
+
if (provider->probedefs == NULL) {
|
129
|
+
usdt_error(provider, USDT_ERROR_NOPROBES);
|
130
|
+
return (-1);
|
131
|
+
}
|
132
|
+
|
133
|
+
for (pd = provider->probedefs; (pd != NULL);
|
134
|
+
prev_pd = pd, pd = pd->next) {
|
135
|
+
|
136
|
+
if ((strcmp(pd->name, probedef->name) == 0) &&
|
137
|
+
(strcmp(pd->function, probedef->function) == 0)) {
|
138
|
+
|
139
|
+
if (prev_pd == NULL)
|
140
|
+
provider->probedefs = pd->next;
|
141
|
+
else
|
142
|
+
prev_pd->next = pd->next;
|
143
|
+
|
144
|
+
return (0);
|
145
|
+
}
|
146
|
+
}
|
147
|
+
|
148
|
+
usdt_error(provider, USDT_ERROR_REMOVE_PROBE,
|
149
|
+
provider->name, provider->module,
|
150
|
+
probedef->function, probedef->name);
|
151
|
+
return (-1);
|
76
152
|
}
|
77
153
|
|
78
154
|
int
|
@@ -87,7 +163,7 @@ usdt_provider_enable(usdt_provider_t *provider)
|
|
87
163
|
|
88
164
|
if (provider->enabled == 1) {
|
89
165
|
usdt_error(provider, USDT_ERROR_ALREADYENABLED);
|
90
|
-
return (0);
|
166
|
+
return (0); /* not fatal */
|
91
167
|
}
|
92
168
|
|
93
169
|
if (provider->probedefs == NULL) {
|
@@ -107,7 +183,7 @@ usdt_provider_enable(usdt_provider_t *provider)
|
|
107
183
|
return (-1);
|
108
184
|
}
|
109
185
|
|
110
|
-
if ((usdt_strtab_add(&strtab, provider->name))
|
186
|
+
if ((usdt_strtab_add(&strtab, provider->name)) == 0) {
|
111
187
|
usdt_error(provider, USDT_ERROR_MALLOC);
|
112
188
|
return (-1);
|
113
189
|
}
|
@@ -133,15 +209,54 @@ usdt_provider_enable(usdt_provider_t *provider)
|
|
133
209
|
|
134
210
|
usdt_dof_file_generate(file, &strtab);
|
135
211
|
|
212
|
+
usdt_dof_section_free(&strtab);
|
213
|
+
for (i = 0; i < 5; i++)
|
214
|
+
usdt_dof_section_free(§s[i]);
|
215
|
+
|
136
216
|
if ((usdt_dof_file_load(file, provider->module)) < 0) {
|
137
217
|
usdt_error(provider, USDT_ERROR_LOADDOF, strerror(errno));
|
138
218
|
return (-1);
|
139
219
|
}
|
140
220
|
|
141
221
|
provider->enabled = 1;
|
222
|
+
provider->file = file;
|
223
|
+
|
224
|
+
return (0);
|
225
|
+
}
|
226
|
+
|
227
|
+
int
|
228
|
+
usdt_provider_disable(usdt_provider_t *provider)
|
229
|
+
{
|
230
|
+
if (provider->enabled == 0)
|
231
|
+
return (0);
|
232
|
+
|
233
|
+
if ((usdt_dof_file_unload((usdt_dof_file_t *)provider->file)) < 0) {
|
234
|
+
usdt_error(provider, USDT_ERROR_UNLOADDOF, strerror(errno));
|
235
|
+
return (-1);
|
236
|
+
}
|
237
|
+
|
238
|
+
usdt_dof_file_free(provider->file);
|
239
|
+
provider->file = NULL;
|
240
|
+
provider->enabled = 0;
|
241
|
+
|
142
242
|
return (0);
|
143
243
|
}
|
144
244
|
|
245
|
+
void
|
246
|
+
usdt_provider_free(usdt_provider_t *provider)
|
247
|
+
{
|
248
|
+
usdt_probedef_t *pd, *next;
|
249
|
+
|
250
|
+
for (pd = provider->probedefs; pd != NULL; pd = next) {
|
251
|
+
next = pd->next;
|
252
|
+
free_probedef(pd);
|
253
|
+
}
|
254
|
+
|
255
|
+
free((char *)provider->name);
|
256
|
+
free((char *)provider->module);
|
257
|
+
free(provider);
|
258
|
+
}
|
259
|
+
|
145
260
|
int
|
146
261
|
usdt_is_enabled(usdt_probe_t *probe)
|
147
262
|
{
|
data/ext/libusdt/usdt.h
CHANGED
@@ -17,7 +17,10 @@ typedef enum usdt_error {
|
|
17
17
|
USDT_ERROR_VALLOC,
|
18
18
|
USDT_ERROR_NOPROBES,
|
19
19
|
USDT_ERROR_LOADDOF,
|
20
|
-
USDT_ERROR_ALREADYENABLED
|
20
|
+
USDT_ERROR_ALREADYENABLED,
|
21
|
+
USDT_ERROR_UNLOADDOF,
|
22
|
+
USDT_ERROR_DUP_PROBE,
|
23
|
+
USDT_ERROR_REMOVE_PROBE
|
21
24
|
} usdt_error_t;
|
22
25
|
|
23
26
|
typedef struct usdt_probe {
|
@@ -35,10 +38,12 @@ typedef struct usdt_probedef {
|
|
35
38
|
usdt_argtype_t types[USDT_ARG_MAX];
|
36
39
|
struct usdt_probe *probe;
|
37
40
|
struct usdt_probedef *next;
|
41
|
+
int refcnt;
|
38
42
|
} usdt_probedef_t;
|
39
43
|
|
40
44
|
usdt_probedef_t *usdt_create_probe(const char *func, const char *name,
|
41
45
|
size_t argc, const char **types);
|
46
|
+
void usdt_probe_release(usdt_probedef_t *probedef);
|
42
47
|
|
43
48
|
typedef struct usdt_provider {
|
44
49
|
const char *name;
|
@@ -46,11 +51,15 @@ typedef struct usdt_provider {
|
|
46
51
|
usdt_probedef_t *probedefs;
|
47
52
|
char *error;
|
48
53
|
int enabled;
|
54
|
+
void *file;
|
49
55
|
} usdt_provider_t;
|
50
56
|
|
51
57
|
usdt_provider_t *usdt_create_provider(const char *name, const char *module);
|
52
|
-
|
58
|
+
int usdt_provider_add_probe(usdt_provider_t *provider, usdt_probedef_t *probedef);
|
59
|
+
int usdt_provider_remove_probe(usdt_provider_t *provider, usdt_probedef_t *probedef);
|
53
60
|
int usdt_provider_enable(usdt_provider_t *provider);
|
61
|
+
int usdt_provider_disable(usdt_provider_t *provider);
|
62
|
+
void usdt_provider_free(usdt_provider_t *provider);
|
54
63
|
|
55
64
|
void usdt_error(usdt_provider_t *provider, usdt_error_t error, ...);
|
56
65
|
char *usdt_errstr(usdt_provider_t *provider);
|
data/ext/libusdt/usdt_dof.c
CHANGED
@@ -79,6 +79,12 @@ usdt_dof_section_init(usdt_dof_section_t *section, uint32_t type, dof_secidx_t i
|
|
79
79
|
return (0);
|
80
80
|
}
|
81
81
|
|
82
|
+
void
|
83
|
+
usdt_dof_section_free(usdt_dof_section_t *section)
|
84
|
+
{
|
85
|
+
free(section->data);
|
86
|
+
}
|
87
|
+
|
82
88
|
int
|
83
89
|
usdt_strtab_init(usdt_strtab_t *strtab, dof_secidx_t index)
|
84
90
|
{
|
@@ -112,11 +118,11 @@ usdt_strtab_add(usdt_strtab_t *strtab, const char *string)
|
|
112
118
|
strtab->strindex += (length + 1);
|
113
119
|
|
114
120
|
if ((strtab->data = realloc(strtab->data, strtab->strindex)) == NULL)
|
115
|
-
return (
|
121
|
+
return (0);
|
116
122
|
|
117
123
|
memcpy((char *) (strtab->data + index), (char *)string, length + 1);
|
118
124
|
strtab->size = index + length + 1;
|
119
125
|
|
120
|
-
return index;
|
126
|
+
return (index);
|
121
127
|
}
|
122
128
|
|
data/ext/libusdt/usdt_dof_file.c
CHANGED
@@ -47,7 +47,10 @@ load_dof(int fd, dof_helper_t *dh)
|
|
47
47
|
val = (user_addr_t)(unsigned long)ioctlData;
|
48
48
|
ret = ioctl(fd, DTRACEHIOC_ADDDOF, &val);
|
49
49
|
|
50
|
-
|
50
|
+
if (ret < 0)
|
51
|
+
return ret;
|
52
|
+
|
53
|
+
return (int)(ioctlData->dofiod_helpers[0].dofhp_dof);
|
51
54
|
}
|
52
55
|
|
53
56
|
#else /* Solaris */
|
@@ -129,7 +132,8 @@ static size_t
|
|
129
132
|
add_section(usdt_dof_file_t *file, size_t offset, usdt_dof_section_t *section)
|
130
133
|
{
|
131
134
|
if (section->pad > 0) {
|
132
|
-
|
135
|
+
/* maximum padding required is 7 */
|
136
|
+
memcpy((file->dof + offset), "\0\0\0\0\0\0\0", section->pad);
|
133
137
|
offset += section->pad;
|
134
138
|
}
|
135
139
|
|
@@ -137,6 +141,25 @@ add_section(usdt_dof_file_t *file, size_t offset, usdt_dof_section_t *section)
|
|
137
141
|
return (offset + section->size);
|
138
142
|
}
|
139
143
|
|
144
|
+
int
|
145
|
+
usdt_dof_file_unload(usdt_dof_file_t *file)
|
146
|
+
{
|
147
|
+
int fd, ret;
|
148
|
+
|
149
|
+
if ((fd = open(helper, O_RDWR)) < 0)
|
150
|
+
return (-1);
|
151
|
+
|
152
|
+
ret = ioctl(fd, DTRACEHIOC_REMOVE, file->gen);
|
153
|
+
|
154
|
+
if (ret < 0)
|
155
|
+
return (-1);
|
156
|
+
|
157
|
+
if ((close(fd)) < 0)
|
158
|
+
return (-1);
|
159
|
+
|
160
|
+
return (0);
|
161
|
+
}
|
162
|
+
|
140
163
|
int
|
141
164
|
usdt_dof_file_load(usdt_dof_file_t *file, const char *module)
|
142
165
|
{
|
@@ -245,3 +268,10 @@ usdt_dof_file_init(usdt_provider_t *provider, size_t size)
|
|
245
268
|
|
246
269
|
return (file);
|
247
270
|
}
|
271
|
+
|
272
|
+
void
|
273
|
+
usdt_dof_file_free(usdt_dof_file_t *file)
|
274
|
+
{
|
275
|
+
free(file->dof);
|
276
|
+
free(file);
|
277
|
+
}
|
@@ -20,6 +20,7 @@ usdt_dof_probes_sect(usdt_dof_section_t *probes,
|
|
20
20
|
for (pd = provider->probedefs; pd != NULL; pd = pd->next) {
|
21
21
|
argc = 0;
|
22
22
|
argv = 0;
|
23
|
+
type = 0;
|
23
24
|
|
24
25
|
for (i = 0; i < pd->argc; i++) {
|
25
26
|
switch(pd->types[i]) {
|
@@ -45,7 +46,7 @@ usdt_dof_probes_sect(usdt_dof_section_t *probes,
|
|
45
46
|
|
46
47
|
#ifdef __x86_64__
|
47
48
|
p.dofpr_addr = (uint64_t) pd->probe->isenabled_addr;
|
48
|
-
#elif __i386__
|
49
|
+
#elif __i386__ || __i386
|
49
50
|
p.dofpr_addr = (uint32_t) pd->probe->isenabled_addr;
|
50
51
|
#else
|
51
52
|
#error "only x86_64 and i386 supported"
|
@@ -61,6 +62,8 @@ usdt_dof_probes_sect(usdt_dof_section_t *probes,
|
|
61
62
|
p.dofpr_noffs = 1;
|
62
63
|
p.dofpr_enoffidx = offidx;
|
63
64
|
p.dofpr_nenoffs = 1;
|
65
|
+
p.dofpr_pad1 = 0;
|
66
|
+
p.dofpr_pad2 = 0;
|
64
67
|
|
65
68
|
usdt_dof_section_add_data(probes, &p, sizeof(dof_probe_t));
|
66
69
|
probes->entsize = sizeof(dof_probe_t);
|
@@ -150,7 +153,7 @@ usdt_dof_provider_sect(usdt_dof_section_t *provider_s, usdt_provider_t *provider
|
|
150
153
|
p.dofpv_prargs = 2;
|
151
154
|
p.dofpv_proffs = 3;
|
152
155
|
p.dofpv_prenoffs = 4;
|
153
|
-
p.dofpv_name = 1;
|
156
|
+
p.dofpv_name = 1; /* provider name always first strtab entry. */
|
154
157
|
|
155
158
|
/*
|
156
159
|
* Stability is something of a hack. Everything is marked *
|
data/ext/libusdt/usdt_internal.h
CHANGED
@@ -80,6 +80,7 @@ usdt_dof_file_t *usdt_dof_file_init(usdt_provider_t *provider, size_t size);
|
|
80
80
|
void usdt_dof_file_append_section(usdt_dof_file_t *file, usdt_dof_section_t *section);
|
81
81
|
void usdt_dof_file_generate(usdt_dof_file_t *file, usdt_strtab_t *strtab);
|
82
82
|
int usdt_dof_file_load(usdt_dof_file_t *file, const char *module);
|
83
|
+
int usdt_dof_file_unload(usdt_dof_file_t *file);
|
83
84
|
|
84
85
|
int usdt_dof_probes_sect(usdt_dof_section_t *probes,
|
85
86
|
usdt_provider_t *provider, usdt_strtab_t *strtab);
|
data/ext/libusdt/usdt_probe.c
CHANGED
@@ -25,7 +25,7 @@ usdt_is_enabled_offset(usdt_probe_t *probe, char *dof)
|
|
25
25
|
{
|
26
26
|
uint32_t offset;
|
27
27
|
#ifdef __x86_64__
|
28
|
-
offset = ((uint64_t) probe->isenabled_addr - (uint64_t) dof +
|
28
|
+
offset = ((uint64_t) probe->isenabled_addr - (uint64_t) dof + 6);
|
29
29
|
#elif __i386__
|
30
30
|
offset = ((uint32_t) probe->isenabled_addr - (uint32_t) dof + 6);
|
31
31
|
#else
|
@@ -39,13 +39,13 @@ usdt_is_enabled_offset(usdt_probe_t *probe, char *dof)
|
|
39
39
|
uint32_t
|
40
40
|
usdt_probe_offset(usdt_probe_t *probe, char *dof, uint8_t argc)
|
41
41
|
{
|
42
|
-
return (
|
42
|
+
return (16);
|
43
43
|
}
|
44
44
|
|
45
45
|
uint32_t
|
46
46
|
usdt_is_enabled_offset(usdt_probe_t *probe, char *dof)
|
47
47
|
{
|
48
|
-
return (
|
48
|
+
return (8);
|
49
49
|
}
|
50
50
|
|
51
51
|
#endif
|
@@ -53,16 +53,20 @@ usdt_is_enabled_offset(usdt_probe_t *probe, char *dof)
|
|
53
53
|
int
|
54
54
|
usdt_create_tracepoints(usdt_probe_t *probe)
|
55
55
|
{
|
56
|
+
size_t size;
|
57
|
+
|
56
58
|
/* ensure that the tracepoints will fit the heap we're allocating */
|
57
|
-
|
59
|
+
size = ((char *)usdt_tracepoint_end - (char *)usdt_tracepoint_isenabled);
|
60
|
+
assert(size < FUNC_SIZE);
|
58
61
|
|
59
|
-
if ((probe->isenabled_addr = valloc(FUNC_SIZE)) == NULL)
|
62
|
+
if ((probe->isenabled_addr = (int (*)())valloc(FUNC_SIZE)) == NULL)
|
60
63
|
return (-1);
|
61
|
-
}
|
62
|
-
probe->probe_addr = probe->isenabled_addr +
|
63
|
-
(usdt_tracepoint_probe - usdt_tracepoint_isenabled);
|
64
64
|
|
65
|
-
|
65
|
+
size = ((char *)usdt_tracepoint_probe - (char *)usdt_tracepoint_isenabled);
|
66
|
+
probe->probe_addr = (char *)probe->isenabled_addr + size;
|
67
|
+
|
68
|
+
memcpy((void *)probe->isenabled_addr,
|
69
|
+
(const void *)usdt_tracepoint_isenabled, FUNC_SIZE);
|
66
70
|
mprotect((void *)probe->isenabled_addr, FUNC_SIZE,
|
67
71
|
PROT_READ | PROT_WRITE | PROT_EXEC);
|
68
72
|
|
data/lib/usdt/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-usdt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -25,6 +25,7 @@ files:
|
|
25
25
|
- ext/libusdt/Makefile
|
26
26
|
- ext/libusdt/README.md
|
27
27
|
- ext/libusdt/test.pl
|
28
|
+
- ext/libusdt/test_mem_usage.c
|
28
29
|
- ext/libusdt/test_usdt.c
|
29
30
|
- ext/libusdt/usdt.c
|
30
31
|
- ext/libusdt/usdt.h
|