GDB tells me that pthread_kill
is causing a segmentation fault in my program. Basically I'm using pthread_kill
to check if a thread is alive or not given its ID.
I've been searching the web and found that it might be that pthread_kill
is causing segmentation fault when TID is invalid. Yes, I have been testing my program using "invalid"(contrived by me) TIDs of type int
. Could that be the real cause?
pthread_t
is not a thread ID, or a numeric index. It is an opaque type. Making up values can result in a crash.
On Linux NPTL, pthread_t is used as a pointer:
int
__pthread_kill (threadid, signo)
pthread_t threadid;
int signo;
{
struct pthread *pd = (struct pthread *) threadid;
It should be fairly clear where things are going wrong already :) Note that this pointerness is also an implementation detail - the older Linuxthreads implementation used numeric indices into a table, and there you could indeed make up TIDs and not expect things to crash.
You need to be tracking thread life and death yourself. A pthread_t
is valid until you call pthread_join
on it successfully. If you want to test whether a valid pthread_t
is alive, call pthread_tryjoin_np
on it; if it returns EBUSY
, the thread is alive. If the function succeeds, the pthread_t
is no longer valid; you must not re-use it at this point - so you must make a note somewhere that that thread is dead now, and there's no need to check it anymore!
You could, of course, implement your own tracking system - create a table somewhere of liveness, a system for handing out TIDs, and passing them into newly created threads. Have each thread mark itself as dead prior to exiting (perhaps using pthread_cleanup_push
so you handle thread cancellation and pthread_exit
), and detach the thread so you don't need to join it (using pthread_detach
). Now you have explicit control of your thread-death reporting.
To get around this limitation in my code, I set the TID to zero when the code is not running
memset(&thread, '\0', sizeof(pthread_t));
... and check it for null before calling pthread_kill
//this code will run if thread is not valid
if (!thread || ESRCH == pthread_kill(thread, 0)) {
//do stuff and create the thread
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With