On Fri, May 6, 2011 at 3:24 AM, David Daney <dda...@caviumnetworks.com> wrote:
> Consider this program under GNU/Linux (x86_64):
>
> ------------- np.c -------------------
> #include <cstdio>
> #include <csignal>
> #include <cstring>
> #include <cstdlib>
>
> static void handler(int sig)
> {
>  printf("got signal %d\n", sig);
>  throw 1;
> }
>
> int (*my_vector)(int);
>
> int *bar;
>
> int main(int argc, char *argv[])
> {
>  struct sigaction sa;
>  memset(&sa, 0, sizeof(sa));
>
>  sa.sa_handler = handler;
>  sa.sa_flags = SA_RESTART;
>  sigemptyset(&sa.sa_mask);
>
>  int rv = sigaction(SIGSEGV, &sa, NULL);
>  if (rv) {
>    perror("sigaction failed");
>    exit(1);
>  }
>
>  try {
>    //*bar = 6;
>    rv = my_vector(0);
>  } catch (int c) {
>    printf("I cought %d\n", c);
>    exit(0);
>  }
>
>  printf("No exception\n");
>  return 0;
> }
> ------------------8<---------------------
>
> $ g++ -fnon-call-exceptions -o np np.cc
> $ ./np
> got signal 11
> terminate called after throwing an instance of 'int'
> Aborted (core dumped)
>
>
> However if we uncomment the '//*bar = 6;' line we get:
>
> $ ./np
> got signal 11
> I cought 1
>
> This happens because the libgcc unwinder cannot find unwinding information
> for the PC at the point of the SIGSEGV.
>
> However, we know that usually when we end up with a PC of zero, it is
> because we called through a NULL function pointer.  In this case, we could
> use the return address (perhaps with a slight adjustment to compensate for
> the call instruction) to do the unwinding.
>
> Would it make any sense to build something like this into libgcc?
>
> Or if we want to do this do we need to patch up the register state before
> executing the throw?

What happens if the indirect call is optimized to a jump via tailcall
optimization?  We'd bogously skip one function then, no?

Richard.

> David Daney
>

Reply via email to