assfail.c revision f841f6ad96ea6675d6c6b35c749eaac601799fdf
/*
* 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 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#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) _private_lwp_mutex_lock(&assert_lock);
}
static void
{
/* to help with core file debugging */
panic_thread = self;
} else {
lwpid = __lwp_self();
}
/* set SIGABRT signal handler to SIG_DFL w/o grabbing any locks */
/* delete SIGABRT from the signal mask */
(void) _private_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) _private_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
{
/* take a snapshot of the mutex before it changes (we hope!) */
char buf[800];
/* avoid recursion deadlock */
if (assert_thread == self)
_exit(127);
(void) _private_lwp_mutex_lock(&assert_lock);
} else {
(void) _private_lwp_mutex_lock(&assert_lock);
lwpid = __lwp_self();
udp = &__uberdata;
pid = _private_getpid();
}
"\n*** _THREAD_ERROR_DETECTION: lock usage error detected ***\n");
}
} else if (!mutex_is_held(&mcopy)) {
} else if (mcopy.mutex_rcount) {
} else {
}
/* EMPTY */;
else if (mcopy.mutex_lockw == 0)
} else {
}
(void) _private_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
{
/* take a snapshot of the rwlock before it changes (we hope) */
char buf[800];
/* avoid recursion deadlock */
if (assert_thread == self)
_exit(127);
(void) _private_lwp_mutex_lock(&assert_lock);
} else {
(void) _private_lwp_mutex_lock(&assert_lock);
lwpid = __lwp_self();
udp = &__uberdata;
pid = _private_getpid();
}
"\n*** _THREAD_ERROR_DETECTION: lock usage error detected ***\n");
if (*rwstate & URW_WRITE_LOCKED) {
} else if (*rwstate & URW_READERS_MASK) {
} else
if (*rwstate & URW_HAS_WAITERS) {
if (*rwstate & URW_WRITE_WANTED)
" (including at least one writer)");
}
} else if (rcopy.rwlock_readers < 0) {
} else if (rcopy.rwlock_readers > 0) {
} else {
}
(void) _private_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) _private_lwp_mutex_lock(&assert_lock);
} else {
(void) _private_lwp_mutex_lock(&assert_lock);
lwpid = __lwp_self();
udp = &__uberdata;
}
"thread usage error detected ***\n*** ");
(void) _private_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) _private_lwp_mutex_lock(&assert_lock);
} else {
(void) _private_lwp_mutex_lock(&assert_lock);
lwpid = __lwp_self();
}
/*
* 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;
* _private_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
{
}