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
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.
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]
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 * Portions Copyright 2006 OmniTI, Inc.
30 /* #pragma ident "@(#)misc.c 1.6 05/06/08 SMI" */
32 #define _BUILDING_UMEM_MISC_C
34 /* #include "mtlib.h" */
46 #if HAVE_SYS_MACHELF_H
47 #include <sys/machelf.h>
50 #include <umem_impl.h>
57 #define UMEM_ERRFD 2 /* goes to standard error */
58 #define UMEM_MAX_ERROR_SIZE 4096 /* error messages are truncated to this */
61 * This is a circular buffer for holding error messages.
62 * umem_error_enter appends to the buffer, adding "..." to the beginning
63 * if data has been lost.
66 #define ERR_SIZE 8192 /* must be a power of 2 */
68 static mutex_t umem_error_lock = DEFAULTMUTEX;
70 static char umem_error_buffer[ERR_SIZE] = "";
71 static uint_t umem_error_begin = 0;
72 static uint_t umem_error_end = 0;
74 #define WRITE_AND_INC(var, value) { \
75 umem_error_buffer[(var)++] = (value); \
76 var = P2PHASE((var), ERR_SIZE); \
80 umem_log_enter(const char *error_str, int serious)
87 mem_printf(serious ? DCRITICAL : DINFO, "umem: %s", error_str);
90 (void) mutex_lock(&umem_error_lock);
92 while ((c = *error_str++) != '\0') {
93 WRITE_AND_INC(umem_error_end, c);
94 if (umem_error_end == umem_error_begin)
98 umem_error_buffer[umem_error_end] = 0;
102 umem_error_begin = P2PHASE(umem_error_end + 1, ERR_SIZE);
104 idx = umem_error_begin;
105 WRITE_AND_INC(idx, '.');
106 WRITE_AND_INC(idx, '.');
107 WRITE_AND_INC(idx, '.');
110 (void) mutex_unlock(&umem_error_lock);
114 umem_error_enter(const char *error_str)
116 #ifndef UMEM_STANDALONE
117 if (umem_output && !issetugid())
118 (void) write(UMEM_ERRFD, error_str, strlen(error_str));
121 umem_log_enter(error_str, 1);
132 if (i & 0xffffffff00000000ul) {
136 if (i & 0xffff0000) {
162 if (!(i & 0xffffffff)) {
185 hrt2ts(hrtime_t hrt, timestruc_t *tsp)
187 tsp->tv_sec = hrt / NANOSEC;
188 tsp->tv_nsec = hrt % NANOSEC;
192 log_message(const char *format, ...)
194 char buf[UMEM_MAX_ERROR_SIZE] = "";
198 va_start(va, format);
199 (void) vsnprintf(buf, UMEM_MAX_ERROR_SIZE-1, format, va);
202 #ifndef UMEM_STANDALONE
204 (void) write(UMEM_ERRFD, buf, strlen(buf));
207 umem_log_enter(buf, 0);
210 #ifndef UMEM_STANDALONE
212 debug_printf(const char *format, ...)
214 char buf[UMEM_MAX_ERROR_SIZE] = "";
218 va_start(va, format);
219 (void) vsnprintf(buf, UMEM_MAX_ERROR_SIZE-1, format, va);
222 (void) write(UMEM_ERRFD, buf, strlen(buf));
227 umem_vprintf(const char *format, va_list va)
229 char buf[UMEM_MAX_ERROR_SIZE] = "";
231 (void) vsnprintf(buf, UMEM_MAX_ERROR_SIZE-1, format, va);
233 umem_error_enter(buf);
237 umem_printf(const char *format, ...)
241 va_start(va, format);
242 umem_vprintf(format, va);
248 umem_printf_warn(void *ignored, const char *format, ...)
252 va_start(va, format);
253 umem_vprintf(format, va);
258 * print_sym tries to print out the symbol and offset of a pointer
261 print_sym(void *pointer)
263 #if HAVE_SYS_MACHELF_H
267 uintptr_t end = NULL;
269 Sym *ext_info = NULL;
271 result = dladdr1(pointer, &sym_info, (void **)&ext_info,
277 end = (uintptr_t)sym_info.dli_saddr + ext_info->st_size;
279 endpath = strrchr(sym_info.dli_fname, '/');
283 endpath = sym_info.dli_fname;
284 umem_printf("%s'", endpath);
287 if (result == 0 || (uintptr_t)pointer > end) {
288 umem_printf("?? (0x%p)", pointer);
291 umem_printf("%s+0x%p", sym_info.dli_sname,
292 (char *)pointer - (char *)sym_info.dli_saddr);