Introduce a pthread__error() macro, for detected application errors as

opposed to internal errors. The setting of the PTHREAD_ERRORMODE
environment variable determines the runtime behavior. Valid settings
are "ignore", "abort", and "print". The default is currently "abort".
This commit is contained in:
nathanw 2003-04-23 19:35:47 +00:00
parent 275eeea6c9
commit df2772713e
2 changed files with 63 additions and 6 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: pthread.c,v 1.16 2003/04/07 21:29:48 nathanw Exp $ */ /* $NetBSD: pthread.c,v 1.17 2003/04/23 19:35:47 nathanw Exp $ */
/*- /*-
* Copyright (c) 2001 The NetBSD Foundation, Inc. * Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__RCSID("$NetBSD: pthread.c,v 1.16 2003/04/07 21:29:48 nathanw Exp $"); __RCSID("$NetBSD: pthread.c,v 1.17 2003/04/23 19:35:47 nathanw Exp $");
#include <err.h> #include <err.h>
#include <errno.h> #include <errno.h>
@ -75,6 +75,12 @@ static int nextthread;
static pthread_spin_t nextthread_lock; static pthread_spin_t nextthread_lock;
static pthread_attr_t pthread_default_attr; static pthread_attr_t pthread_default_attr;
#define PTHREAD_ERRORMODE_ABORT 1
#define PTHREAD_ERRORMODE_PRINT 2
#define PTHREAD_ERRORMODE_IGNORE 3
static int pthread__errormode;
pthread_spin_t pthread__runqueue_lock; pthread_spin_t pthread__runqueue_lock;
struct pthread_queue_t pthread__runqueue; struct pthread_queue_t pthread__runqueue;
struct pthread_queue_t pthread__idlequeue; struct pthread_queue_t pthread__idlequeue;
@ -119,6 +125,7 @@ void
pthread_init(void) pthread_init(void)
{ {
pthread_t first; pthread_t first;
char *mode;
extern int __isthreaded; extern int __isthreaded;
/* Initialize locks first; they're needed elsewhere. */ /* Initialize locks first; they're needed elsewhere. */
@ -147,6 +154,16 @@ pthread_init(void)
pthread__debug_init(); pthread__debug_init();
#endif #endif
pthread__errormode = PTHREAD_ERRORMODE_ABORT;
if ((mode = getenv("PTHREAD_ERRORMODE")) != NULL) {
if (strcasecmp(mode, "ignore") == 0)
pthread__errormode = PTHREAD_ERRORMODE_IGNORE;
else if (strcasecmp(mode, "print") == 0)
pthread__errormode = PTHREAD_ERRORMODE_PRINT;
else if (strcasecmp(mode, "abort") == 0)
pthread__errormode = PTHREAD_ERRORMODE_ABORT;
}
/* Tell libc that we're here and it should role-play accordingly. */ /* Tell libc that we're here and it should role-play accordingly. */
__isthreaded = 1; __isthreaded = 1;
} }
@ -1051,3 +1068,33 @@ pthread__assertfunc(char *file, int line, char *function, char *expr)
_exit(1); _exit(1);
} }
void
pthread__errorfunc(char *file, int line, char *function, char *msg)
{
char buf[1024];
int len;
if (pthread__errormode == PTHREAD_ERRORMODE_IGNORE)
return;
/*
* snprintf should not acquire any locks, or we could
* end up deadlocked if the assert caller held locks.
*/
len = snprintf(buf, 1024,
"Error detected, file \"%s\", line %d%s%s%s: %s.\n",
file, line,
function ? ", function \"" : "",
function ? function : "",
function ? "\"" : "",
msg);
write(STDERR_FILENO, buf, len);
if (pthread__errormode == PTHREAD_ERRORMODE_ABORT) {
(void)kill(getpid(), SIGABRT);
_exit(1);
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: pthread_int.h,v 1.10 2003/04/18 21:32:32 nathanw Exp $ */ /* $NetBSD: pthread_int.h,v 1.11 2003/04/23 19:35:47 nathanw Exp $ */
/*- /*-
* Copyright (c) 2001 The NetBSD Foundation, Inc. * Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -339,9 +339,18 @@ void pthread__sigcontext_to_ucontext(const struct pthread__sigcontext *,
#define pthread__self() (pthread__id(pthread__sp())) #define pthread__self() (pthread__id(pthread__sp()))
#define pthread__assert(e) \ #define pthread__assert(e) do { \
(__predict_true((e)) ? __static_cast(void,0) : \ if (__predict_false(!(e))) \
pthread__assertfunc(__FILE__, __LINE__, __func__, #e)) pthread__assertfunc(__FILE__, __LINE__, __func__, #e); \
} while (0)
#define pthread__error(err, msg, e) do { \
if (__predict_false(!(e))) { \
pthread__errorfunc(__FILE__, __LINE__, __func__, msg); \
return (err); \
} \
} while (0)
/* These three routines are defined in processor-specific code. */ /* These three routines are defined in processor-specific code. */
@ -358,5 +367,6 @@ void pthread__signal_deferred(pthread_t self, pthread_t t);
void pthread__destroy_tsd(pthread_t self); void pthread__destroy_tsd(pthread_t self);
void pthread__assertfunc(char *file, int line, char *function, char *expr); void pthread__assertfunc(char *file, int line, char *function, char *expr);
void pthread__errorfunc(char *file, int line, char *function, char *msg);
#endif /* _LIB_PTHREAD_INT_H */ #endif /* _LIB_PTHREAD_INT_H */