This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFC - add a debug hook to the unwinder


I'm interested in making "next-over-throw" do something sensible in
gdb.  In particular, if the user nexts over a throw which is caught in
the "nexting" frame, or above, I'd like gdb to stop at the catch
point.

It seems to me that the simplest way to do this is to add a debugging
hook into the unwinder.

I wrote a prototype of this.  But, before pursuing it further I
thought I'd see if there are any objections to this approach.  I don't
want to invest too much time in this if I'll just have to implement
this a different way.

The appended is not my final patch, but does show the general idea.
The way this is intended to work is that gdb sets _Unwind_DebugCFA to
the target CFA.  Then, if unwinding proceeds past this, the unwinder
sets _Unwind_DebugHandler to the destination PC, and calls
_Unwind_DebugHook.  gdb puts a breakpoint on this function, and when
it is hit, sets another breakpoint based on _Unwind_DebugHandler.

I suppose a similar change would be needed for the IA-64 unwinder.

Tom

Index: unwind-dw2.c
===================================================================
--- unwind-dw2.c	(revision 143873)
+++ unwind-dw2.c	(working copy)
@@ -1,5 +1,5 @@
 /* DWARF2 exception handling and frame unwind runtime interface routines.
-   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
    Free Software Foundation, Inc.
 
    This file is part of GCC.
@@ -1462,17 +1462,38 @@
 }
 
 
+__thread void *_Unwind_DebugCFA;
+__thread void *_Unwind_DebugHandler;
+
+void _Unwind_DebugHook (void) __attribute__ ((__noinline__));
+
+void
+_Unwind_DebugHook (void)
+{
+  _Unwind_DebugCFA = 0;
+}
+
 /* Install TARGET into CURRENT so that we can return to it.  This is a
    macro because __builtin_eh_return must be invoked in the context of
    our caller.  */
 
-#define uw_install_context(CURRENT, TARGET)				 \
-  do									 \
-    {									 \
-      long offset = uw_install_context_1 ((CURRENT), (TARGET));		 \
-      void *handler = __builtin_frob_return_addr ((TARGET)->ra);	 \
-      __builtin_eh_return (offset, handler);				 \
-    }									 \
+#define uw_install_context(CURRENT, TARGET)				\
+  do									\
+    {									\
+      long offset = uw_install_context_1 ((CURRENT), (TARGET));		\
+      void *handler = __builtin_frob_return_addr ((TARGET)->ra);	\
+      void *debug_cfa = _Unwind_DebugCFA;				\
+      if (__builtin_expect (debug_cfa != NULL, 0))			\
+	{								\
+	  if ((STACK_GROWS_DOWNWARD && (TARGET)->cfa >= debug_cfa)	\
+	      || (!STACK_GROWS_DOWNWARD && (TARGET)->cfa <= debug_cfa)) \
+	    {								\
+	      _Unwind_DebugHandler = handler;				\
+	      _Unwind_DebugHook ();					\
+	    }								\
+	}								\
+      __builtin_eh_return (offset, handler);				\
+    }									\
   while (0)
 
 static long


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]