ruby-static-tracing 0.0.12 → 0.0.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/ext/ruby-static-tracing/lib/deps-extconf.rb +1 -1
  3. data/ext/ruby-static-tracing/lib/libstapsdt/Makefile +76 -0
  4. data/ext/ruby-static-tracing/lib/libstapsdt/example/demo.c +42 -0
  5. data/ext/ruby-static-tracing/lib/libstapsdt/src/asm/libstapsdt-x86_64.s +14 -0
  6. data/ext/ruby-static-tracing/lib/libstapsdt/src/dynamic-symbols.c +41 -0
  7. data/ext/ruby-static-tracing/lib/libstapsdt/src/dynamic-symbols.h +34 -0
  8. data/ext/ruby-static-tracing/lib/libstapsdt/src/errors.c +30 -0
  9. data/ext/ruby-static-tracing/lib/libstapsdt/src/errors.h +8 -0
  10. data/ext/ruby-static-tracing/lib/libstapsdt/src/hash-table.c +27 -0
  11. data/ext/ruby-static-tracing/lib/libstapsdt/src/hash-table.h +3 -0
  12. data/ext/ruby-static-tracing/lib/libstapsdt/src/libstapsdt.c +258 -0
  13. data/ext/ruby-static-tracing/lib/libstapsdt/src/libstapsdt.h +67 -0
  14. data/ext/ruby-static-tracing/lib/libstapsdt/src/sdtnote.c +176 -0
  15. data/ext/ruby-static-tracing/lib/libstapsdt/src/sdtnote.h +46 -0
  16. data/ext/ruby-static-tracing/lib/libstapsdt/src/section.c +30 -0
  17. data/ext/ruby-static-tracing/lib/libstapsdt/src/section.h +21 -0
  18. data/ext/ruby-static-tracing/lib/libstapsdt/src/shared-lib.c +563 -0
  19. data/ext/ruby-static-tracing/lib/libstapsdt/src/shared-lib.h +46 -0
  20. data/ext/ruby-static-tracing/lib/libstapsdt/src/string-table.c +67 -0
  21. data/ext/ruby-static-tracing/lib/libstapsdt/src/string-table.h +28 -0
  22. data/ext/ruby-static-tracing/lib/libstapsdt/src/util.c +12 -0
  23. data/ext/ruby-static-tracing/lib/libstapsdt/src/util.h +6 -0
  24. data/ext/ruby-static-tracing/lib/libstapsdt/tests/test-errors.c +77 -0
  25. data/ext/ruby-static-tracing/lib/libstapsdt/tests/test-memory-leaks.c +25 -0
  26. data/ext/ruby-static-tracing/lib/libusdt/Makefile +168 -0
  27. data/ext/ruby-static-tracing/lib/libusdt/test_mem_usage.c +77 -0
  28. data/ext/ruby-static-tracing/lib/libusdt/test_usdt.c +87 -0
  29. data/ext/ruby-static-tracing/lib/libusdt/usdt.c +321 -0
  30. data/ext/ruby-static-tracing/lib/libusdt/usdt.h +65 -0
  31. data/ext/ruby-static-tracing/lib/libusdt/usdt_dof.c +126 -0
  32. data/ext/ruby-static-tracing/lib/libusdt/usdt_dof_file.c +290 -0
  33. data/ext/ruby-static-tracing/lib/libusdt/usdt_dof_sections.c +180 -0
  34. data/ext/ruby-static-tracing/lib/libusdt/usdt_internal.h +107 -0
  35. data/ext/ruby-static-tracing/lib/libusdt/usdt_probe.c +133 -0
  36. data/ext/ruby-static-tracing/lib/libusdt/usdt_tracepoints_i386.s +69 -0
  37. data/ext/ruby-static-tracing/lib/libusdt/usdt_tracepoints_x86_64.s +123 -0
  38. data/lib/ruby-static-tracing/version.rb +1 -1
  39. metadata +38 -2
@@ -0,0 +1,126 @@
1
+ /*
2
+ * Copyright (c) 2012, Chris Andrews. All rights reserved.
3
+ */
4
+
5
+ #include "usdt_internal.h"
6
+
7
+ int
8
+ usdt_dof_section_add_data(usdt_dof_section_t *section, void *data, size_t length)
9
+ {
10
+ int newlen = section->size + length;
11
+
12
+ if ((section->data = realloc((char *)section->data, newlen)) == NULL)
13
+ return (-1);
14
+
15
+ memcpy(section->data + section->size, data, length);
16
+ section->size = newlen;
17
+ return (0);
18
+ }
19
+
20
+ size_t
21
+ usdt_provider_dof_size(usdt_provider_t *provider, usdt_strtab_t *strtab)
22
+ {
23
+ uint8_t i, j;
24
+ int args = 0;
25
+ int probes = 0;
26
+ size_t size = 0;
27
+ usdt_probedef_t *pd;
28
+ size_t sections[8];
29
+
30
+ for (pd = provider->probedefs; pd != NULL; pd = pd->next) {
31
+ args += pd->argc;
32
+ probes++;
33
+ }
34
+
35
+ sections[0] = sizeof(dof_hdr_t);
36
+ sections[1] = sizeof(dof_sec_t) * 6;
37
+ sections[2] = strtab->size;
38
+ sections[3] = sizeof(dof_probe_t) * probes;
39
+ sections[4] = sizeof(uint8_t) * args;
40
+ sections[5] = sizeof(uint32_t) * probes;
41
+ sections[6] = sizeof(uint32_t) * probes;
42
+ sections[7] = sizeof(dof_provider_t);
43
+
44
+ for (i = 0; i < 8; i++) {
45
+ size += sections[i];
46
+ j = size % 8;
47
+ if (j > 0)
48
+ size += (8 - j);
49
+ }
50
+
51
+ return size;
52
+ }
53
+
54
+ int
55
+ usdt_dof_section_init(usdt_dof_section_t *section, uint32_t type, dof_secidx_t index)
56
+ {
57
+ section->type = type;
58
+ section->index = index;
59
+ section->flags = DOF_SECF_LOAD;
60
+ section->offset = 0;
61
+ section->size = 0;
62
+ section->entsize = 0;
63
+ section->pad = 0;
64
+ section->next = NULL;
65
+
66
+ if ((section->data = malloc(1)) == NULL)
67
+ return (-1);
68
+
69
+ switch(type) {
70
+ case DOF_SECT_PROBES: section->align = 8; break;
71
+ case DOF_SECT_PRARGS: section->align = 1; break;
72
+ case DOF_SECT_PROFFS: section->align = 4; break;
73
+ case DOF_SECT_PRENOFFS: section->align = 4; break;
74
+ case DOF_SECT_PROVIDER: section->align = 4; break;
75
+ }
76
+
77
+ return (0);
78
+ }
79
+
80
+ void
81
+ usdt_dof_section_free(usdt_dof_section_t *section)
82
+ {
83
+ free(section->data);
84
+ }
85
+
86
+ int
87
+ usdt_strtab_init(usdt_strtab_t *strtab, dof_secidx_t index)
88
+ {
89
+ strtab->type = DOF_SECT_STRTAB;;
90
+ strtab->index = index;
91
+ strtab->flags = DOF_SECF_LOAD;
92
+ strtab->offset = 0;
93
+ strtab->size = 0;
94
+ strtab->entsize = 0;
95
+ strtab->pad = 0;
96
+ strtab->data = NULL;
97
+ strtab->align = 1;
98
+ strtab->strindex = 1;
99
+
100
+ if ((strtab->data = (char *) malloc(1)) == NULL)
101
+ return (-1);
102
+
103
+ *strtab->data = '\0';
104
+
105
+ return (0);
106
+ }
107
+
108
+ dof_stridx_t
109
+ usdt_strtab_add(usdt_strtab_t *strtab, const char *string)
110
+ {
111
+ size_t length;
112
+ int index;
113
+
114
+ length = strlen(string);
115
+ index = strtab->strindex;
116
+ strtab->strindex += (length + 1);
117
+
118
+ if ((strtab->data = realloc(strtab->data, strtab->strindex)) == NULL)
119
+ return (0);
120
+
121
+ memcpy((char *) (strtab->data + index), (char *)string, length + 1);
122
+ strtab->size = index + length + 1;
123
+
124
+ return (index);
125
+ }
126
+
@@ -0,0 +1,290 @@
1
+ /*
2
+ * Copyright (c) 2012, Chris Andrews. All rights reserved.
3
+ */
4
+
5
+ #include "usdt_internal.h"
6
+
7
+ #include <sys/ioctl.h>
8
+
9
+ static uint8_t
10
+ dof_version(uint8_t header_version)
11
+ {
12
+ uint8_t dof_version;
13
+ /* DOF versioning: Apple always needs version 3, but Solaris can use
14
+ 1 or 2 depending on whether is-enabled probes are needed. */
15
+ #ifdef __APPLE__
16
+ dof_version = DOF_VERSION_3;
17
+ #else
18
+ switch(header_version) {
19
+ case 1:
20
+ dof_version = DOF_VERSION_1;
21
+ break;
22
+ case 2:
23
+ dof_version = DOF_VERSION_2;
24
+ break;
25
+ default:
26
+ dof_version = DOF_VERSION;
27
+ }
28
+ #endif
29
+ return dof_version;
30
+ }
31
+
32
+ #ifdef __APPLE__
33
+ static const char *helper = "/dev/dtracehelper";
34
+
35
+ static int
36
+ load_dof(int fd, dof_helper_t *dh)
37
+ {
38
+ int ret;
39
+ uint8_t buffer[sizeof(dof_ioctl_data_t) + sizeof(dof_helper_t)];
40
+ dof_ioctl_data_t* ioctlData = (dof_ioctl_data_t*)buffer;
41
+ user_addr_t val;
42
+
43
+ ioctlData->dofiod_count = 1;
44
+ memcpy(&ioctlData->dofiod_helpers[0], dh, sizeof(dof_helper_t));
45
+
46
+ val = (user_addr_t)(unsigned long)ioctlData;
47
+ ret = ioctl(fd, DTRACEHIOC_ADDDOF, &val);
48
+
49
+ if (ret < 0)
50
+ return ret;
51
+
52
+ return (int)(ioctlData->dofiod_helpers[0].dofhp_dof);
53
+ }
54
+
55
+ #else /* Solaris and FreeBSD */
56
+
57
+ /* ignore Sol10 GA ... */
58
+ static const char *helper = "/dev/dtrace/helper";
59
+
60
+ static int
61
+ load_dof(int fd, dof_helper_t *dh)
62
+ {
63
+ int ret;
64
+
65
+ ret = ioctl(fd, DTRACEHIOC_ADDDOF, dh);
66
+ #if defined(__FreeBSD__) && __FreeBSD__ <= 10
67
+ if (ret != -1)
68
+ ret = dh ->gen;
69
+ #endif
70
+ return ret;
71
+ }
72
+
73
+ #endif
74
+
75
+ static void
76
+ pad_section(usdt_dof_section_t *sec)
77
+ {
78
+ size_t i, pad;
79
+
80
+ if (sec->align > 1) {
81
+ i = sec->offset % sec->align;
82
+ if (i > 0) {
83
+ pad = sec->align - i;
84
+ sec->offset = (pad + sec->offset);
85
+ sec->pad = pad;
86
+ }
87
+ }
88
+ }
89
+
90
+ static void
91
+ dof_header(dof_hdr_t *header)
92
+ {
93
+ int i;
94
+
95
+ header->dofh_ident[DOF_ID_MAG0] = DOF_MAG_MAG0;
96
+ header->dofh_ident[DOF_ID_MAG1] = DOF_MAG_MAG1;
97
+ header->dofh_ident[DOF_ID_MAG2] = DOF_MAG_MAG2;
98
+ header->dofh_ident[DOF_ID_MAG3] = DOF_MAG_MAG3;
99
+
100
+ header->dofh_ident[DOF_ID_MODEL] = DOF_MODEL_NATIVE;
101
+ header->dofh_ident[DOF_ID_ENCODING] = DOF_ENCODE_NATIVE;
102
+ header->dofh_ident[DOF_ID_VERSION] = dof_version(2);
103
+ header->dofh_ident[DOF_ID_DIFVERS] = DIF_VERSION;
104
+ header->dofh_ident[DOF_ID_DIFIREG] = DIF_DIR_NREGS;
105
+ header->dofh_ident[DOF_ID_DIFTREG] = DIF_DTR_NREGS;
106
+
107
+ for (i = DOF_ID_PAD; i < DOF_ID_SIZE; i++)
108
+ header->dofh_ident[i] = 0;
109
+
110
+ header->dofh_flags = 0;
111
+
112
+ header->dofh_hdrsize = sizeof(dof_hdr_t);
113
+ header->dofh_secsize = sizeof(dof_sec_t);
114
+ header->dofh_secoff = sizeof(dof_hdr_t);
115
+
116
+ header->dofh_loadsz = 0;
117
+ header->dofh_filesz = 0;
118
+ header->dofh_pad = 0;
119
+ }
120
+
121
+ static size_t
122
+ add_header(usdt_dof_file_t *file, size_t offset, usdt_dof_section_t *section)
123
+ {
124
+ dof_sec_t header;
125
+
126
+ header.dofs_flags = section->flags;
127
+ header.dofs_type = section->type;
128
+ header.dofs_offset = section->offset;
129
+ header.dofs_size = section->size;
130
+ header.dofs_entsize = section->entsize;
131
+ header.dofs_align = section->align;
132
+
133
+ memcpy((file->dof + offset), &header, sizeof(dof_sec_t));
134
+ return (offset + sizeof(dof_sec_t));
135
+ }
136
+
137
+ static size_t
138
+ add_section(usdt_dof_file_t *file, size_t offset, usdt_dof_section_t *section)
139
+ {
140
+ if (section->pad > 0) {
141
+ /* maximum padding required is 7 */
142
+ memcpy((file->dof + offset), "\0\0\0\0\0\0\0", section->pad);
143
+ offset += section->pad;
144
+ }
145
+
146
+ memcpy((file->dof + offset), section->data, section->size);
147
+ return (offset + section->size);
148
+ }
149
+
150
+ int
151
+ usdt_dof_file_unload(usdt_dof_file_t *file)
152
+ {
153
+ int fd, ret;
154
+
155
+ if ((fd = open(helper, O_RDWR)) < 0)
156
+ return (-1);
157
+
158
+ #ifdef __FreeBSD__
159
+ ret = ioctl(fd, DTRACEHIOC_REMOVE, &file->gen);
160
+ #else
161
+ ret = ioctl(fd, DTRACEHIOC_REMOVE, file->gen);
162
+ #endif
163
+
164
+ if (ret < 0)
165
+ return (-1);
166
+
167
+ if ((close(fd)) < 0)
168
+ return (-1);
169
+
170
+ return (0);
171
+ }
172
+
173
+ int
174
+ usdt_dof_file_load(usdt_dof_file_t *file, const char *module)
175
+ {
176
+ dof_helper_t dh;
177
+ dof_hdr_t *dof;
178
+ int fd;
179
+
180
+ dof = (dof_hdr_t *) file->dof;
181
+
182
+ dh.dofhp_dof = (uintptr_t)dof;
183
+ dh.dofhp_addr = (uintptr_t)dof;
184
+ #if __FreeBSD__ >= 11
185
+ dh.dofhp_pid = getpid();
186
+ #endif
187
+ (void) strncpy(dh.dofhp_mod, module, sizeof (dh.dofhp_mod));
188
+
189
+ if ((fd = open(helper, O_RDWR)) < 0)
190
+ return (-1);
191
+
192
+ file->gen = load_dof(fd, &dh);
193
+
194
+ if ((close(fd)) < 0)
195
+ return (-1);
196
+
197
+ if (file->gen < 0)
198
+ return (-1);
199
+
200
+ return (0);
201
+ }
202
+
203
+ void
204
+ usdt_dof_file_append_section(usdt_dof_file_t *file, usdt_dof_section_t *section)
205
+ {
206
+ usdt_dof_section_t *s;
207
+
208
+ if (file->sections == NULL) {
209
+ file->sections = section;
210
+ }
211
+ else {
212
+ for (s = file->sections; (s->next != NULL); s = s->next) ;
213
+ s->next = section;
214
+ }
215
+ }
216
+
217
+ void
218
+ usdt_dof_file_generate(usdt_dof_file_t *file, usdt_strtab_t *strtab)
219
+ {
220
+ dof_hdr_t header;
221
+ uint64_t filesz;
222
+ uint64_t loadsz;
223
+ usdt_dof_section_t *sec;
224
+ size_t offset;
225
+
226
+ dof_header(&header);
227
+ header.dofh_secnum = 6;
228
+
229
+ filesz = sizeof(dof_hdr_t) + (sizeof(dof_sec_t) * header.dofh_secnum);
230
+ loadsz = filesz;
231
+
232
+ strtab->offset = filesz;
233
+ pad_section((usdt_dof_section_t *)strtab);
234
+ filesz += strtab->size + strtab->pad;
235
+
236
+ if (strtab->flags & 1)
237
+ loadsz += strtab->size + strtab->pad;
238
+
239
+ for (sec = file->sections; sec != NULL; sec = sec->next) {
240
+ sec->offset = filesz;
241
+ pad_section(sec);
242
+ filesz += sec->size + sec->pad;
243
+ if (sec->flags & 1)
244
+ loadsz += sec->size + sec->pad;
245
+ }
246
+
247
+ header.dofh_loadsz = loadsz;
248
+ header.dofh_filesz = filesz;
249
+ memcpy(file->dof, &header, sizeof(dof_hdr_t));
250
+
251
+ offset = sizeof(dof_hdr_t);
252
+
253
+ offset = add_header(file, offset, (usdt_dof_section_t *)strtab);
254
+
255
+ for (sec = file->sections; sec != NULL; sec = sec->next)
256
+ offset = add_header(file, offset, sec);
257
+
258
+ offset = add_section(file, offset, (usdt_dof_section_t *)strtab);
259
+
260
+ for (sec = file->sections; sec != NULL; sec = sec->next)
261
+ offset = add_section(file, offset, sec);
262
+ }
263
+
264
+ usdt_dof_file_t *
265
+ usdt_dof_file_init(usdt_provider_t *provider, size_t size)
266
+ {
267
+ usdt_dof_file_t *file;
268
+
269
+ if ((file = malloc(sizeof(*file))) == NULL) {
270
+ usdt_error(provider, USDT_ERROR_MALLOC);
271
+ return (NULL);
272
+ }
273
+
274
+ if ((file->dof = valloc(size)) == NULL) {
275
+ usdt_error(provider, USDT_ERROR_VALLOC);
276
+ return (NULL);
277
+ }
278
+
279
+ file->sections = NULL;
280
+ file->size = size;
281
+
282
+ return (file);
283
+ }
284
+
285
+ void
286
+ usdt_dof_file_free(usdt_dof_file_t *file)
287
+ {
288
+ free(file->dof);
289
+ free(file);
290
+ }
@@ -0,0 +1,180 @@
1
+ /*
2
+ * Copyright (c) 2012, Chris Andrews. All rights reserved.
3
+ */
4
+
5
+ #include "usdt_internal.h"
6
+
7
+ int
8
+ usdt_dof_probes_sect(usdt_dof_section_t *probes,
9
+ usdt_provider_t *provider, usdt_strtab_t *strtab)
10
+ {
11
+ usdt_probedef_t *pd;
12
+ dof_probe_t p;
13
+ dof_stridx_t type, argv;
14
+ uint8_t argc, i;
15
+ uint32_t argidx = 0;
16
+ uint32_t offidx = 0;
17
+
18
+ usdt_dof_section_init(probes, DOF_SECT_PROBES, 1);
19
+
20
+ for (pd = provider->probedefs; pd != NULL; pd = pd->next) {
21
+ argc = 0;
22
+ argv = 0;
23
+ type = 0;
24
+
25
+ for (i = 0; i < pd->argc; i++) {
26
+ type = usdt_strtab_add(strtab, pd->types[i]);
27
+ argc++;
28
+ if (argv == 0)
29
+ argv = type;
30
+ }
31
+
32
+ if (usdt_create_tracepoints(pd->probe) < 0) {
33
+ usdt_error(provider, USDT_ERROR_VALLOC);
34
+ return (-1);
35
+ }
36
+
37
+ #ifdef __x86_64__
38
+ p.dofpr_addr = (uint64_t) pd->probe->isenabled_addr;
39
+ #elif __i386__ || __i386
40
+ p.dofpr_addr = (uint32_t) pd->probe->isenabled_addr;
41
+ #else
42
+ #error "only x86_64 and i386 supported"
43
+ #endif
44
+ p.dofpr_func = usdt_strtab_add(strtab, pd->function);
45
+ p.dofpr_name = usdt_strtab_add(strtab, pd->name);
46
+ p.dofpr_nargv = argv;
47
+ p.dofpr_xargv = argv;
48
+ p.dofpr_argidx = argidx;
49
+ p.dofpr_offidx = offidx;
50
+ p.dofpr_nargc = argc;
51
+ p.dofpr_xargc = argc;
52
+ p.dofpr_noffs = 1;
53
+ p.dofpr_enoffidx = offidx;
54
+ p.dofpr_nenoffs = 1;
55
+ p.dofpr_pad1 = 0;
56
+ p.dofpr_pad2 = 0;
57
+
58
+ usdt_dof_section_add_data(probes, &p, sizeof(dof_probe_t));
59
+ probes->entsize = sizeof(dof_probe_t);
60
+
61
+ argidx += argc;
62
+ offidx++;
63
+ }
64
+
65
+ return (0);
66
+ }
67
+
68
+ int
69
+ usdt_dof_prargs_sect(usdt_dof_section_t *prargs, usdt_provider_t *provider)
70
+ {
71
+ usdt_probedef_t *pd;
72
+ uint8_t i;
73
+
74
+ usdt_dof_section_init(prargs, DOF_SECT_PRARGS, 2);
75
+ prargs->entsize = 1;
76
+
77
+ for (pd = provider->probedefs; pd != NULL; pd = pd->next) {
78
+ for (i = 0; i < pd->argc; i++)
79
+ usdt_dof_section_add_data(prargs, &i, 1);
80
+ }
81
+ if (prargs->size == 0) {
82
+ i = 0;
83
+ if (usdt_dof_section_add_data(prargs, &i, 1) < 0) {
84
+ usdt_error(provider, USDT_ERROR_MALLOC);
85
+ return (-1);
86
+ }
87
+ }
88
+
89
+ return (0);
90
+ }
91
+
92
+ int
93
+ usdt_dof_proffs_sect(usdt_dof_section_t *proffs,
94
+ usdt_provider_t *provider, char *dof)
95
+ {
96
+ usdt_probedef_t *pd;
97
+ uint32_t off;
98
+
99
+ usdt_dof_section_init(proffs, DOF_SECT_PROFFS, 3);
100
+ proffs->entsize = 4;
101
+
102
+ for (pd = provider->probedefs; pd != NULL; pd = pd->next) {
103
+ off = usdt_probe_offset(pd->probe, dof, pd->argc);
104
+ if (usdt_dof_section_add_data(proffs, &off, 4) < 0) {
105
+ usdt_error(provider, USDT_ERROR_MALLOC);
106
+ return (-1);
107
+ }
108
+ }
109
+
110
+ return (0);
111
+ }
112
+
113
+ int
114
+ usdt_dof_prenoffs_sect(usdt_dof_section_t *prenoffs,
115
+ usdt_provider_t *provider, char *dof)
116
+ {
117
+ usdt_probedef_t *pd;
118
+ uint32_t off;
119
+
120
+ usdt_dof_section_init(prenoffs, DOF_SECT_PRENOFFS, 4);
121
+ prenoffs->entsize = 4;
122
+
123
+ for (pd = provider->probedefs; pd != NULL; pd = pd->next) {
124
+ off = usdt_is_enabled_offset(pd->probe, dof);
125
+ if (usdt_dof_section_add_data(prenoffs, &off, 4) < 0) {
126
+ usdt_error(provider, USDT_ERROR_MALLOC);
127
+ return (-1);
128
+ }
129
+ }
130
+
131
+ return (0);
132
+ }
133
+
134
+ int
135
+ usdt_dof_provider_sect(usdt_dof_section_t *provider_s, usdt_provider_t *provider)
136
+ {
137
+ dof_provider_t p;
138
+
139
+ usdt_dof_section_init(provider_s, DOF_SECT_PROVIDER, 5);
140
+
141
+ p.dofpv_strtab = 0;
142
+ p.dofpv_probes = 1;
143
+ p.dofpv_prargs = 2;
144
+ p.dofpv_proffs = 3;
145
+ p.dofpv_prenoffs = 4;
146
+ p.dofpv_name = 1; /* provider name always first strtab entry. */
147
+
148
+ /*
149
+ * Stability is something of a hack. Everything is marked *
150
+ * "stable" here to permit use of the "args" array, which is *
151
+ * needed to access arguments past "arg9".
152
+ *
153
+ * It should be up to the creator of the provider to decide
154
+ * this, though, and it should be possible to set the
155
+ * appropriate stability at creation time.
156
+ */
157
+
158
+ p.dofpv_provattr = DOF_ATTR(DTRACE_STABILITY_STABLE,
159
+ DTRACE_STABILITY_STABLE,
160
+ DTRACE_STABILITY_STABLE);
161
+ p.dofpv_modattr = DOF_ATTR(DTRACE_STABILITY_STABLE,
162
+ DTRACE_STABILITY_STABLE,
163
+ DTRACE_STABILITY_STABLE);
164
+ p.dofpv_funcattr = DOF_ATTR(DTRACE_STABILITY_STABLE,
165
+ DTRACE_STABILITY_STABLE,
166
+ DTRACE_STABILITY_STABLE);
167
+ p.dofpv_nameattr = DOF_ATTR(DTRACE_STABILITY_STABLE,
168
+ DTRACE_STABILITY_STABLE,
169
+ DTRACE_STABILITY_STABLE);
170
+ p.dofpv_argsattr = DOF_ATTR(DTRACE_STABILITY_STABLE,
171
+ DTRACE_STABILITY_STABLE,
172
+ DTRACE_STABILITY_STABLE);
173
+
174
+ if ((usdt_dof_section_add_data(provider_s, &p, sizeof(p))) < 0) {
175
+ usdt_error(provider, USDT_ERROR_MALLOC);
176
+ return (-1);
177
+ }
178
+
179
+ return (0);
180
+ }