clerew5 | 17 May 2012 18:59
Picon
Favicon

Catching SIGSEGV

I am trying to trap a SIGSEGV (also SIGBUS, SIGILL and SIGFPE, but I have not even managed to generate those
yet :-( ).

I can easily get the program to produce a message "Segmentation Violation" on stderr, but noway can I catch
it before getting that message.

I have written
        sigemptyset(&set);
        sigaddset(&set, SIGUSR1);
        sigaddset(&set, SIGUSR2);
        sigaddset(&set, SIGTERM);
        sigaddset(&set, SIGINT);
        sigaddset(&set, SIGSEGV);
        sigaddset(&set, SIGBUS);
        sigaddset(&set, SIGILL);
        sigaddset(&set, SIGFPE);
        sigaddset(&set, SIGSYS); 
and I have created a pthread which contains
                sigwait(&set, &signal);
printf("Display signal %d\n", signal);
                switch (signal) {
                case SIGSEGV:
                case SIGBUS:
                case SIGILL:
                case SIGFPE:
                case SIGSYS:
                        fatal("Heat failed: %s", strerror(errno));
                case SIGTERM:
                case SIGINT:
                        warn("Heat terminated");
(Continue reading)

David Given | 18 May 2012 00:12

Re: Catching SIGSEGV

On 17/05/12 17:59, clerew5 wrote:
[...]
>         sigemptyset(&set);
>         sigaddset(&set, SIGUSR1);
>         sigaddset(&set, SIGUSR2);
>         sigaddset(&set, SIGTERM);
>         sigaddset(&set, SIGINT);
>         sigaddset(&set, SIGSEGV);
>         sigaddset(&set, SIGBUS);
>         sigaddset(&set, SIGILL);
>         sigaddset(&set, SIGFPE);
>         sigaddset(&set, SIGSYS); 
> and I have created a pthread which contains
>                 sigwait(&set, &signal);

I'm not quite sure what you're trying to do here --- AIUI sigwait()
blocks until a signal *for the blocked thread* is received, so no code
that can generate the signal will be run... (unless you send it manually
from another thread).

If you're trying to catch a signal thrown by code in a different thread,
then I don't think that will work.

The simplest approach is to just register a SIGSEGV signal handler in
the thread that's going to be doing the work. Then, when the signal is
thrown, your handler will run. If you want to do the work in a different
thread, then you'll need some sort of IPC between threads (but beware
that you can only run a small subset of functions safely from inside a
signal handler).

(Continue reading)

clerew5 | 19 May 2012 00:09
Picon
Favicon

Re: Catching SIGSEGV


--- In nslu2-linux@..., David Given <dg <at> ...> wrote:

> I'm not quite sure what you're trying to do here --- AIUI sigwait()
> blocks until a signal *for the blocked thread* is received, so no code
> that can generate the signal will be run... (unless you send it manually
> from another thread).

Ah! I had thought that all signals would be passed to all threads (which is indeed the case for signals
arising from outside).
> 
> If you're trying to catch a signal thrown by code in a different thread,
> then I don't think that will work.
> 
> The simplest approach is to just register a SIGSEGV signal handler in
> the thread that's going to be doing the work. Then, when the signal is
> thrown, your handler will run. If you want to do the work in a different
> thread, then you'll need some sort of IPC between threads (but beware
> that you can only run a small subset of functions safely from inside a
> signal handler).

Yes, I have now set up a sigaction-type handler in main(), and it seems to be inherited by processes created
subsequently to that. It sort of works, but I need to know where the SIGSEGV came from, in order to know where
to look for the bug. Here is my current handler:

void errHandler(int signum, siginfo_t *info, void *ptr) { 
        int count = backtrace( tracePtrs, 100 ); 
        backtrace_symbols_fd(tracePtrs, count, 2); 
        fatal("Heat failed with %s: si_code=%d", 
              strsignal(signum), info->si_code); 
(Continue reading)

David Given | 19 May 2012 01:20

Re: Re: Catching SIGSEGV

On 18/05/12 23:09, clerew5 wrote:
[...]
> Ah! I had thought that all signals would be passed to all threads (which is indeed the case for signals
arising from outside).

This is definitely getting out of my comfort zone (signals and threads
mix like oil and cats), but I was under the impression that outside
signals to sent to a single thread *at random* that had the signal
unblocked? So you control which thread you want to receive the signals
by blocking them from everywhere else.

[...]
> void errHandler(int signum, siginfo_t *info, void *ptr) { 
>         int count = backtrace( tracePtrs, 100 ); 
>         backtrace_symbols_fd(tracePtrs, count, 2); 
[...]
> But the stack it prints bears no resemblance to what I get from 'bt' in gdb. It seems to start from
errHandler, but after that it bears no resemblance to anything recognizable; and it is not just because it
arises within a handler, because I have manually invoked it from elsewhere in the program, and it still
does not work.

I've tried the test program in the backtrace man page on my armhf box,
and it doesn't work. I'm afraid that it's possible that backtrace simply
doesn't work on ARM.

> My plan is to embed the whole program (which has to run 24/7) within a shell script which observes the
failures, records what it can in a suitable file, and then restarts the program. But it is important that
things should be cleaned up before the program is removed...

You may be treading on thin ice here. Depending on what causes the seg
(Continue reading)

clerew5 | 21 May 2012 11:43
Picon
Favicon

Re: Catching SIGSEGV


--- In nslu2-linux@..., David Given <dg <at> ...> wrote:
>
> On 18/05/12 23:09, clerew5 wrote:
> [...]
> > Ah! I had thought that all signals would be passed to all threads (which is indeed the case for signals
arising from outside).
> 
> This is definitely getting out of my comfort zone (signals and threads
> mix like oil and cats), but I was under the impression that outside
> signals to sent to a single thread *at random* that had the signal
> unblocked? So you control which thread you want to receive the signals
> by blocking them from everywhere else.

Yes, that is what I thought, and the thread in question was the only one allowed to see the signals (the prime
purpose off that thread is to catch people who suddenly press buttons). But it seems that SIGSEGV (unless
generated externally) is only sent to the thread it happened in, or maybe its parents.

> > But the stack it prints bears no resemblance to what I get from 'bt' in gdb. It seems to start from
errHandler, but after that it bears no resemblance to anything recognizable; and it is not just because it
arises within a handler, because I have manually invoked it from elsewhere in the program, and it still
does not work.
> 
> I've tried the test program in the backtrace man page on my armhf box,
> and it doesn't work. I'm afraid that it's possible that backtrace simply
> doesn't work on ARM.

Actually, it is doing better than I thought. Here is some actual output:

./heat(pthread_create+0x710)[0x9da0]
(Continue reading)


Gmane