From 56bc657ce470861a61424ed3045b312c6ea0f3d3 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Sat, 9 Mar 2013 21:55:18 +0000 Subject: [PATCH] * cygtls.h (_cygtls::signal_debugger): Change argument type. (_cygtls::copy_context): Delete declaration. * exceptions.cc (exception::handle): Don't call copy_context() here. Move signal_handler call earlier and always call it. (_cygtls::copy_context): Delete definition. (_cygtls::signal_debugger): Move copy_context logic here. Suspend thread receiving signal before gathering context information. --- winsup/cygwin/ChangeLog | 10 +++++++ winsup/cygwin/cygtls.h | 3 +-- winsup/cygwin/exceptions.cc | 53 ++++++++++++++++++++++--------------- 3 files changed, 42 insertions(+), 24 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 17746b3d2..8404c33a3 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,13 @@ +2013-03-09 Christopher Faylor + + * cygtls.h (_cygtls::signal_debugger): Change argument type. + (_cygtls::copy_context): Delete declaration. + * exceptions.cc (exception::handle): Don't call copy_context() here. + Move signal_handler call earlier and always call it. + (_cygtls::copy_context): Delete definition. + (_cygtls::signal_debugger): Move copy_context logic here. Suspend + thread receiving signal before gathering context information. + 2013-03-08 Christopher Faylor * spawn.cc (child_info_spawn::worker): Save and restore my_wr_proc_pipe diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h index a5b622111..5ddb9e199 100644 --- a/winsup/cygwin/cygtls.h +++ b/winsup/cygwin/cygtls.h @@ -219,8 +219,7 @@ public: void __reg3 interrupt_setup (siginfo_t&, void *, struct sigaction&); bool inside_kernel (CONTEXT *); - void __reg2 copy_context (CONTEXT *); - void __reg2 signal_debugger (int); + void __reg2 signal_debugger (siginfo_t&); #ifdef CYGTLS_HANDLE operator HANDLE () const {return tid ? tid->win32_obj_id : NULL;} diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 4b424715d..987bb4d44 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -606,8 +606,6 @@ exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void break; } - me.copy_context (in); - /* Temporarily replace windows top level SEH with our own handler. We don't want any Windows magic kicking in. This top level frame will be removed automatically after our exception handler returns. */ @@ -1162,6 +1160,10 @@ sigpacket::process () sigproc_printf ("using tls %p", tls); } + /* Do stuff for gdb */ + if ((HANDLE) *tls) + tls->signal_debugger (si); + void *handler = have_execed ? NULL : (void *) thissig.sa_handler; if (handler == SIG_IGN) @@ -1233,18 +1235,6 @@ dosig: } dispatch_sig: - /* Do stuff for gdb */ - if (si.si_code == SI_USER || !si.si_cyg) - { - CONTEXT c; - c.ContextFlags = CONTEXT_FULL; - GetThreadContext (hMainThread, &c); - _my_tls.copy_context (&c); - - /* Tell gdb that we got a signal. Presumably, gdb already noticed this - if we hit an exception. */ - _my_tls.signal_debugger (si.si_signo); - } if (have_execed) { sigproc_printf ("terminating captive process"); @@ -1312,18 +1302,37 @@ _cygtls::call_signal_handler () } void -_cygtls::copy_context (CONTEXT *c) -{ - memcpy (&thread_context, c, (&thread_context._internal - (unsigned char *) &thread_context)); -} - -void -_cygtls::signal_debugger (int sig) +_cygtls::signal_debugger (siginfo_t& si) { + HANDLE th = NULL; if (isinitialized () && being_debugged ()) { + CONTEXT c; + CONTEXT *pc; + + if (si.si_cyg) + pc = ((cygwin_exception *) si.si_cyg)->context (); + else if (!(th = (HANDLE) *this)) + return; + else + { + SuspendThread (th); + c.ContextFlags = CONTEXT_FULL; + if (GetThreadContext (th, &c)) + pc = &c; + else + goto out; + if (incyg) + c.Eip = retaddr (); + } + memcpy (&thread_context, pc, (&thread_context._internal - + (unsigned char *) &thread_context)); char sigmsg[2 * sizeof (_CYGWIN_SIGNAL_STRING " ffffffff ffffffff")]; - __small_sprintf (sigmsg, _CYGWIN_SIGNAL_STRING " %d %p %p", sig, thread_id, &thread_context); + __small_sprintf (sigmsg, _CYGWIN_SIGNAL_STRING " %d %p %p", si.si_signo, + thread_id, &thread_context); OutputDebugString (sigmsg); } +out: + if (th) + ResumeThread (th); }