Thread: question about pthreads and sigsegv

  1. #1
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445

    question about pthreads and sigsegv

    if I am executing in a thread, and the thread causes segfault, caught by the signal handler, can I call pthread_self() and have it return the thread id of the faulting thread? if not, how can I determine what thread faulted so I can kill it?

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Elkvis View Post
    if I am executing in a thread, and the thread causes segfault, caught by the signal handler, can I call pthread_self() and have it return the thread id of the faulting thread? if not, how can I determine what thread faulted so I can kill it?
    I think it sounds like a recipe for disaster. SIGSEGV is catchable but the behavior after doing so is undefined unless the signal was generated by raise() or kill(). It sounds like you are trying to cover up bugs in your program -- the better solution is to find and squash these bugs so that you're not getting SIGSEGV in the first place.

    If the thread is executing code which is out of your direct control, you really should be running it in a separate process anyway.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  3. #3
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Quote Originally Posted by brewbuck View Post
    the better solution is to find and squash these bugs so that you're not getting SIGSEGV in the first place.
    I don't actually ever see this kind of activity happening, but I'm considering converting my multi-process server program over to a single-process, multi-threaded model, and I want to be prepared for bad things to happen if they do.

  4. #4
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Elkvis View Post
    I don't actually ever see this kind of activity happening, but I'm considering converting my multi-process server program over to a single-process, multi-threaded model, and I want to be prepared for bad things to happen if they do.
    The fundamental problem is that signals behave strangely under pthreads. Signals are not delivered to the thread which triggered them. Instead, they are delivered to whichever thread has the signal unblocked. If all threads have the signal unblocked, then any thread at all could receive the signal, not just the one which triggered it. In other words, pthread_self() may not be referring to the thread which caused the SIGSEGV.

    There is no solution to this. In order to ensure that only the faulting thread receives the signal, it must be the only thread with this signal unblocked. But there is no way to accomplish that, because you do not know ahead of time which thread is about to segfault.

    The best you can do is to block SIGSEGV in ALL threads but one, and when this thread receives the signal, simply shut everything down gracefully.

    There is a hack that could possibly do what you're looking for, but I think it's evil and I don't really want to describe it. I only mention it in case somebody else points out that it's possible. I know it is, but it sucks.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  5. #5
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    so if I block signals in all but the main thread, could I call fork() and then one of the exec() functions to respawn my server in the event of an error, or would I have to find some other way to make it restart? I know programs can be set up in /etc/inittab to respawn automatically if they die, but I'm not sure that's the best way.

  6. #6
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    http://www.opengroup.org/onlinepubs/...l#tag_02_04_03
    Quote Originally Posted by Posix
    The behavior of a process is undefined after it returns normally from a signal-catching function for a SIGBUS, SIGFPE, SIGILL, or SIGSEGV signal that was not generated by kill(), sigqueue(), or raise().
    gg

  7. #7
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    That answers my question perfectly. thanks for the link.

Popular pages Recent additions subscribe to a feed