ruby-static-tracing 0.0.12 → 0.0.13

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