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