From: cerr on
On Jan 15, 1:32 pm, sc...(a)slp53.sl.home (Scott Lurndal) wrote:
> cerr <ron.egg...(a)gmail.com> writes:
> >On Jan 15, 9:12=A0am, David Schwartz <dav...(a)webmaster.com> wrote:
> >> On Jan 15, 8:49=A0am, cerr <ron.egg...(a)gmail.com> wrote:
>
> >> > Exactly that's where one of the problems was:
> >> > fre(var);
> >> > without
> >> > var=3DNULL;
> >> > which leads to a stale pointer that still has a "seemingly" valid
> >> > value but is wrong!
> >> > Now I'm off to huntting the next seg fault... :o - that I -
> >> > unfortunately - don't really know where it's happening cause gdb only
> >> > reports the SIGKILL but with strace I see that a SIGSEGV is leading to
> >> > SIGKILLing the other threads.... no idea why i can't see the SIGSEGV
> >> > in gdb... :(
>
> >> Catch the SIGSEGV and call 'abort'.
> >Huh, IO don't understand. Where would I call abort().
>
> #include <assert.h>
> #include <signal.h>
> #include <stdlib.h>
>
> void
> catch_sigsegv(int signo, siginfo_t *sip, void *ucp)
> {
>         abort();
>
> }
>
> main(...)
>
>   ...
>
>   struct sigaction sa;
>   stack_t          ss;
>
>   ss.ss_sp = malloc(SIGSTKSZ);
>   assert(ss.ss_sp != NULL);
>   ss.ss_size = SIGSTKSZ;
>   ss.ss_flags = 0;
>   diag = sigaltstack(&ss, NULL);
>   if (diag == -1) {
>      //handle error
>   }
>
>   sigemptyset(&sa.sa_mask);
>   sa.sa_flags = SA_ONSTACK;
>   sa.sigaction = catch_sigsegv;
>   diag = sigaction(SIGSEGV, &sa, NULL);
>   if (diag == -1) {
>      // handle error
>   }
>
Hi Scott,

Okay, thanks for that, but what am i doing here with that? I thought
I'd need to use signal() to trigger action like calling a function
upon reception of such, no?
How do I read the stack from the thread the SIGSEGV happened in after
it happened? Doesn't the stack of that thread get ereased immediately?
Also how can i read where it happened/which function the SIGSEGV
happened in?

Thanks,
Ron

From: Scott Lurndal on
cerr <ron.eggler(a)gmail.com> writes:
>On Jan 15, 1:32=A0pm, sc...(a)slp53.sl.home (Scott Lurndal) wrote:

>> #include <assert.h>
>> #include <signal.h>
>> #include <stdlib.h>
>>
>> void
>> catch_sigsegv(int signo, siginfo_t *sip, void *ucp)
>> {
>> =A0 =A0 =A0 =A0 abort();
>>
>> }
>>
>> main(...)
>>
>> =A0 ...
>>
>> =A0 struct sigaction sa;
>> =A0 stack_t =A0 =A0 =A0 =A0 =A0ss;
>>
>> =A0 ss.ss_sp =3D malloc(SIGSTKSZ);
>> =A0 assert(ss.ss_sp !=3D NULL);
>> =A0 ss.ss_size =3D SIGSTKSZ;
>> =A0 ss.ss_flags =3D 0;
>> =A0 diag =3D sigaltstack(&ss, NULL);
>> =A0 if (diag =3D=3D -1) {
>> =A0 =A0 =A0//handle error
>> =A0 }
>>
>> =A0 sigemptyset(&sa.sa_mask);
>> =A0 sa.sa_flags =3D SA_ONSTACK;
>> =A0 sa.sigaction =3D catch_sigsegv;
>> =A0 diag =3D sigaction(SIGSEGV, &sa, NULL);
>> =A0 if (diag =3D=3D -1) {
>> =A0 =A0 =A0// handle error
>> =A0 }
>>
>Hi Scott,
>
>Okay, thanks for that, but what am i doing here with that? I thought
>I'd need to use signal() to trigger action like calling a function

signal(2) is deprecated in favor of sigaction(2) (as used above).

>upon reception of such, no?
>How do I read the stack from the thread the SIGSEGV happened in after

In the handler, you can:

void
catch_sigsegv(int signo, siginfo_t *sip, void *ucp)
{
ucontext_t *uconp = (ucontext_t *)ucp;

/* Instruction pointer at failure (x86_64) */
printf("failure at 0x%lx\n", uconp->uc_mcontext.gregs[REG_RIP]);

/* For i386 */
printf("failure at 0x%lx\n", uconp->uc_mcontext.gregs[REG_EIP]);

/* for other architectures, see /usr/include/sys/ucontext.h */
}

Take the address printed above and feed it into the addr2line
command along with your executable, and if you're compiled with -g,
addr2line will tell you what line in what source file corresponds
to the instruction pointer at the time of the SIGSEGV.

scott
From: Ersek, Laszlo on
In article <x954n.11461$0X.9105(a)news.usenetserver.com>, scott(a)slp53.sl.home (Scott Lurndal) writes:

> sa.sa_flags = SA_ONSTACK;
> sa.sigaction = catch_sigsegv;

I'd risk

sa.sa_flags = SA_ONSTACK | SA_SIGINFO;
sa.sa_sigaction = catch_sigsegv;

Cheers,
lacos
From: Scott Lurndal on
lacos(a)ludens.elte.hu (Ersek, Laszlo) writes:
>In article <x954n.11461$0X.9105(a)news.usenetserver.com>, scott(a)slp53.sl.home (Scott Lurndal) writes:
>
>> sa.sa_flags = SA_ONSTACK;
>> sa.sigaction = catch_sigsegv;
>
>I'd risk
>
> sa.sa_flags = SA_ONSTACK | SA_SIGINFO;
> sa.sa_sigaction = catch_sigsegv;
>
>Cheers,
>lacos

yes, good point (although the sa_sigaction and sa_handler fields are usually in a union,
and it is ok for the implementation to pass the siginfo_t and ucontext_t pointers even when
SA_SIGINFO isn't set.

scott
From: cerr on
On Jan 15, 5:18 pm, la...(a)ludens.elte.hu (Ersek, Laszlo) wrote:
> In article <x954n.11461$0X.9...(a)news.usenetserver.com>, sc...(a)slp53.sl.home (Scott Lurndal) writes:
> >   sa.sa_flags = SA_ONSTACK;
> >   sa.sigaction = catch_sigsegv;
>
> I'd risk
>
>   sa.sa_flags = SA_ONSTACK | SA_SIGINFO;
>   sa.sa_sigaction = catch_sigsegv;

okay, I'll try this asap - maybe even tonight - depending on how my
evening develops ;)
However, why are we not doing a
signal(SIGSEGV, catch_sigsegv);
to catch the signal? Is that cause I'll be missing the stack which I
guess I'll get to keep with this:
ss.ss_sp = malloc(SIGSTKSZ);
assert(ss.ss_sp != NULL);
ss.ss_size = SIGSTKSZ;
ss.ss_flags = 0;
diag = sigaltstack(&ss, NULL);
???
--
roN