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.
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in New Issue