In fedora machine, I am handling segv signal, doing some cleanup and then generating core file using

SignalHandler(){
// Do Cleanup
// For generation of core file
    signal(a, SIG_DFL); 
    kill(getpid(), a);
    }

But When I run a multi threaded program, the core file seems to point to a place completely unrelated to where the seg fault has occurred. Is there any work around for this??

Say there are 3 thread m (main), t1, t2
if segv happened in t2, I am seeing the core file to point to some unrelated code in m. I think by the time I catch the signal and do cleanup and generate the core file, the backtrace stack is getting changed..

Also m is running a tcp server, waiting for connections from client. So mostly I am finding the core to point at this point: in accept call of tcp.

Any way in which I can make the core to point at the correct place?? Since it is necessary for me to handle segv and do some cleanup.

Dani AI

Generated

The problem is that your handler resets the disposition and then sends the signal to the process (via kill(getpid(), …)) — a process-directed fatal signal may be delivered to any thread that doesn’t block it, so the kernel can pick the main thread and the core will show accept() instead of the original faulting site. (man7.org)

A robust fix is: install SIGSEGV with sigaction() (use SA_SIGINFO | SA_ONSTACK), do only minimal async-signal-safe cleanup in the handler, then restore the default disposition and re-send the signal to the same thread. In a multithreaded program raise(sig) is defined to target the calling thread (it’s equivalent to pthread_kill(pthread_self(), sig)), so restoring default and calling raise() will let the kernel perform the usual core dump for that thread. If you already have the pthread_t for the faulting thread, pthread_kill(thread, sig) can also be used to target it directly. (man7.org)

Minimal example (illustrative — keep handler work tiny and async-signal-safe):

static void segv_handler(int sig, siginfo_t *si, void *uc)
{
    const char msg[] = "fatal: segfault, generating core\n";
    write(STDERR_FILENO, msg, sizeof msg - 1);   /* async-signal-safe */
    struct sigaction sa = { .sa_handler = SIG_DFL };
    sigemptyset(&sa.sa_mask);
    sigaction(sig, &sa, NULL);                   /* restore default */
    raise(sig);                                  /* re-deliver to this thread */
}

/* Install with:
   sa.sa_sigaction = segv_handler;
   sa.sa_flags = SA_SIGINFO | SA_ONSTACK;
   sigaction(SIGSEGV, &sa, NULL);
*/

Use an alternate stack (sigaltstack) to handle stack-overflow-style faults, and remember a signal handler must call only async-signal-safe functions (so avoid malloc, printf, complex logging, etc.). If you need richer dumps (all-thread backtraces, symbolized output) prefer to have the handler record the fault address/ucontext and then let an external monitor or a fork+gcore approach produce the full dump outside the delicate handler context. (man7.org)

’s pthread_kill hint is on point if you can identify the exact pthread_t; otherwise restoring default and using raise() from the faulting thread is the simplest way to get a core that reflects the thread that actually crashed. , changing kill(getpid(), ...) to a thread-directed re-raise as above should make your cores point at the real faulting location.

Recommended Answers

All 3 Replies

Have you tried pthread_kill (pthread_self (), sig) ?

Since I am handling segv generated by thread t1 in thread m, does pthread_self() point to thread m; is there a way I can kill the target thread, t1 in this case.

Anyways, will try that..tq.

You can call pthread_kill on any valid thread identifier. The trick is getting a handle to that thread. If you've already got a handle to the thread in question they you can provide that. pthread_self on the other hand, returns the identifier of the currently active thread.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.