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.
@@ -0,0 +1,87 @@
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
+ fire_probe(usdt_probedef_t *probedef, int argc, void **argv)
13
+ {
14
+ if (usdt_is_enabled(probedef->probe))
15
+ usdt_fire_probe(probedef->probe, argc, argv);
16
+ }
17
+
18
+ int main(int argc, char **argv) {
19
+ usdt_provider_t *provider;
20
+ usdt_probedef_t *probedef;
21
+ char char_argv[USDT_ARG_MAX];
22
+ int int_argv[USDT_ARG_MAX * 2];
23
+ void **args = NULL;
24
+ int i;
25
+ char buf[255];
26
+
27
+ for (i = 0; i < USDT_ARG_MAX; i++)
28
+ int_argv[i] = i + 1;
29
+ for (i = 0; i < USDT_ARG_MAX; i++)
30
+ char_argv[i] = (char) i + 65;
31
+
32
+ if (argc < 3) {
33
+ fprintf(stderr, "usage: %s func name [types ...]\n", argv[0]);
34
+ return(1);
35
+ }
36
+
37
+ if (argc > 3) {
38
+ args = malloc((argc-3) * sizeof(void *));
39
+ }
40
+
41
+ for (i = 0; i < USDT_ARG_MAX; i++) {
42
+ if (argv[i+3] != NULL && i+3 < argc) {
43
+ if (strncmp("c", argv[i+3], 1) == 0) {
44
+ args[i] = (void *)strndup(&char_argv[i], 1);
45
+ argv[i+3] = strdup("char *");
46
+ }
47
+ if (strncmp("i", argv[i+3], 1) == 0) {
48
+ args[i] = (void *)(long)int_argv[i];
49
+ argv[i+3] = strdup("int");
50
+ }
51
+ }
52
+ }
53
+
54
+ if ((provider = usdt_create_provider("testlibusdt", "modname")) == NULL) {
55
+ fprintf(stderr, "unable to create provider\n");
56
+ exit (1);
57
+ }
58
+ if ((probedef = usdt_create_probe((const char *)argv[1],
59
+ (const char *)argv[2],
60
+ (argc-3), (const char **)&argv[3])) == NULL)
61
+ {
62
+ fprintf(stderr, "unable to create probe\n");
63
+ exit (1);
64
+ }
65
+ usdt_provider_add_probe(provider, probedef);
66
+
67
+ if ((usdt_provider_enable(provider)) < 0) {
68
+ fprintf(stderr, "unable to enable provider: %s\n", usdt_errstr(provider));
69
+ exit (1);
70
+ }
71
+
72
+ fprintf(stdout, "enabled\n");
73
+ fflush(stdout);
74
+ fgets(buf, 255, stdin);
75
+
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);
85
+
86
+ return 0;
87
+ }
@@ -0,0 +1,296 @@
1
+ /*
2
+ * Copyright (c) 2012, Chris Andrews. All rights reserved.
3
+ */
4
+
5
+ #include "usdt_internal.h"
6
+
7
+ #include <stdlib.h>
8
+ #include <stdarg.h>
9
+ #include <string.h>
10
+ #include <errno.h>
11
+ #include <stdio.h>
12
+
13
+ char *usdt_errors[] = {
14
+ "failed to allocate memory",
15
+ "failed to allocate page-aligned memory",
16
+ "no probes defined",
17
+ "failed to load DOF: %s",
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"
22
+ };
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
+
45
+ usdt_provider_t *
46
+ usdt_create_provider(const char *name, const char *module)
47
+ {
48
+ usdt_provider_t *provider;
49
+
50
+ if ((provider = malloc(sizeof *provider)) == NULL)
51
+ return NULL;
52
+
53
+ provider->name = strdup(name);
54
+ provider->module = strdup(module);
55
+ provider->probedefs = NULL;
56
+ provider->enabled = 0;
57
+
58
+ return provider;
59
+ }
60
+
61
+ usdt_probedef_t *
62
+ usdt_create_probe(const char *func, const char *name, size_t argc, const char **types)
63
+ {
64
+ int i;
65
+ usdt_probedef_t *p;
66
+
67
+ if (argc > USDT_ARG_MAX)
68
+ argc = USDT_ARG_MAX;
69
+
70
+ if ((p = malloc(sizeof *p)) == NULL)
71
+ return (NULL);
72
+
73
+ p->refcnt = 2;
74
+ p->function = strdup(func);
75
+ p->name = strdup(name);
76
+ p->argc = argc;
77
+ p->probe = NULL;
78
+
79
+ for (i = 0; i < argc; i++) {
80
+ if (strncmp("char *", types[i], 6) == 0)
81
+ p->types[i] = USDT_ARGTYPE_STRING;
82
+ if (strncmp("int", types[i], 3) == 0)
83
+ p->types[i] = USDT_ARGTYPE_INTEGER;
84
+ }
85
+
86
+ return (p);
87
+ }
88
+
89
+ void
90
+ usdt_probe_release(usdt_probedef_t *probedef)
91
+ {
92
+ free_probedef(probedef);
93
+ }
94
+
95
+ int
96
+ usdt_provider_add_probe(usdt_provider_t *provider, usdt_probedef_t *probedef)
97
+ {
98
+ usdt_probedef_t *pd;
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
+
112
+ probedef->next = NULL;
113
+ if (provider->probedefs == NULL)
114
+ provider->probedefs = probedef;
115
+ else {
116
+ for (pd = provider->probedefs; (pd->next != NULL); pd = pd->next) ;
117
+ pd->next = probedef;
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);
152
+ }
153
+
154
+ int
155
+ usdt_provider_enable(usdt_provider_t *provider)
156
+ {
157
+ usdt_strtab_t strtab;
158
+ usdt_dof_file_t *file;
159
+ usdt_probedef_t *pd;
160
+ int i;
161
+ size_t size;
162
+ usdt_dof_section_t sects[5];
163
+
164
+ if (provider->enabled == 1) {
165
+ usdt_error(provider, USDT_ERROR_ALREADYENABLED);
166
+ return (0); /* not fatal */
167
+ }
168
+
169
+ if (provider->probedefs == NULL) {
170
+ usdt_error(provider, USDT_ERROR_NOPROBES);
171
+ return (-1);
172
+ }
173
+
174
+ for (pd = provider->probedefs; pd != NULL; pd = pd->next) {
175
+ if ((pd->probe = malloc(sizeof(*pd->probe))) == NULL) {
176
+ usdt_error(provider, USDT_ERROR_MALLOC);
177
+ return (-1);
178
+ }
179
+ }
180
+
181
+ if ((usdt_strtab_init(&strtab, 0)) < 0) {
182
+ usdt_error(provider, USDT_ERROR_MALLOC);
183
+ return (-1);
184
+ }
185
+
186
+ if ((usdt_strtab_add(&strtab, provider->name)) == 0) {
187
+ usdt_error(provider, USDT_ERROR_MALLOC);
188
+ return (-1);
189
+ }
190
+
191
+ if ((usdt_dof_probes_sect(&sects[0], provider, &strtab)) < 0)
192
+ return (-1);
193
+ if ((usdt_dof_prargs_sect(&sects[1], provider)) < 0)
194
+ return (-1);
195
+
196
+ size = usdt_provider_dof_size(provider, &strtab);
197
+ if ((file = usdt_dof_file_init(provider, size)) == NULL)
198
+ return (-1);
199
+
200
+ if ((usdt_dof_proffs_sect(&sects[2], provider, file->dof)) < 0)
201
+ return (-1);
202
+ if ((usdt_dof_prenoffs_sect(&sects[3], provider, file->dof)) < 0)
203
+ return (-1);
204
+ if ((usdt_dof_provider_sect(&sects[4], provider)) < 0)
205
+ return (-1);
206
+
207
+ for (i = 0; i < 5; i++)
208
+ usdt_dof_file_append_section(file, &sects[i]);
209
+
210
+ usdt_dof_file_generate(file, &strtab);
211
+
212
+ usdt_dof_section_free(&strtab);
213
+ for (i = 0; i < 5; i++)
214
+ usdt_dof_section_free(&sects[i]);
215
+
216
+ if ((usdt_dof_file_load(file, provider->module)) < 0) {
217
+ usdt_error(provider, USDT_ERROR_LOADDOF, strerror(errno));
218
+ return (-1);
219
+ }
220
+
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
+
242
+ return (0);
243
+ }
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
+
260
+ int
261
+ usdt_is_enabled(usdt_probe_t *probe)
262
+ {
263
+ if (probe != NULL)
264
+ return (*probe->isenabled_addr)();
265
+ else
266
+ return 0;
267
+ }
268
+
269
+ void
270
+ usdt_fire_probe(usdt_probe_t *probe, size_t argc, void **nargv)
271
+ {
272
+ if (probe != NULL)
273
+ usdt_probe_args(probe->probe_addr, argc, nargv);
274
+ }
275
+
276
+ static void
277
+ usdt_verror(usdt_provider_t *provider, usdt_error_t error, va_list argp)
278
+ {
279
+ vasprintf(&provider->error, usdt_errors[error], argp);
280
+ }
281
+
282
+ void
283
+ usdt_error(usdt_provider_t *provider, usdt_error_t error, ...)
284
+ {
285
+ va_list argp;
286
+
287
+ va_start(argp, error);
288
+ usdt_verror(provider, error, argp);
289
+ va_end(argp);
290
+ }
291
+
292
+ char *
293
+ usdt_errstr(usdt_provider_t *provider)
294
+ {
295
+ return (provider->error);
296
+ }
@@ -0,0 +1,66 @@
1
+ /*
2
+ * Copyright (c) 2012, Chris Andrews. All rights reserved.
3
+ */
4
+
5
+ #include <stdint.h>
6
+ #include <unistd.h>
7
+
8
+ typedef uint8_t usdt_argtype_t;
9
+ #define USDT_ARGTYPE_NONE 0
10
+ #define USDT_ARGTYPE_STRING 1
11
+ #define USDT_ARGTYPE_INTEGER 2
12
+
13
+ #define USDT_ARG_MAX 32
14
+
15
+ typedef enum usdt_error {
16
+ USDT_ERROR_MALLOC = 0,
17
+ USDT_ERROR_VALLOC,
18
+ USDT_ERROR_NOPROBES,
19
+ USDT_ERROR_LOADDOF,
20
+ USDT_ERROR_ALREADYENABLED,
21
+ USDT_ERROR_UNLOADDOF,
22
+ USDT_ERROR_DUP_PROBE,
23
+ USDT_ERROR_REMOVE_PROBE
24
+ } usdt_error_t;
25
+
26
+ typedef struct usdt_probe {
27
+ int (*isenabled_addr)(void);
28
+ void *probe_addr;
29
+ } usdt_probe_t;
30
+
31
+ int usdt_is_enabled(usdt_probe_t *probe);
32
+ void usdt_fire_probe(usdt_probe_t *probe, size_t argc, void **argv);
33
+
34
+ typedef struct usdt_probedef {
35
+ const char *name;
36
+ const char *function;
37
+ size_t argc;
38
+ usdt_argtype_t types[USDT_ARG_MAX];
39
+ struct usdt_probe *probe;
40
+ struct usdt_probedef *next;
41
+ int refcnt;
42
+ } usdt_probedef_t;
43
+
44
+ usdt_probedef_t *usdt_create_probe(const char *func, const char *name,
45
+ size_t argc, const char **types);
46
+ void usdt_probe_release(usdt_probedef_t *probedef);
47
+
48
+ typedef struct usdt_provider {
49
+ const char *name;
50
+ const char *module;
51
+ usdt_probedef_t *probedefs;
52
+ char *error;
53
+ int enabled;
54
+ void *file;
55
+ } usdt_provider_t;
56
+
57
+ usdt_provider_t *usdt_create_provider(const char *name, const char *module);
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);
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);
63
+
64
+ void usdt_error(usdt_provider_t *provider, usdt_error_t error, ...);
65
+ char *usdt_errstr(usdt_provider_t *provider);
66
+