summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2013-03-09 21:55:18 +0000
committerChristopher Faylor <me@cgf.cx>2013-03-09 21:55:18 +0000
commit56bc657ce470861a61424ed3045b312c6ea0f3d3 (patch)
treed7197035064aa46b92b8103c92ea4d581efdfb08
parent6a375e03253862e982d27d87c10cac618ba9b7f6 (diff)
downloadcygnal-56bc657ce470861a61424ed3045b312c6ea0f3d3.tar.gz
cygnal-56bc657ce470861a61424ed3045b312c6ea0f3d3.tar.bz2
cygnal-56bc657ce470861a61424ed3045b312c6ea0f3d3.zip
* 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.
-rw-r--r--winsup/cygwin/ChangeLog10
-rw-r--r--winsup/cygwin/cygtls.h3
-rw-r--r--winsup/cygwin/exceptions.cc53
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 <me.cygwin2013@cgf.cx>
+
+ * 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 <me.cygwin2013@cgf.cx>
* 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);
}