root/trunk/umem_fail.c

Revision 6, 3.4 kB (checked in by richdawe, 8 years ago)

Build a basic shared library on Linux; may not work!

  • Property svn:eol-style set to native
Line 
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 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 /*
27  * Portions Copyright 2006 OmniTI, Inc.
28  */
29
30 /* #pragma ident        "@(#)umem_fail.c        1.4     05/06/08 SMI" */
31
32 /*
33  * Failure routines for libumem (not standalone)
34  */
35
36 #include "config.h"
37 #include <sys/types.h>
38 #include <signal.h>
39 #include <stdarg.h>
40 #include <string.h>
41 #include <stdio.h>
42
43 #include "misc.h"
44 /*#include "util.h"*/
45
46 static volatile int umem_exiting = 0;
47 #define UMEM_EXIT_ABORT 1
48
49 static mutex_t umem_exit_lock = DEFAULTMUTEX; /* protects umem_exiting */
50
51 static int
52 firstexit(int type)
53 {
54         if (umem_exiting)
55                 return (0);
56
57         (void) mutex_lock(&umem_exit_lock);
58         if (umem_exiting) {
59                 (void) mutex_unlock(&umem_exit_lock);
60                 return (0);
61         }
62         umem_exiting = type;
63         (void) mutex_unlock(&umem_exit_lock);
64
65         return (1);
66 }
67
68 /*
69  * We can't use abort(3C), since it closes all of the standard library
70  * FILEs, which can call free().
71  *
72  * In addition, we can't just raise(SIGABRT), since the current handler
73  * might do allocation.  We give them once chance, though.
74  */
75 static void __NORETURN
76 umem_do_abort(void)
77 {
78 #ifdef _WIN32
79         abort();
80 #else
81         if (firstexit(UMEM_EXIT_ABORT)) {
82                 (void) raise(SIGABRT);
83         }
84
85         for (;;) {
86                 (void) signal(SIGABRT, SIG_DFL);
87                 (void) sigrelse(SIGABRT);
88                 (void) raise(SIGABRT);
89         }
90 #endif
91 }
92
93 #define SKIP_FRAMES             1       /* skip the panic frame */
94 #define ERR_STACK_FRAMES        128
95
96 static void
97 print_stacktrace(void)
98 {
99         uintptr_t cur_stack[ERR_STACK_FRAMES];
100
101         /*
102          * if we are in a signal context, checking for it will recurse
103          */
104         uint_t nframes = getpcstack(cur_stack, ERR_STACK_FRAMES, 0);
105         uint_t idx;
106
107         if (nframes > SKIP_FRAMES) {
108                 umem_printf("stack trace:\n");
109
110                 for (idx = SKIP_FRAMES; idx < nframes; idx++) {
111                         (void) print_sym((void *)cur_stack[idx]);
112                         umem_printf("\n");
113                 }
114         }
115 }
116
117 void
118 umem_panic(const char *format, ...)
119 {
120         va_list va;
121
122         va_start(va, format);
123         umem_vprintf(format, va);
124         va_end(va);
125
126         if (format[strlen(format)-1] != '\n')
127                 umem_error_enter("\n");
128
129         va_start(va, format);
130         /*ec_debug_vprintf(DCRITICAL, DMEM, format, va);*/
131         fvprintf(stderr, format, va);
132         va_end(va);
133        
134         print_stacktrace();
135
136         umem_do_abort();
137 }
138
139 void
140 umem_err_recoverable(const char *format, ...)
141 {
142         va_list va;
143
144         va_start(va, format);
145         umem_vprintf(format, va);
146         va_end(va);
147
148         if (format[strlen(format)-1] != '\n')
149                 umem_error_enter("\n");
150
151         print_stacktrace();
152
153         if (umem_abort > 0)
154                 umem_do_abort();
155 }
156
157 int
158 __umem_assert_failed(const char *assertion, const char *file, int line)
159 {
160         umem_panic("Assertion failed: %s, file %s, line %d\n",
161             assertion, file, line);
162         umem_do_abort();
163         /*NOTREACHED*/
164         return (0);
165 }
Note: See TracBrowser for help on using the browser.