author | Christopher Siden <chris.siden@delphix.com> |
Mon, 21 May 2012 12:11:39 -0700 | |
changeset 13700 | 2889e2596bd6 |
parent 11913 | 283e725df792 |
child 13764 | 38b4aca480b3 |
permissions | -rw-r--r-- |
0 | 1 |
/* |
2 |
* CDDL HEADER START |
|
3 |
* |
|
4 |
* The contents of this file are subject to the terms of the |
|
2248
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
5 |
* Common Development and Distribution License (the "License"). |
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
6 |
* You may not use this file except in compliance with the License. |
0 | 7 |
* |
8 |
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
|
9 |
* or http://www.opensolaris.org/os/licensing. |
|
10 |
* See the License for the specific language governing permissions |
|
11 |
* and limitations under the License. |
|
12 |
* |
|
13 |
* When distributing Covered Code, include this CDDL HEADER in each |
|
14 |
* file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
|
15 |
* If applicable, add the following below this CDDL HEADER, with the |
|
16 |
* fields enclosed by brackets "[]" replaced with your own identifying |
|
17 |
* information: Portions Copyright [yyyy] [name of copyright owner] |
|
18 |
* |
|
19 |
* CDDL HEADER END |
|
20 |
*/ |
|
2248
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
21 |
|
0 | 22 |
/* |
11913
283e725df792
PSARC 2010/062 increase number of realtime signals
Roger A. Faulkner <Roger.Faulkner@Sun.COM>
parents:
10629
diff
changeset
|
23 |
* Copyright 2010 Sun Microsystems, Inc. All rights reserved. |
0 | 24 |
* Use is subject to license terms. |
25 |
*/ |
|
13700
2889e2596bd6
2619 asynchronous destruction of ZFS file systems
Christopher Siden <chris.siden@delphix.com>
parents:
11913
diff
changeset
|
26 |
/* |
2889e2596bd6
2619 asynchronous destruction of ZFS file systems
Christopher Siden <chris.siden@delphix.com>
parents:
11913
diff
changeset
|
27 |
* Copyright (c) 2012 by Delphix. All rights reserved. |
2889e2596bd6
2619 asynchronous destruction of ZFS file systems
Christopher Siden <chris.siden@delphix.com>
parents:
11913
diff
changeset
|
28 |
*/ |
0 | 29 |
|
30 |
#include "lint.h" |
|
31 |
#include "thr_uberdata.h" |
|
32 |
||
33 |
const char *panicstr; |
|
34 |
ulwp_t *panic_thread; |
|
35 |
||
36 |
static mutex_t assert_lock = DEFAULTMUTEX; |
|
37 |
static ulwp_t *assert_thread = NULL; |
|
38 |
||
39 |
/* |
|
40 |
* Called from __assert() to set panicstr and panic_thread. |
|
41 |
*/ |
|
42 |
void |
|
43 |
__set_panicstr(const char *msg) |
|
44 |
{ |
|
45 |
panicstr = msg; |
|
46 |
panic_thread = __curthread(); |
|
47 |
} |
|
48 |
||
49 |
/* |
|
50 |
* Called from exit() (atexit function) to give precedence |
|
51 |
* to assertion failures and a core dump over _exit(). |
|
52 |
*/ |
|
53 |
void |
|
54 |
grab_assert_lock() |
|
55 |
{ |
|
6515
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5891
diff
changeset
|
56 |
(void) _lwp_mutex_lock(&assert_lock); |
0 | 57 |
} |
58 |
||
59 |
static void |
|
60 |
Abort(const char *msg) |
|
61 |
{ |
|
62 |
ulwp_t *self; |
|
63 |
struct sigaction act; |
|
64 |
sigset_t sigmask; |
|
65 |
lwpid_t lwpid; |
|
66 |
||
67 |
/* to help with core file debugging */ |
|
68 |
panicstr = msg; |
|
69 |
if ((self = __curthread()) != NULL) { |
|
70 |
panic_thread = self; |
|
71 |
lwpid = self->ul_lwpid; |
|
72 |
} else { |
|
6812 | 73 |
lwpid = _lwp_self(); |
0 | 74 |
} |
75 |
||
76 |
/* set SIGABRT signal handler to SIG_DFL w/o grabbing any locks */ |
|
6515
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5891
diff
changeset
|
77 |
(void) memset(&act, 0, sizeof (act)); |
0 | 78 |
act.sa_sigaction = SIG_DFL; |
79 |
(void) __sigaction(SIGABRT, &act, NULL); |
|
80 |
||
81 |
/* delete SIGABRT from the signal mask */ |
|
6515
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5891
diff
changeset
|
82 |
(void) sigemptyset(&sigmask); |
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5891
diff
changeset
|
83 |
(void) sigaddset(&sigmask, SIGABRT); |
11913
283e725df792
PSARC 2010/062 increase number of realtime signals
Roger A. Faulkner <Roger.Faulkner@Sun.COM>
parents:
10629
diff
changeset
|
84 |
(void) __lwp_sigmask(SIG_UNBLOCK, &sigmask); |
0 | 85 |
|
6812 | 86 |
(void) _lwp_kill(lwpid, SIGABRT); /* never returns */ |
87 |
(void) kill(getpid(), SIGABRT); /* if it does, try harder */ |
|
0 | 88 |
_exit(127); |
89 |
} |
|
90 |
||
91 |
/* |
|
92 |
* Write a panic message w/o grabbing any locks other than assert_lock. |
|
93 |
* We have no idea what locks are held at this point. |
|
94 |
*/ |
|
2248
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
95 |
static void |
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
96 |
common_panic(const char *head, const char *why) |
0 | 97 |
{ |
98 |
char msg[400]; /* no panic() message in the library is this long */ |
|
99 |
ulwp_t *self; |
|
100 |
size_t len1, len2; |
|
101 |
||
102 |
if ((self = __curthread()) != NULL) |
|
103 |
enter_critical(self); |
|
6515
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5891
diff
changeset
|
104 |
(void) _lwp_mutex_lock(&assert_lock); |
0 | 105 |
|
6515
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5891
diff
changeset
|
106 |
(void) memset(msg, 0, sizeof (msg)); |
2248
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
107 |
(void) strcpy(msg, head); |
0 | 108 |
len1 = strlen(msg); |
109 |
len2 = strlen(why); |
|
110 |
if (len1 + len2 >= sizeof (msg)) |
|
111 |
len2 = sizeof (msg) - len1 - 1; |
|
112 |
(void) strncat(msg, why, len2); |
|
113 |
len1 = strlen(msg); |
|
114 |
if (msg[len1 - 1] != '\n') |
|
115 |
msg[len1++] = '\n'; |
|
5891 | 116 |
(void) __write(2, msg, len1); |
0 | 117 |
Abort(msg); |
118 |
} |
|
119 |
||
2248
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
120 |
void |
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
121 |
thr_panic(const char *why) |
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
122 |
{ |
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
123 |
common_panic("*** libc thread failure: ", why); |
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
124 |
} |
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
125 |
|
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
126 |
void |
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
127 |
aio_panic(const char *why) |
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
128 |
{ |
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
129 |
common_panic("*** libc aio system failure: ", why); |
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
130 |
} |
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
131 |
|
0 | 132 |
/* |
133 |
* Utility function for converting a long integer to a string, avoiding stdio. |
|
134 |
* 'base' must be one of 10 or 16 |
|
135 |
*/ |
|
136 |
void |
|
137 |
ultos(uint64_t n, int base, char *s) |
|
138 |
{ |
|
139 |
char lbuf[24]; /* 64 bits fits in 16 hex digits, 20 decimal */ |
|
140 |
char *cp = lbuf; |
|
141 |
||
142 |
do { |
|
143 |
*cp++ = "0123456789abcdef"[n%base]; |
|
144 |
n /= base; |
|
145 |
} while (n); |
|
146 |
if (base == 16) { |
|
147 |
*s++ = '0'; |
|
148 |
*s++ = 'x'; |
|
149 |
} |
|
150 |
do { |
|
151 |
*s++ = *--cp; |
|
152 |
} while (cp > lbuf); |
|
153 |
*s = '\0'; |
|
154 |
} |
|
155 |
||
156 |
/* |
|
157 |
* Report application lock usage error for mutexes and condvars. |
|
158 |
* Not called if _THREAD_ERROR_DETECTION=0. |
|
159 |
* Continue execution if _THREAD_ERROR_DETECTION=1. |
|
160 |
* Dump core if _THREAD_ERROR_DETECTION=2. |
|
161 |
*/ |
|
162 |
void |
|
163 |
lock_error(const mutex_t *mp, const char *who, void *cv, const char *msg) |
|
164 |
{ |
|
10629
12b43beac546
6883880 non-8-byte-aligned mutexes: update needed for solaris_nevada
Roger A. Faulkner <Roger.Faulkner@Sun.COM>
parents:
6812
diff
changeset
|
165 |
mutex_t mcopy; |
0 | 166 |
char buf[800]; |
167 |
uberdata_t *udp; |
|
168 |
ulwp_t *self; |
|
169 |
lwpid_t lwpid; |
|
170 |
pid_t pid; |
|
171 |
||
10629
12b43beac546
6883880 non-8-byte-aligned mutexes: update needed for solaris_nevada
Roger A. Faulkner <Roger.Faulkner@Sun.COM>
parents:
6812
diff
changeset
|
172 |
/* |
12b43beac546
6883880 non-8-byte-aligned mutexes: update needed for solaris_nevada
Roger A. Faulkner <Roger.Faulkner@Sun.COM>
parents:
6812
diff
changeset
|
173 |
* Take a snapshot of the mutex before it changes (we hope!). |
12b43beac546
6883880 non-8-byte-aligned mutexes: update needed for solaris_nevada
Roger A. Faulkner <Roger.Faulkner@Sun.COM>
parents:
6812
diff
changeset
|
174 |
* Use memcpy() rather than 'mcopy = *mp' in case mp is unaligned. |
12b43beac546
6883880 non-8-byte-aligned mutexes: update needed for solaris_nevada
Roger A. Faulkner <Roger.Faulkner@Sun.COM>
parents:
6812
diff
changeset
|
175 |
*/ |
12b43beac546
6883880 non-8-byte-aligned mutexes: update needed for solaris_nevada
Roger A. Faulkner <Roger.Faulkner@Sun.COM>
parents:
6812
diff
changeset
|
176 |
(void) memcpy(&mcopy, mp, sizeof (mcopy)); |
12b43beac546
6883880 non-8-byte-aligned mutexes: update needed for solaris_nevada
Roger A. Faulkner <Roger.Faulkner@Sun.COM>
parents:
6812
diff
changeset
|
177 |
|
0 | 178 |
/* avoid recursion deadlock */ |
179 |
if ((self = __curthread()) != NULL) { |
|
180 |
if (assert_thread == self) |
|
181 |
_exit(127); |
|
182 |
enter_critical(self); |
|
6515
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5891
diff
changeset
|
183 |
(void) _lwp_mutex_lock(&assert_lock); |
0 | 184 |
assert_thread = self; |
185 |
lwpid = self->ul_lwpid; |
|
186 |
udp = self->ul_uberdata; |
|
187 |
pid = udp->pid; |
|
188 |
} else { |
|
189 |
self = NULL; |
|
6515
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5891
diff
changeset
|
190 |
(void) _lwp_mutex_lock(&assert_lock); |
6812 | 191 |
lwpid = _lwp_self(); |
0 | 192 |
udp = &__uberdata; |
6515
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5891
diff
changeset
|
193 |
pid = getpid(); |
0 | 194 |
} |
195 |
||
196 |
(void) strcpy(buf, |
|
197 |
"\n*** _THREAD_ERROR_DETECTION: lock usage error detected ***\n"); |
|
198 |
(void) strcat(buf, who); |
|
199 |
(void) strcat(buf, "("); |
|
200 |
if (cv != NULL) { |
|
201 |
ultos((uint64_t)(uintptr_t)cv, 16, buf + strlen(buf)); |
|
202 |
(void) strcat(buf, ", "); |
|
203 |
} |
|
204 |
ultos((uint64_t)(uintptr_t)mp, 16, buf + strlen(buf)); |
|
205 |
(void) strcat(buf, ")"); |
|
206 |
if (msg != NULL) { |
|
207 |
(void) strcat(buf, ": "); |
|
208 |
(void) strcat(buf, msg); |
|
6812 | 209 |
} else if (!mutex_held(&mcopy)) { |
0 | 210 |
(void) strcat(buf, ": calling thread does not own the lock"); |
211 |
} else if (mcopy.mutex_rcount) { |
|
212 |
(void) strcat(buf, ": mutex rcount = "); |
|
213 |
ultos((uint64_t)mcopy.mutex_rcount, 10, buf + strlen(buf)); |
|
214 |
} else { |
|
215 |
(void) strcat(buf, ": calling thread already owns the lock"); |
|
216 |
} |
|
217 |
(void) strcat(buf, "\ncalling thread is "); |
|
218 |
ultos((uint64_t)(uintptr_t)self, 16, buf + strlen(buf)); |
|
219 |
(void) strcat(buf, " thread-id "); |
|
220 |
ultos((uint64_t)lwpid, 10, buf + strlen(buf)); |
|
6812 | 221 |
if (msg != NULL || mutex_held(&mcopy)) |
0 | 222 |
/* EMPTY */; |
223 |
else if (mcopy.mutex_lockw == 0) |
|
224 |
(void) strcat(buf, "\nthe lock is unowned"); |
|
4574 | 225 |
else if (!(mcopy.mutex_type & USYNC_PROCESS)) { |
0 | 226 |
(void) strcat(buf, "\nthe lock owner is "); |
227 |
ultos((uint64_t)mcopy.mutex_owner, 16, buf + strlen(buf)); |
|
228 |
} else { |
|
229 |
(void) strcat(buf, " in process "); |
|
230 |
ultos((uint64_t)pid, 10, buf + strlen(buf)); |
|
231 |
(void) strcat(buf, "\nthe lock owner is "); |
|
232 |
ultos((uint64_t)mcopy.mutex_owner, 16, buf + strlen(buf)); |
|
233 |
(void) strcat(buf, " in process "); |
|
234 |
ultos((uint64_t)mcopy.mutex_ownerpid, 10, buf + strlen(buf)); |
|
235 |
} |
|
236 |
(void) strcat(buf, "\n\n"); |
|
5891 | 237 |
(void) __write(2, buf, strlen(buf)); |
0 | 238 |
if (udp->uberflags.uf_thread_error_detection >= 2) |
239 |
Abort(buf); |
|
240 |
assert_thread = NULL; |
|
6515
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5891
diff
changeset
|
241 |
(void) _lwp_mutex_unlock(&assert_lock); |
0 | 242 |
if (self != NULL) |
243 |
exit_critical(self); |
|
244 |
} |
|
245 |
||
246 |
/* |
|
247 |
* Report application lock usage error for rwlocks. |
|
248 |
* Not called if _THREAD_ERROR_DETECTION=0. |
|
249 |
* Continue execution if _THREAD_ERROR_DETECTION=1. |
|
250 |
* Dump core if _THREAD_ERROR_DETECTION=2. |
|
251 |
*/ |
|
252 |
void |
|
253 |
rwlock_error(const rwlock_t *rp, const char *who, const char *msg) |
|
254 |
{ |
|
10629
12b43beac546
6883880 non-8-byte-aligned mutexes: update needed for solaris_nevada
Roger A. Faulkner <Roger.Faulkner@Sun.COM>
parents:
6812
diff
changeset
|
255 |
rwlock_t rcopy; |
4570
f93b74ddbdd5
6559990 user-level read/write locks should be much faster
raf
parents:
2248
diff
changeset
|
256 |
uint32_t rwstate; |
0 | 257 |
char buf[800]; |
258 |
uberdata_t *udp; |
|
259 |
ulwp_t *self; |
|
260 |
lwpid_t lwpid; |
|
261 |
pid_t pid; |
|
4570
f93b74ddbdd5
6559990 user-level read/write locks should be much faster
raf
parents:
2248
diff
changeset
|
262 |
int process; |
0 | 263 |
|
10629
12b43beac546
6883880 non-8-byte-aligned mutexes: update needed for solaris_nevada
Roger A. Faulkner <Roger.Faulkner@Sun.COM>
parents:
6812
diff
changeset
|
264 |
/* |
12b43beac546
6883880 non-8-byte-aligned mutexes: update needed for solaris_nevada
Roger A. Faulkner <Roger.Faulkner@Sun.COM>
parents:
6812
diff
changeset
|
265 |
* Take a snapshot of the rwlock before it changes (we hope!). |
12b43beac546
6883880 non-8-byte-aligned mutexes: update needed for solaris_nevada
Roger A. Faulkner <Roger.Faulkner@Sun.COM>
parents:
6812
diff
changeset
|
266 |
* Use memcpy() rather than 'rcopy = *rp' in case rp is unaligned. |
12b43beac546
6883880 non-8-byte-aligned mutexes: update needed for solaris_nevada
Roger A. Faulkner <Roger.Faulkner@Sun.COM>
parents:
6812
diff
changeset
|
267 |
*/ |
12b43beac546
6883880 non-8-byte-aligned mutexes: update needed for solaris_nevada
Roger A. Faulkner <Roger.Faulkner@Sun.COM>
parents:
6812
diff
changeset
|
268 |
(void) memcpy(&rcopy, rp, sizeof (rcopy)); |
12b43beac546
6883880 non-8-byte-aligned mutexes: update needed for solaris_nevada
Roger A. Faulkner <Roger.Faulkner@Sun.COM>
parents:
6812
diff
changeset
|
269 |
|
0 | 270 |
/* avoid recursion deadlock */ |
271 |
if ((self = __curthread()) != NULL) { |
|
272 |
if (assert_thread == self) |
|
273 |
_exit(127); |
|
274 |
enter_critical(self); |
|
6515
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5891
diff
changeset
|
275 |
(void) _lwp_mutex_lock(&assert_lock); |
0 | 276 |
assert_thread = self; |
277 |
lwpid = self->ul_lwpid; |
|
278 |
udp = self->ul_uberdata; |
|
279 |
pid = udp->pid; |
|
280 |
} else { |
|
281 |
self = NULL; |
|
6515
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5891
diff
changeset
|
282 |
(void) _lwp_mutex_lock(&assert_lock); |
6812 | 283 |
lwpid = _lwp_self(); |
0 | 284 |
udp = &__uberdata; |
6515
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5891
diff
changeset
|
285 |
pid = getpid(); |
0 | 286 |
} |
287 |
||
4570
f93b74ddbdd5
6559990 user-level read/write locks should be much faster
raf
parents:
2248
diff
changeset
|
288 |
rwstate = (uint32_t)rcopy.rwlock_readers; |
f93b74ddbdd5
6559990 user-level read/write locks should be much faster
raf
parents:
2248
diff
changeset
|
289 |
process = (rcopy.rwlock_type & USYNC_PROCESS); |
f93b74ddbdd5
6559990 user-level read/write locks should be much faster
raf
parents:
2248
diff
changeset
|
290 |
|
0 | 291 |
(void) strcpy(buf, |
292 |
"\n*** _THREAD_ERROR_DETECTION: lock usage error detected ***\n"); |
|
293 |
(void) strcat(buf, who); |
|
294 |
(void) strcat(buf, "("); |
|
295 |
ultos((uint64_t)(uintptr_t)rp, 16, buf + strlen(buf)); |
|
296 |
(void) strcat(buf, "): "); |
|
297 |
(void) strcat(buf, msg); |
|
298 |
(void) strcat(buf, "\ncalling thread is "); |
|
299 |
ultos((uint64_t)(uintptr_t)self, 16, buf + strlen(buf)); |
|
300 |
(void) strcat(buf, " thread-id "); |
|
301 |
ultos((uint64_t)lwpid, 10, buf + strlen(buf)); |
|
4570
f93b74ddbdd5
6559990 user-level read/write locks should be much faster
raf
parents:
2248
diff
changeset
|
302 |
if (process) { |
0 | 303 |
(void) strcat(buf, " in process "); |
304 |
ultos((uint64_t)pid, 10, buf + strlen(buf)); |
|
4570
f93b74ddbdd5
6559990 user-level read/write locks should be much faster
raf
parents:
2248
diff
changeset
|
305 |
} |
f93b74ddbdd5
6559990 user-level read/write locks should be much faster
raf
parents:
2248
diff
changeset
|
306 |
if (rwstate & URW_WRITE_LOCKED) { |
f93b74ddbdd5
6559990 user-level read/write locks should be much faster
raf
parents:
2248
diff
changeset
|
307 |
(void) strcat(buf, "\nthe writer lock owner is "); |
f93b74ddbdd5
6559990 user-level read/write locks should be much faster
raf
parents:
2248
diff
changeset
|
308 |
ultos((uint64_t)rcopy.rwlock_owner, 16, |
f93b74ddbdd5
6559990 user-level read/write locks should be much faster
raf
parents:
2248
diff
changeset
|
309 |
buf + strlen(buf)); |
f93b74ddbdd5
6559990 user-level read/write locks should be much faster
raf
parents:
2248
diff
changeset
|
310 |
if (process) { |
0 | 311 |
(void) strcat(buf, " in process "); |
312 |
ultos((uint64_t)rcopy.rwlock_ownerpid, 10, |
|
313 |
buf + strlen(buf)); |
|
314 |
} |
|
4570
f93b74ddbdd5
6559990 user-level read/write locks should be much faster
raf
parents:
2248
diff
changeset
|
315 |
} else if (rwstate & URW_READERS_MASK) { |
f93b74ddbdd5
6559990 user-level read/write locks should be much faster
raf
parents:
2248
diff
changeset
|
316 |
(void) strcat(buf, "\nthe reader lock is held by "); |
f93b74ddbdd5
6559990 user-level read/write locks should be much faster
raf
parents:
2248
diff
changeset
|
317 |
ultos((uint64_t)(rwstate & URW_READERS_MASK), 10, |
f93b74ddbdd5
6559990 user-level read/write locks should be much faster
raf
parents:
2248
diff
changeset
|
318 |
buf + strlen(buf)); |
f93b74ddbdd5
6559990 user-level read/write locks should be much faster
raf
parents:
2248
diff
changeset
|
319 |
(void) strcat(buf, " readers"); |
0 | 320 |
} else { |
321 |
(void) strcat(buf, "\nthe lock is unowned"); |
|
322 |
} |
|
4570
f93b74ddbdd5
6559990 user-level read/write locks should be much faster
raf
parents:
2248
diff
changeset
|
323 |
if (rwstate & URW_HAS_WAITERS) |
f93b74ddbdd5
6559990 user-level read/write locks should be much faster
raf
parents:
2248
diff
changeset
|
324 |
(void) strcat(buf, "\nand the lock appears to have waiters"); |
0 | 325 |
(void) strcat(buf, "\n\n"); |
5891 | 326 |
(void) __write(2, buf, strlen(buf)); |
0 | 327 |
if (udp->uberflags.uf_thread_error_detection >= 2) |
328 |
Abort(buf); |
|
329 |
assert_thread = NULL; |
|
6515
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5891
diff
changeset
|
330 |
(void) _lwp_mutex_unlock(&assert_lock); |
0 | 331 |
if (self != NULL) |
332 |
exit_critical(self); |
|
333 |
} |
|
334 |
||
335 |
/* |
|
336 |
* Report a thread usage error. |
|
337 |
* Not called if _THREAD_ERROR_DETECTION=0. |
|
338 |
* Writes message and continues execution if _THREAD_ERROR_DETECTION=1. |
|
339 |
* Writes message and dumps core if _THREAD_ERROR_DETECTION=2. |
|
340 |
*/ |
|
341 |
void |
|
342 |
thread_error(const char *msg) |
|
343 |
{ |
|
344 |
char buf[800]; |
|
345 |
uberdata_t *udp; |
|
346 |
ulwp_t *self; |
|
347 |
lwpid_t lwpid; |
|
348 |
||
349 |
/* avoid recursion deadlock */ |
|
350 |
if ((self = __curthread()) != NULL) { |
|
351 |
if (assert_thread == self) |
|
352 |
_exit(127); |
|
353 |
enter_critical(self); |
|
6515
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5891
diff
changeset
|
354 |
(void) _lwp_mutex_lock(&assert_lock); |
0 | 355 |
assert_thread = self; |
356 |
lwpid = self->ul_lwpid; |
|
357 |
udp = self->ul_uberdata; |
|
358 |
} else { |
|
359 |
self = NULL; |
|
6515
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5891
diff
changeset
|
360 |
(void) _lwp_mutex_lock(&assert_lock); |
6812 | 361 |
lwpid = _lwp_self(); |
0 | 362 |
udp = &__uberdata; |
363 |
} |
|
364 |
||
365 |
(void) strcpy(buf, "\n*** _THREAD_ERROR_DETECTION: " |
|
5891 | 366 |
"thread usage error detected ***\n*** "); |
0 | 367 |
(void) strcat(buf, msg); |
368 |
||
369 |
(void) strcat(buf, "\n*** calling thread is "); |
|
370 |
ultos((uint64_t)(uintptr_t)self, 16, buf + strlen(buf)); |
|
371 |
(void) strcat(buf, " thread-id "); |
|
372 |
ultos((uint64_t)lwpid, 10, buf + strlen(buf)); |
|
373 |
(void) strcat(buf, "\n\n"); |
|
5891 | 374 |
(void) __write(2, buf, strlen(buf)); |
0 | 375 |
if (udp->uberflags.uf_thread_error_detection >= 2) |
376 |
Abort(buf); |
|
377 |
assert_thread = NULL; |
|
6515
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5891
diff
changeset
|
378 |
(void) _lwp_mutex_unlock(&assert_lock); |
0 | 379 |
if (self != NULL) |
380 |
exit_critical(self); |
|
381 |
} |
|
382 |
||
383 |
/* |
|
384 |
* We use __assfail() because the libc __assert() calls |
|
385 |
* gettext() which calls malloc() which grabs a mutex. |
|
386 |
* We do everything without calling standard i/o. |
|
2248
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
387 |
* assfail() and _assfail() are exported functions; |
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
388 |
* __assfail() is private to libc. |
0 | 389 |
*/ |
390 |
#pragma weak _assfail = __assfail |
|
391 |
void |
|
392 |
__assfail(const char *assertion, const char *filename, int line_num) |
|
393 |
{ |
|
394 |
char buf[800]; /* no assert() message in the library is this long */ |
|
395 |
ulwp_t *self; |
|
396 |
lwpid_t lwpid; |
|
397 |
||
398 |
/* avoid recursion deadlock */ |
|
399 |
if ((self = __curthread()) != NULL) { |
|
400 |
if (assert_thread == self) |
|
401 |
_exit(127); |
|
402 |
enter_critical(self); |
|
6515
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5891
diff
changeset
|
403 |
(void) _lwp_mutex_lock(&assert_lock); |
0 | 404 |
assert_thread = self; |
405 |
lwpid = self->ul_lwpid; |
|
406 |
} else { |
|
407 |
self = NULL; |
|
6515
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5891
diff
changeset
|
408 |
(void) _lwp_mutex_lock(&assert_lock); |
6812 | 409 |
lwpid = _lwp_self(); |
0 | 410 |
} |
411 |
||
412 |
(void) strcpy(buf, "assertion failed for thread "); |
|
413 |
ultos((uint64_t)(uintptr_t)self, 16, buf + strlen(buf)); |
|
414 |
(void) strcat(buf, ", thread-id "); |
|
415 |
ultos((uint64_t)lwpid, 10, buf + strlen(buf)); |
|
416 |
(void) strcat(buf, ": "); |
|
417 |
(void) strcat(buf, assertion); |
|
418 |
(void) strcat(buf, ", file "); |
|
419 |
(void) strcat(buf, filename); |
|
420 |
(void) strcat(buf, ", line "); |
|
421 |
ultos((uint64_t)line_num, 10, buf + strlen(buf)); |
|
422 |
(void) strcat(buf, "\n"); |
|
5891 | 423 |
(void) __write(2, buf, strlen(buf)); |
0 | 424 |
/* |
425 |
* We could replace the call to Abort() with the following code |
|
426 |
* if we want just to issue a warning message and not die. |
|
427 |
* assert_thread = NULL; |
|
6515
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5891
diff
changeset
|
428 |
* _lwp_mutex_unlock(&assert_lock); |
0 | 429 |
* if (self != NULL) |
430 |
* exit_critical(self); |
|
431 |
*/ |
|
432 |
Abort(buf); |
|
433 |
} |
|
2248
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
434 |
|
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
435 |
/* |
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
436 |
* We define and export this version of assfail() just because libaio |
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
437 |
* used to define and export it, needlessly. Now that libaio is folded |
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
438 |
* into libc, we need to continue this for ABI/version reasons. |
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
439 |
* We don't use "#pragma weak assfail __assfail" in order to avoid |
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
440 |
* warnings from the check_fnames utility at build time for libraries |
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
441 |
* that define their own version of assfail(). |
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
442 |
*/ |
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
443 |
void |
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
444 |
assfail(const char *assertion, const char *filename, int line_num) |
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
445 |
{ |
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
446 |
__assfail(assertion, filename, line_num); |
4609e8bb25ad
6416832 libaio and librt can and should be folded into libc
raf
parents:
0
diff
changeset
|
447 |
} |
13700
2889e2596bd6
2619 asynchronous destruction of ZFS file systems
Christopher Siden <chris.siden@delphix.com>
parents:
11913
diff
changeset
|
448 |
|
2889e2596bd6
2619 asynchronous destruction of ZFS file systems
Christopher Siden <chris.siden@delphix.com>
parents:
11913
diff
changeset
|
449 |
void |
2889e2596bd6
2619 asynchronous destruction of ZFS file systems
Christopher Siden <chris.siden@delphix.com>
parents:
11913
diff
changeset
|
450 |
assfail3(const char *assertion, uintmax_t lv, const char *op, uintmax_t rv, |
2889e2596bd6
2619 asynchronous destruction of ZFS file systems
Christopher Siden <chris.siden@delphix.com>
parents:
11913
diff
changeset
|
451 |
const char *filename, int line_num) |
2889e2596bd6
2619 asynchronous destruction of ZFS file systems
Christopher Siden <chris.siden@delphix.com>
parents:
11913
diff
changeset
|
452 |
{ |
2889e2596bd6
2619 asynchronous destruction of ZFS file systems
Christopher Siden <chris.siden@delphix.com>
parents:
11913
diff
changeset
|
453 |
char buf[1000]; |
2889e2596bd6
2619 asynchronous destruction of ZFS file systems
Christopher Siden <chris.siden@delphix.com>
parents:
11913
diff
changeset
|
454 |
(void) strcpy(buf, assertion); |
2889e2596bd6
2619 asynchronous destruction of ZFS file systems
Christopher Siden <chris.siden@delphix.com>
parents:
11913
diff
changeset
|
455 |
(void) strcat(buf, " (0x"); |
2889e2596bd6
2619 asynchronous destruction of ZFS file systems
Christopher Siden <chris.siden@delphix.com>
parents:
11913
diff
changeset
|
456 |
ultos((uint64_t)lv, 16, buf + strlen(buf)); |
2889e2596bd6
2619 asynchronous destruction of ZFS file systems
Christopher Siden <chris.siden@delphix.com>
parents:
11913
diff
changeset
|
457 |
(void) strcat(buf, " "); |
2889e2596bd6
2619 asynchronous destruction of ZFS file systems
Christopher Siden <chris.siden@delphix.com>
parents:
11913
diff
changeset
|
458 |
(void) strcat(buf, op); |
2889e2596bd6
2619 asynchronous destruction of ZFS file systems
Christopher Siden <chris.siden@delphix.com>
parents:
11913
diff
changeset
|
459 |
(void) strcat(buf, " 0x"); |
2889e2596bd6
2619 asynchronous destruction of ZFS file systems
Christopher Siden <chris.siden@delphix.com>
parents:
11913
diff
changeset
|
460 |
ultos((uint64_t)rv, 16, buf + strlen(buf)); |
2889e2596bd6
2619 asynchronous destruction of ZFS file systems
Christopher Siden <chris.siden@delphix.com>
parents:
11913
diff
changeset
|
461 |
(void) strcat(buf, ")"); |
2889e2596bd6
2619 asynchronous destruction of ZFS file systems
Christopher Siden <chris.siden@delphix.com>
parents:
11913
diff
changeset
|
462 |
__assfail(buf, filename, line_num); |
2889e2596bd6
2619 asynchronous destruction of ZFS file systems
Christopher Siden <chris.siden@delphix.com>
parents:
11913
diff
changeset
|
463 |
} |