| /* |
| * CDDL HEADER START |
| * |
| * The contents of this file are subject to the terms of the |
| * Common Development and Distribution License, Version 1.0 only |
| * (the "License"). You may not use this file except in compliance |
| * with the License. |
| * |
| * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
| * or http://www.opensolaris.org/os/licensing. |
| * See the License for the specific language governing permissions |
| * and limitations under the License. |
| * |
| * When distributing Covered Code, include this CDDL HEADER in each |
| * file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
| * If applicable, add the following below this CDDL HEADER, with the |
| * fields enclosed by brackets "[]" replaced with your own identifying |
| * information: Portions Copyright [yyyy] [name of copyright owner] |
| * |
| * CDDL HEADER END |
| */ |
| /* |
| * Copyright (c) 1994, by Sun Microsytems, Inc. |
| */ |
| |
| #pragma ident "%Z%%M% %I% %E% SMI" |
| |
| /* |
| * Includes |
| */ |
| |
| #ifndef DEBUG |
| #define NDEBUG 1 |
| #endif |
| |
| #include <assert.h> |
| #include <limits.h> |
| #include <values.h> |
| #include <stdio.h> |
| #include <string.h> |
| #include <unistd.h> |
| |
| #include <tnf/probe.h> |
| #include "tnf_trace.h" |
| #include "tnf_args.h" |
| |
| /* |
| * tnf_probe_debug() - a debug final function |
| */ |
| |
| #define BUF_LIMIT 1024 |
| #define NAME_LIMIT 32 |
| #define ATTR_LIMIT 128 |
| |
| /* |
| * code coverage comment out |
| * #pragma covcc !instr |
| */ |
| |
| void |
| tnf_probe_debug(tnf_probe_setup_t *set_p) |
| { |
| char tmp_buf[BUF_LIMIT]; |
| char *buf_p; |
| tnf_probe_control_t *probe_p; |
| const char *attr_start, *name_start, *name_end; |
| ulong_t attr_len; |
| int num_args, i, str_len, name_len; |
| void *arg_position; |
| tnf_arg_kind_t arg_type; |
| void *buffer; |
| |
| buf_p = tmp_buf; |
| probe_p = set_p->probe_p; |
| buffer = set_p->buffer_p; |
| |
| /* get the name of the probe */ |
| attr_start = tnf_probe_get_value(probe_p, "name", &attr_len); |
| assert(attr_start); |
| attr_len = (attr_len > (NAME_LIMIT - 1)) ? (NAME_LIMIT - 1) : attr_len; |
| str_len = sprintf(buf_p, "probe %.*s; ", attr_len, attr_start); |
| buf_p += str_len; |
| |
| /* get the sunw%debug attribute */ |
| attr_start = tnf_probe_get_value(probe_p, "sunw%debug", &attr_len); |
| if (attr_start) { |
| attr_len = (attr_len > (ATTR_LIMIT - 1)) ? |
| (ATTR_LIMIT - 1) : attr_len; |
| str_len = sprintf(buf_p, "sunw%%debug \"%.*s\"; ", |
| attr_len, attr_start); |
| buf_p += str_len; |
| } |
| |
| /* number of args ? we are done if there are only standard args */ |
| num_args = tnf_probe_get_num_args(probe_p); |
| if (num_args <= 2) { |
| (void) sprintf(buf_p, "\n"); |
| (void) write(STDERR_FILENO, tmp_buf, strlen(tmp_buf)); |
| return; |
| } |
| |
| /* get the slot names */ |
| name_start = tnf_probe_get_value(probe_p, "slots", &attr_len); |
| assert(name_start); |
| |
| num_args = tnf_probe_get_num_args(probe_p); |
| if (num_args <= 2) |
| return; |
| /* print each of the arguments to the probe */ |
| for (i = 2; i < num_args; i++) { |
| /* find slot names - number of spaces is equal to number of args */ |
| name_end = strchr(name_start, VAL_SEPARATOR); |
| /* LINTED - result is <= string length */ |
| name_len = name_end - name_start; |
| name_len = (name_len > (NAME_LIMIT - 1)) ? |
| (NAME_LIMIT - 1) : name_len; |
| str_len = sprintf(buf_p, "%.*s=", name_len, name_start); |
| buf_p += str_len; |
| name_start = name_end + 1; |
| |
| arg_position = tnf_probe_get_arg_indexed(probe_p, i, buffer); |
| arg_type = tnf_probe_get_type_indexed(probe_p, i); |
| |
| switch (arg_type) { |
| case TNF_UNKNOWN: |
| str_len = sprintf(buf_p, "<unknown>; "); |
| buf_p += str_len; |
| break; |
| case TNF_INT32: |
| str_len = sprintf(buf_p, "%ld; ", |
| tnf_probe_get_int(arg_position)); |
| buf_p += str_len; |
| break; |
| case TNF_UINT32: |
| str_len = sprintf(buf_p, "%lu; ", |
| tnf_probe_get_uint(arg_position)); |
| buf_p += str_len; |
| break; |
| case TNF_INT64: |
| /* LINTED malformed format string */ |
| str_len = sprintf(buf_p, "%lld; ", |
| tnf_probe_get_longlong(arg_position)); |
| buf_p += str_len; |
| break; |
| case TNF_UINT64: |
| /* LINTED malformed format string */ |
| str_len = sprintf(buf_p, "%llu; ", |
| tnf_probe_get_ulonglong(arg_position)); |
| buf_p += str_len; |
| break; |
| case TNF_FLOAT32: |
| str_len = sprintf(buf_p, "%f; ", |
| tnf_probe_get_float(arg_position)); |
| buf_p += str_len; |
| break; |
| case TNF_FLOAT64: |
| str_len = sprintf(buf_p, "%f; ", |
| tnf_probe_get_double(arg_position)); |
| buf_p += str_len; |
| break; |
| case TNF_STRING: |
| attr_start = tnf_probe_get_chars(arg_position); |
| attr_len = strlen(attr_start); |
| attr_len = (attr_len > (ATTR_LIMIT - 1)) ? (ATTR_LIMIT - 1) : |
| attr_len; |
| str_len = sprintf(buf_p, "\"%.*s\"; ", attr_len, attr_start); |
| buf_p += str_len; |
| break; |
| case TNF_ARRAY: |
| /* no break */ |
| case TNF_STRUCT: |
| /* no break */ |
| case TNF_OPAQUE: |
| str_len = sprintf(buf_p, "0x%lx; ", |
| tnf_probe_get_ulong(arg_position)); |
| buf_p += str_len; |
| break; |
| default: |
| str_len = sprintf(buf_p, "<error>; "); |
| buf_p += str_len; |
| break; |
| } |
| } |
| |
| (void) sprintf(buf_p, "\n"); |
| (void) write(STDERR_FILENO, tmp_buf, strlen(tmp_buf)); |
| |
| return; |
| |
| } /* end tnf_probe_debug */ |
| |
| |
| /* |
| * code coverage comment out |
| * #pragma covcc instr |
| */ |
| |
| #ifdef TESTING |
| /* |
| * tnf_probe_empty() - an empty final function |
| */ |
| |
| /*ARGSUSED0*/ |
| void |
| tnf_probe_empty(tnf_probe_setup_t *set_p) |
| { |
| |
| return; |
| |
| } /* end tnf_probe_empty */ |
| #endif |