Stack unwind through

Paul Flinders paul@dawa.demon.co.uk
Thu Jun 4 13:50:00 GMT 1998


Hi,
    Some time ago I reported a bug in unwinding the stack through
singnal handlers under Linux - basically it doesn't work as shown by
gdb (in this case the 28th may snapshot) trying to do a backtrace from
its own SIGINT handler (note frames 2 and 3).

#0  quit () at utils.c:586
#1  0x80b551b in request_quit (signo=2) at utils.c:699
#2  0xbffff4f8 in ?? ()
#3  0xbffff698 in ?? ()
#4  0x80df56f in rl_read_key () at readline.c:578
#5  0x80df26b in readline_internal () at readline.c:330
#6  0x80df16b in readline (prompt=0x8147998 "(gdb) ") at readline.c:268
#7  0x80b2d98 in command_line_input (prrompt=0x8147998 "(gdb) ", repeat=1, 
    annotation_suffix=0x81122da "prompt") at top.c:2063
#8  0x80b2540 in command_loop () at top.c:1332
#9  0x80b83c9 in main (argc=1, argv=0xbffff948) at main.c:563

The correct stack trace is 
#0  quit () at utils.c:586
#1  0x80b56c7 in request_quit (signo=2) at utils.c:699
#2  <signal handler called>
#3  0x400425a4 in sigprocmask ()
#4  <signal handler called>
#5  0x4008f524 in read ()
#6  0x80df71b in rl_read_key () at readline.c:578
#7  0x80df417 in readline_internal () at readline.c:330
#8  0x80df317 in readline (prompt=0x8147b38 "(gdb) ") at readline.c:268
#9  0x80b2f44 in command_line_input (prrompt=0x8147b38 "(gdb) ", repeat=1, 
    annotation_suffix=0x8112476 "prompt") at top.c:2063
#10 0x80b26ec in command_loop () at top.c:1332
#11 0x80b8575 in main (argc=1, argv=0xbffff948) at main.c:563

I can see that the bug is still present in the current snapshot - can
anyone remember why it wasn't fixed?

There was a problem with the patch I sent uncovering (but *not* AFAICS
causing) a problem with the core file tests but I've deleted the mail
which detailed the problem (unfortunately, perhaps, the tests only
_reported_ failure when the fix to the strack trace is applied).

In case it wasn't kept the patch for the stack trace bug follows..

Paul.

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 1
+
+/* 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 trampolice 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 */




More information about the Gdb-patches mailing list