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:
parent
275eeea6c9
commit
df2772713e
|
@ -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.
|
||||
|
@ -37,7 +37,7 @@
|
|||
*/
|
||||
|
||||
#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 <errno.h>
|
||||
|
@ -75,6 +75,12 @@ static int nextthread;
|
|||
static pthread_spin_t nextthread_lock;
|
||||
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;
|
||||
struct pthread_queue_t pthread__runqueue;
|
||||
struct pthread_queue_t pthread__idlequeue;
|
||||
|
@ -119,6 +125,7 @@ void
|
|||
pthread_init(void)
|
||||
{
|
||||
pthread_t first;
|
||||
char *mode;
|
||||
extern int __isthreaded;
|
||||
|
||||
/* Initialize locks first; they're needed elsewhere. */
|
||||
|
@ -147,6 +154,16 @@ pthread_init(void)
|
|||
pthread__debug_init();
|
||||
#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. */
|
||||
__isthreaded = 1;
|
||||
}
|
||||
|
@ -1051,3 +1068,33 @@ pthread__assertfunc(char *file, int line, char *function, char *expr)
|
|||
|
||||
_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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
@ -339,9 +339,18 @@ void pthread__sigcontext_to_ucontext(const struct pthread__sigcontext *,
|
|||
|
||||
#define pthread__self() (pthread__id(pthread__sp()))
|
||||
|
||||
#define pthread__assert(e) \
|
||||
(__predict_true((e)) ? __static_cast(void,0) : \
|
||||
pthread__assertfunc(__FILE__, __LINE__, __func__, #e))
|
||||
#define pthread__assert(e) do { \
|
||||
if (__predict_false(!(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. */
|
||||
|
@ -358,5 +367,6 @@ void pthread__signal_deferred(pthread_t self, pthread_t t);
|
|||
|
||||
void pthread__destroy_tsd(pthread_t self);
|
||||
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 */
|
||||
|
|
Loading…
Reference in New Issue