Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Signal handling in pthreads

I have created a pthread, and installed a signal handler inside that, same way as we do in main( ) function. The thread's signal handler is a separate function. Surprisingly, it is not working, that is the thread's signal handler is not able to catch signals.

Here is the code:

#include <pthread.h> #include <unistd.h> #include <sys/types.h> #include <stdio.h> #include <signal.h> #include <string.h>  typedef struct data {  char name[10];  int age; }data;  void sig_func(int sig) {  printf("Caught signal: %d\n",sig);  signal(SIGSEGV,sig_func); }  void func(data *p) {  printf("This is from thread function\n");  signal(SIGSEGV,sig_func); // Register signal handler inside thread  strcpy(p->name,"Mr. Linux");  p->age=30;  sleep(2); // Sleep to catch the signal }  int main() {  pthread_t tid;  pthread_attr_t attr;  data *ptr;   pthread_attr_init(&attr);  pthread_create(&tid,&attr,(void*)func,ptr);  pthread_kill(tid,SIGSEGV);   pthread_join(tid,NULL);  printf("Name:%s\n",ptr->name);  printf("Age:%d\n",ptr->age); } 

Output:

Segmentation fault (which means the signal is not caught by handler)

like image 594
RajSanpui Avatar asked Mar 12 '11 11:03

RajSanpui


People also ask

Where should a signal be delivered for multi threaded?

For multithreaded programs, sigwait(2) is the preferred interface to use, because it deals so well with aysynchronously generated signals. sigwait() causes the calling thread to wait until any signal identified by its set argument is delivered to the thread.

What does a signal handler do?

24.4 Defining Signal Handlers A signal handler is just a function that you compile together with the rest of the program. Instead of directly invoking the function, you use signal or sigaction to tell the operating system to call it when a signal arrives.

Are signal handlers per thread?

signal is a per process call, not a per thread one, if you call it it sets the handler for all threads in the process. Signals and threads is a complex topic.

How do you send a signal to a thread?

The pthread_kill() function sends the signal sig to thread, a thread in the same process as the caller. The signal is asynchronously directed to thread. If sig is 0, then no signal is sent, but error checking is still performed; this can be used to check for the existence of a thread ID.


1 Answers

There are several problems with your code:

  • ptr is not initialised, so all the ptr-> parts will crash the program
  • you are calling pthread_kill() immediately, very likely before the signal handler has been installed, and in a thread (which has unspecified behaviour)
  • you call printf() from a signal handler, which is not guaranteed to work (see man 7 signal for a list of safe functions)

This will work a lot better, though you'd still need proper thread synchronisation, and as stated elsewhere, you should use sigaction():

#include <pthread.h> #include <unistd.h> #include <sys/types.h> #include <stdio.h> #include <signal.h> #include <string.h>  typedef struct data {  char name[10];  int age; }data;  void sig_func(int sig) {  write(1, "Caught signal 11\n", 17);  signal(SIGSEGV,sig_func); }  void func(data *p) {  fprintf(stderr, "This is from thread function\n");  strcpy(p->name,"Mr. Linux");  p->age=30;  sleep(2); // Sleep to catch the signal }  int main() {  pthread_t tid;  pthread_attr_t attr;  data d;  data *ptr = &d;   signal(SIGSEGV,sig_func); // Register signal handler before going multithread  pthread_attr_init(&attr);  pthread_create(&tid,&attr,(void*)func,ptr);  sleep(1); // Leave time for initialisation  pthread_kill(tid,SIGSEGV);   pthread_join(tid,NULL);  fprintf(stderr, "Name:%s\n",ptr->name);  fprintf(stderr, "Age:%d\n",ptr->age); } 

Edit: install sighandler in main thread

like image 129
sam hocevar Avatar answered Nov 11 '22 09:11

sam hocevar