1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright (c) 1994, by Sun Microsytems, Inc.
24 */
25
26 #pragma ident "%Z%%M% %I% %E% SMI"
27
28 /*
29 * Includes
30 */
31
32 #ifndef DEBUG
33 #define NDEBUG 1
34 #endif
35
36 #include <assert.h>
37 #include <limits.h>
38 #include <values.h>
39 #include <stdio.h>
40 #include <string.h>
41 #include <unistd.h>
42
43 #include <tnf/probe.h>
44 #include "tnf_trace.h"
45 #include "tnf_args.h"
46
47 /*
48 * tnf_probe_debug() - a debug final function
49 */
50
51 #define BUF_LIMIT 1024
52 #define NAME_LIMIT 32
53 #define ATTR_LIMIT 128
54
55 /*
56 * code coverage comment out
57 * #pragma covcc !instr
58 */
59
60 void
tnf_probe_debug(tnf_probe_setup_t * set_p)61 tnf_probe_debug(tnf_probe_setup_t *set_p)
62 {
63 char tmp_buf[BUF_LIMIT];
64 char *buf_p;
65 tnf_probe_control_t *probe_p;
66 const char *attr_start, *name_start, *name_end;
67 ulong_t attr_len;
68 int num_args, i, str_len, name_len;
69 void *arg_position;
70 tnf_arg_kind_t arg_type;
71 void *buffer;
72
73 buf_p = tmp_buf;
74 probe_p = set_p->probe_p;
75 buffer = set_p->buffer_p;
76
77 /* get the name of the probe */
78 attr_start = tnf_probe_get_value(probe_p, "name", &attr_len);
79 assert(attr_start);
80 attr_len = (attr_len > (NAME_LIMIT - 1)) ? (NAME_LIMIT - 1) : attr_len;
81 str_len = sprintf(buf_p, "probe %.*s; ", attr_len, attr_start);
82 buf_p += str_len;
83
84 /* get the sunw%debug attribute */
85 attr_start = tnf_probe_get_value(probe_p, "sunw%debug", &attr_len);
86 if (attr_start) {
87 attr_len = (attr_len > (ATTR_LIMIT - 1)) ?
88 (ATTR_LIMIT - 1) : attr_len;
89 str_len = sprintf(buf_p, "sunw%%debug \"%.*s\"; ",
90 attr_len, attr_start);
91 buf_p += str_len;
92 }
93
94 /* number of args ? we are done if there are only standard args */
95 num_args = tnf_probe_get_num_args(probe_p);
96 if (num_args <= 2) {
97 (void) sprintf(buf_p, "\n");
98 (void) write(STDERR_FILENO, tmp_buf, strlen(tmp_buf));
99 return;
100 }
101
102 /* get the slot names */
103 name_start = tnf_probe_get_value(probe_p, "slots", &attr_len);
104 assert(name_start);
105
106 num_args = tnf_probe_get_num_args(probe_p);
107 if (num_args <= 2)
108 return;
109 /* print each of the arguments to the probe */
110 for (i = 2; i < num_args; i++) {
111 /* find slot names - number of spaces is equal to number of args */
112 name_end = strchr(name_start, VAL_SEPARATOR);
113 /* LINTED - result is <= string length */
114 name_len = name_end - name_start;
115 name_len = (name_len > (NAME_LIMIT - 1)) ?
116 (NAME_LIMIT - 1) : name_len;
117 str_len = sprintf(buf_p, "%.*s=", name_len, name_start);
118 buf_p += str_len;
119 name_start = name_end + 1;
120
121 arg_position = tnf_probe_get_arg_indexed(probe_p, i, buffer);
122 arg_type = tnf_probe_get_type_indexed(probe_p, i);
123
124 switch (arg_type) {
125 case TNF_UNKNOWN:
126 str_len = sprintf(buf_p, "<unknown>; ");
127 buf_p += str_len;
128 break;
129 case TNF_INT32:
130 str_len = sprintf(buf_p, "%ld; ",
131 tnf_probe_get_int(arg_position));
132 buf_p += str_len;
133 break;
134 case TNF_UINT32:
135 str_len = sprintf(buf_p, "%lu; ",
136 tnf_probe_get_uint(arg_position));
137 buf_p += str_len;
138 break;
139 case TNF_INT64:
140 /* LINTED malformed format string */
141 str_len = sprintf(buf_p, "%lld; ",
142 tnf_probe_get_longlong(arg_position));
143 buf_p += str_len;
144 break;
145 case TNF_UINT64:
146 /* LINTED malformed format string */
147 str_len = sprintf(buf_p, "%llu; ",
148 tnf_probe_get_ulonglong(arg_position));
149 buf_p += str_len;
150 break;
151 case TNF_FLOAT32:
152 str_len = sprintf(buf_p, "%f; ",
153 tnf_probe_get_float(arg_position));
154 buf_p += str_len;
155 break;
156 case TNF_FLOAT64:
157 str_len = sprintf(buf_p, "%f; ",
158 tnf_probe_get_double(arg_position));
159 buf_p += str_len;
160 break;
161 case TNF_STRING:
162 attr_start = tnf_probe_get_chars(arg_position);
163 attr_len = strlen(attr_start);
164 attr_len = (attr_len > (ATTR_LIMIT - 1)) ? (ATTR_LIMIT - 1) :
165 attr_len;
166 str_len = sprintf(buf_p, "\"%.*s\"; ", attr_len, attr_start);
167 buf_p += str_len;
168 break;
169 case TNF_ARRAY:
170 /* no break */
171 case TNF_STRUCT:
172 /* no break */
173 case TNF_OPAQUE:
174 str_len = sprintf(buf_p, "0x%lx; ",
175 tnf_probe_get_ulong(arg_position));
176 buf_p += str_len;
177 break;
178 default:
179 str_len = sprintf(buf_p, "<error>; ");
180 buf_p += str_len;
181 break;
182 }
183 }
184
185 (void) sprintf(buf_p, "\n");
186 (void) write(STDERR_FILENO, tmp_buf, strlen(tmp_buf));
187
188 return;
189
190 } /* end tnf_probe_debug */
191
192
193 /*
194 * code coverage comment out
195 * #pragma covcc instr
196 */
197
198 #ifdef TESTING
199 /*
200 * tnf_probe_empty() - an empty final function
201 */
202
203 /*ARGSUSED0*/
204 void
tnf_probe_empty(tnf_probe_setup_t * set_p)205 tnf_probe_empty(tnf_probe_setup_t *set_p)
206 {
207
208 return;
209
210 } /* end tnf_probe_empty */
211 #endif
212