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 >