From 4892a26a45b1a522a99507f7e2f74520d6917c4b Mon Sep 17 00:00:00 2001 From: Eric Bollengier Date: Thu, 24 Jun 2010 14:07:56 +0200 Subject: [PATCH] Add wrapper for pthread_kill() to check if thread exists before using kill You can enable this extra check to be sure that we use pthread_kill() only with valid pthread id USE_LOCKMGR_SAFEKILL in version.h. It looks like that some implementation, like the linux one, segfaults when you are sending a signal to a non existing thread. This problem can be fixed by using non detached thread, or by checking if the thread is still present before sending the signal. --- bacula/src/lib/lockmgr.c | 34 ++++++++++++++++++++++++++++++++++ bacula/src/lib/lockmgr.h | 10 ++++++++++ 2 files changed, 44 insertions(+) diff --git a/bacula/src/lib/lockmgr.c b/bacula/src/lib/lockmgr.c index e95c92c24f..5e27b224a0 100644 --- a/bacula/src/lib/lockmgr.c +++ b/bacula/src/lib/lockmgr.c @@ -710,6 +710,40 @@ int pthread_mutex_destroy(bthread_mutex_t *m) return pthread_mutex_destroy(&m->mutex); } +/* + * Replacement for pthread_kill (only with USE_LOCKMGR_SAFEKILL) + */ +int bthread_kill(pthread_t thread, int sig, + const char *file, int line) +{ + bool thread_found_in_process=false; + + /* We doesn't allow to send signal to ourself */ + ASSERT(!pthread_equal(thread, pthread_self())); + + /* This loop isn't very efficient with dozens of threads but we don't use + * signal very much, and this feature is for testing only + */ + lmgr_p(&lmgr_global_mutex); + { + lmgr_thread_t *item; + foreach_dlist(item, global_mgr) { + if (pthread_equal(thread, item->thread_id)) { + thread_found_in_process=true; + break; + } + } + } + lmgr_v(&lmgr_global_mutex); + + /* Sending a signal to non existing thread can create problem + * so, we can stop here. + */ + ASSERT(thread_found_in_process == true); + + return pthread_kill(thread, sig); +} + /* * Replacement for pthread_mutex_lock() * Returns always ok diff --git a/bacula/src/lib/lockmgr.h b/bacula/src/lib/lockmgr.h index a0bd869492..a7f26e85f4 100644 --- a/bacula/src/lib/lockmgr.h +++ b/bacula/src/lib/lockmgr.h @@ -158,6 +158,16 @@ int lmgr_thread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg); +/* + * Can use SAFEKILL to check if the argument is a valid threadid + */ +int bthread_kill(pthread_t thread, int sig, + const char *file="*unknown*", int line=0); + +#ifdef USE_LOCKMGR_SAFEKILL +# define pthread_kill(a,b) bthread_kill((a),(b), __FILE__, __LINE__) +#endif + #define BTHREAD_MUTEX_NO_PRIORITY {PTHREAD_MUTEX_INITIALIZER, 0} #define BTHREAD_MUTEX_INITIALIZER BTHREAD_MUTEX_NO_PRIORITY -- 2.39.5