root/trunk/umem_fail.c

Revision 2, 3.4 kB (checked in by wez, 9 years ago)

Initial revision

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