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 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 205 tnf_probe_empty(tnf_probe_setup_t *set_p) 206 { 207 208 return; 209 210 } /* end tnf_probe_empty */ 211 #endif 212