This is the mail archive of the gdb@sourceware.cygnus.com mailing list for the GDB project. See the GDB home page for more information.


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

Backtrace through signal handlers for Linux



Well it's ages since I sent anything to gdb-patches  I hope that
someone's still listening!

GDB (971126 snapshot, presumably earlier versions) doesn't unwind the
stack correctly through signal handler invocations - the following
patch corrects things


diff -r -u orig/gdb-971126/gdb/ChangeLog gdb-971126/gdb/ChangeLog
--- orig/gdb-971126/gdb/ChangeLog	Wed Nov 26 16:48:11 1997
+++ gdb-971126/gdb/ChangeLog	Sun Jan 18 16:21:34 1998
@@ -1,3 +1,8 @@
+1998-01-18  Paul Flinders  <paul@dawa.demon.co.uk>
+
+	* config/i386/tm-linux.h(IN_SIGTRAMP, FRAME_SAVED_PC) Add support
+ 	for correctly unwinding through Linux signal handlers
+
 Wed Nov 26 09:59:47 1997  Andrew Cagney  <cagney@b1.cygnus.com>
 
 	* dwarf2read.c (struct comp_unit_head): Change length and
diff -r -u orig/gdb-971126/gdb/config/i386/tm-linux.h gdb-971126/gdb/config/i386/tm-linux.h
--- orig/gdb-971126/gdb/config/i386/tm-linux.h	Wed Nov 26 16:28:29 1997
+++ gdb-971126/gdb/config/i386/tm-linux.h	Sun Jan 18 16:18:14 1998
@@ -25,15 +25,39 @@
 
 #include "i386/tm-i386.h"
 
-/* Offset to saved PC in sigcontext, from <linux/signal.h>.  */
-#define SIGCONTEXT_PC_OFFSET 38
-
 /* We need this file for the SOLIB_TRAMPOLINE stuff. */
 
 #include "tm-sysv4.h"
 
 /* The following works around a problem with /usr/include/sys/procfs.h  */
 #define sys_quotactl
+
+/* Linux calls signal handlers as handler(int signo, struct sigcontext sc)
+   rather than the bsd style of (int signo, int code, struct sigcontext *sc) so
+   the default sigtramp_saved_pc in blockframe.c doesn't work. Also there's no
+   sigtramp function - a return trampoline is placed in the stack by the kernel.
+
+   So we detect the trampoline by disassembling the code and replace the
+   version of FRAME_SAVED_PC from i386/tm-i386.h with the one below. We use the
+   fact that the return trampoline immediately follows the sigcontext structure
+   in memory to get the location of the saved PC */
+   
+#define IN_SIGTRAMP(pc, name) \
+    (read_memory_unsigned_integer (pc, 1) == 0x58      /* popl   %eax      */ \
+     && read_memory_unsigned_integer (pc+1, 1) == 0xb8 /* movl   $,eax     */ \
+     && read_memory_unsigned_integer (pc+2, 4) == 0x77 /* $= 0x77 (sigret) */ \
+     && read_memory_unsigned_integer (pc+6, 2) == 0x80cd) /* int 80 */
+
+#undef FRAME_SAVED_PC
+
+/* Saved Pc.  Get it from sigcontext if within sigtramp.  */
+#define FRAME_SAVED_PC(FRAME) \
+  (((FRAME)->signal_handler_caller \
+    ? read_memory_integer ((FRAME)->pc - 32, 4) \
+    : read_memory_integer ((FRAME)->frame + 4, 4)) \
+   )
+
+
 
 
 #endif  /* #ifndef TM_LINUX_H */