2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 2N/A * Use is subject to license terms. 2N/A * Called from __assert() to set panicstr and panic_thread. 2N/A * Called from exit() (atexit function) to give precedence 2N/A * to assertion failures and a core dump over _exit(). 2N/A /* to help with core file debugging */ 2N/A /* set SIGABRT signal handler to SIG_DFL w/o grabbing any locks */ 2N/A /* delete SIGABRT from the signal mask */ 2N/A * Write a panic message w/o grabbing any locks other than assert_lock. 2N/A * We have no idea what locks are held at this point. 2N/A char msg[
400];
/* no panic() message in the library is this long */ 2N/A * Utility function for converting a long integer to a string, avoiding stdio. 2N/A * 'base' must be one of 10 or 16 2N/A char lbuf[
24];
/* 64 bits fits in 16 hex digits, 20 decimal */ 2N/A * Report application lock usage error for mutexes and condvars. 2N/A * Not called if _THREAD_ERROR_DETECTION=0. 2N/A * Continue execution if _THREAD_ERROR_DETECTION=1. 2N/A * Dump core if _THREAD_ERROR_DETECTION=2. 2N/A * Take a snapshot of the mutex before it changes (we hope!). 2N/A * Use memcpy() rather than 'mcopy = *mp' in case mp is unaligned. 2N/A /* avoid recursion deadlock */ 2N/A "\n*** _THREAD_ERROR_DETECTION: lock usage error detected ***\n");
2N/A (
void)
strcat(
buf,
": calling thread does not own the lock");
2N/A (
void)
strcat(
buf,
": calling thread already owns the lock");
2N/A * Report application lock usage error for rwlocks. 2N/A * Not called if _THREAD_ERROR_DETECTION=0. 2N/A * Continue execution if _THREAD_ERROR_DETECTION=1. 2N/A * Dump core if _THREAD_ERROR_DETECTION=2. 2N/A * Take a snapshot of the rwlock before it changes (we hope!). 2N/A * Use memcpy() rather than 'rcopy = *rp' in case rp is unaligned. 2N/A /* avoid recursion deadlock */ 2N/A "\n*** _THREAD_ERROR_DETECTION: lock usage error detected ***\n");
2N/A (
void)
strcat(
buf,
"\nand the lock appears to have waiters");
2N/A * Report a thread usage error. 2N/A * Not called if _THREAD_ERROR_DETECTION=0. 2N/A * Writes message and continues execution if _THREAD_ERROR_DETECTION=1. 2N/A * Writes message and dumps core if _THREAD_ERROR_DETECTION=2. 2N/A /* avoid recursion deadlock */ 2N/A "thread usage error detected ***\n*** ");
2N/A * We use __assfail() because the libc __assert() calls 2N/A * gettext() which calls malloc() which grabs a mutex. 2N/A * We do everything without calling standard i/o. 2N/A * assfail() and _assfail() are exported functions; 2N/A * __assfail() is private to libc. 2N/A char buf[
800];
/* no assert() message in the library is this long */ 2N/A /* avoid recursion deadlock */ 2N/A * We could replace the call to Abort() with the following code 2N/A * if we want just to issue a warning message and not die. 2N/A * assert_thread = NULL; 2N/A * _lwp_mutex_unlock(&assert_lock); 2N/A * exit_critical(self); 2N/A * We define and export this version of assfail() just because libaio 2N/A * used to define and export it, needlessly. Now that libaio is folded 2N/A * We don't use "#pragma weak assfail __assfail" in order to avoid 2N/A * warnings from the check_fnames utility at build time for libraries 2N/A * that define their own version of assfail().