assfail.c revision 35e6f27ad0d19ae8ac48ddcbccbe1af717832f29
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include "lint.h"
#include "thr_uberdata.h"
const char *panicstr;
/*
* Called from __assert() to set panicstr and panic_thread.
*/
void
__set_panicstr(const char *msg)
{
panic_thread = __curthread();
}
/*
* Called from exit() (atexit function) to give precedence
* to assertion failures and a core dump over _exit().
*/
void
{
(void) _lwp_mutex_lock(&assert_lock);
}
static void
{
/* to help with core file debugging */
panic_thread = self;
} else {
}
/* set SIGABRT signal handler to SIG_DFL w/o grabbing any locks */
/* delete SIGABRT from the signal mask */
(void) sigemptyset(&sigmask);
_exit(127);
}
/*
* Write a panic message w/o grabbing any locks other than assert_lock.
* We have no idea what locks are held at this point.
*/
static void
{
(void) _lwp_mutex_lock(&assert_lock);
}
void
{
}
void
{
}
/*
* Utility function for converting a long integer to a string, avoiding stdio.
* 'base' must be one of 10 or 16
*/
void
{
do {
n /= base;
} while (n);
if (base == 16) {
*s++ = '0';
*s++ = 'x';
}
do {
*s++ = *--cp;
*s = '\0';
}
/*
* Report application lock usage error for mutexes and condvars.
* Not called if _THREAD_ERROR_DETECTION=0.
* Continue execution if _THREAD_ERROR_DETECTION=1.
* Dump core if _THREAD_ERROR_DETECTION=2.
*/
void
{
char buf[800];
/*
* Take a snapshot of the mutex before it changes (we hope!).
* Use memcpy() rather than 'mcopy = *mp' in case mp is unaligned.
*/
/* avoid recursion deadlock */
if (assert_thread == self)
_exit(127);
(void) _lwp_mutex_lock(&assert_lock);
} else {
(void) _lwp_mutex_lock(&assert_lock);
udp = &__uberdata;
}
"\n*** _THREAD_ERROR_DETECTION: lock usage error detected ***\n");
}
} else if (!mutex_held(&mcopy)) {
} else if (mcopy.mutex_rcount) {
} else {
}
/* EMPTY */;
else if (mcopy.mutex_lockw == 0)
} else {
}
(void) _lwp_mutex_unlock(&assert_lock);
}
/*
* Report application lock usage error for rwlocks.
* Not called if _THREAD_ERROR_DETECTION=0.
* Continue execution if _THREAD_ERROR_DETECTION=1.
* Dump core if _THREAD_ERROR_DETECTION=2.
*/
void
{
char buf[800];
int process;
/*
* Take a snapshot of the rwlock before it changes (we hope!).
* Use memcpy() rather than 'rcopy = *rp' in case rp is unaligned.
*/
/* avoid recursion deadlock */
if (assert_thread == self)
_exit(127);
(void) _lwp_mutex_lock(&assert_lock);
} else {
(void) _lwp_mutex_lock(&assert_lock);
udp = &__uberdata;
}
"\n*** _THREAD_ERROR_DETECTION: lock usage error detected ***\n");
if (process) {
}
if (rwstate & URW_WRITE_LOCKED) {
if (process) {
}
} else if (rwstate & URW_READERS_MASK) {
} else {
}
if (rwstate & URW_HAS_WAITERS)
(void) _lwp_mutex_unlock(&assert_lock);
}
/*
* Report a thread usage error.
* Not called if _THREAD_ERROR_DETECTION=0.
* Writes message and continues execution if _THREAD_ERROR_DETECTION=1.
* Writes message and dumps core if _THREAD_ERROR_DETECTION=2.
*/
void
thread_error(const char *msg)
{
char buf[800];
/* avoid recursion deadlock */
if (assert_thread == self)
_exit(127);
(void) _lwp_mutex_lock(&assert_lock);
} else {
(void) _lwp_mutex_lock(&assert_lock);
udp = &__uberdata;
}
"thread usage error detected ***\n*** ");
(void) _lwp_mutex_unlock(&assert_lock);
}
/*
* We use __assfail() because the libc __assert() calls
* gettext() which calls malloc() which grabs a mutex.
* We do everything without calling standard i/o.
* assfail() and _assfail() are exported functions;
* __assfail() is private to libc.
*/
void
{
/* avoid recursion deadlock */
if (assert_thread == self)
_exit(127);
(void) _lwp_mutex_lock(&assert_lock);
} else {
(void) _lwp_mutex_lock(&assert_lock);
}
/*
* We could replace the call to Abort() with the following code
* if we want just to issue a warning message and not die.
* assert_thread = NULL;
* _lwp_mutex_unlock(&assert_lock);
* if (self != NULL)
* exit_critical(self);
*/
}
/*
* We define and export this version of assfail() just because libaio
* used to define and export it, needlessly. Now that libaio is folded
* We don't use "#pragma weak assfail __assfail" in order to avoid
* warnings from the check_fnames utility at build time for libraries
* that define their own version of assfail().
*/
void
{
}