Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 1 Oct 1996 16:16:36 -0400
From:      Garrett Wollman <wollman@lcs.mit.edu>
To:        Julian Elischer <julian@whistle.com>
Cc:        current@FreeBSD.ORG
Subject:   Re: gdb port testing... gdb-4.16 to move into /usr/src soon...
Message-ID:  <9610012016.AA00447@halloran-eldar.lcs.mit.edu>
In-Reply-To: <3251786E.59E2B600@whistle.com>
References:  <9610011420.AA04046@cssmuc.frt.dec.com> <3251786E.59E2B600@whistle.com>

next in thread | previous in thread | raw e-mail | index | archive | help
<<On Tue, 01 Oct 1996 13:00:46 -0700, Julian Elischer <julian@whistle.com> said:

> for me, looking at stack traces on the new one (using the dgb stubs)
> on a running kernel, were not as good on the new one as in the old one..
> I'll try to give examples soon.

I have hacked a bit on the code to make it properly decode special
frames when debugging the kernel.  Patches follow, beware cut&paste
lossage...

-GAWollman

diff -u -r1.1 -r1.7
--- kvm-fbsd.c  1996/09/30 21:04:19     1.1
+++ kvm-fbsd.c  1996/10/01 20:13:15     1.7
@@ -40,6 +40,7 @@
 
 #include <machine/vmparam.h>
 #include <machine/pcb.h>
+#include <machine/frame.h>
 
 static void kcore_files_info PARAMS ((struct target_ops *));
 
@@ -105,6 +106,92 @@
  */
 #define kvread(addr, p) \
        (target_read_memory ((CORE_ADDR)(addr), (char *)(p), sizeof(*(p))))
+
+
+/*
+ * The following is FreeBSD-specific hackery to decode special frames
+ * and elide the assembly-language stub.  This could be made faster by
+ * defining a frame_type field in the machine-dependent frame information,
+ * but we don't think that's too important right now.
+ */
+enum frametype { tf_normal, tf_trap, tf_interrupt, tf_syscall };
+
+CORE_ADDR
+fbsd_kern_frame_saved_pc (fr)
+struct frame_info *fr;
+{
+       struct minimal_symbol *sym;
+       CORE_ADDR this_saved_pc;
+       enum frametype frametype;
+
+       this_saved_pc = read_memory_integer (fr->frame + 4, 4);
+       sym = lookup_minimal_symbol_by_pc (this_saved_pc);
+       frametype = tf_normal;
+       if (sym != NULL) {
+               if (strcmp (SYMBOL_NAME(sym), "calltrap") == 0)
+                       frametype = tf_trap;
+               else if (strncmp (SYMBOL_NAME(sym), "Xresume", 7) == 0)
+                       frametype = tf_interrupt;
+               else if (strcmp (SYMBOL_NAME(sym), "Xsyscall") == 0)
+                       frametype = tf_syscall;
+       }
+
+       switch (frametype) {
+       case tf_normal:
+               return (this_saved_pc);
+
+#define oEIP   offsetof(struct trapframe, tf_eip)
+
+       case tf_trap:
+               return (read_memory_integer (fr->frame + 8 + oEIP, 4));
+
+       case tf_interrupt:
+               return (read_memory_integer (fr->frame + 16 + oEIP, 4));
+
+       case tf_syscall:
+               return (read_memory_integer (fr->frame + 8 + oEIP, 4));
+#undef oEIP
+       }
+}
+
+CORE_ADDR
+fbsd_kern_frame_chain (fr)
+struct frame_info *fr;
+{
+       struct minimal_symbol *sym;
+       CORE_ADDR this_saved_pc;
+       enum frametype frametype;
+
+       this_saved_pc = read_memory_integer (fr->frame + 4, 4);
+       sym = lookup_minimal_symbol_by_pc (this_saved_pc);
+       frametype = tf_normal;
+       if (sym != NULL) {
+               if (strcmp (SYMBOL_NAME(sym), "calltrap") == 0)
+                       frametype = tf_trap;
+               else if (strncmp (SYMBOL_NAME(sym), "Xresume", 7) == 0)
+                       frametype = tf_interrupt;
+               else if (strcmp (SYMBOL_NAME(sym), "_Xsyscall") == 0)
+                       frametype = tf_syscall;
+       }
+
+       switch (frametype) {
+       case tf_normal:
+               return (read_memory_integer (fr->frame, 4));
+
+#define oEBP   offsetof(struct trapframe, tf_ebp)
+
+       case tf_trap:
+               return (read_memory_integer (fr->frame + 8 + oEBP, 4));
+
+       case tf_interrupt:
+               return (read_memory_integer (fr->frame + 16 + oEBP, 4));
+
+       case tf_syscall:
+               return (read_memory_integer (fr->frame + 8 + oEBP, 4));
+#undef oEBP
+       }
+}
+
 
 static CORE_ADDR
 ksym_lookup (name)
diff -u -r1.1 -r1.2
--- tm-fbsd.h   1996/09/30 21:04:48     1.1
+++ tm-fbsd.h   1996/10/01 18:54:36     1.2
@@ -35,4 +35,30 @@
 
 #define IN_SOLIB_CALL_TRAMPOLINE(pc, name) STREQ (name, "_DYNAMIC")
 
+/* FRAME_CHAIN takes a frame's nominal address and produces the frame's
+   chain-pointer.
+   In the case of the i386, the frame's nominal address
+   is the address of a 4-byte word containing the calling frame's address.  */
+
+extern CORE_ADDR fbsd_kern_frame_chain (struct frame_info *);
+#undef FRAME_CHAIN
+#define FRAME_CHAIN(thisframe)  \
+  (kernel_debugging ? fbsd_kern_frame_chain(thisframe) : \
+  ((thisframe)->signal_handler_caller \
+   ? (thisframe)->frame \
+   : (!inside_entry_file ((thisframe)->pc) \
+      ? read_memory_integer ((thisframe)->frame, 4) \
+      : 0)))
+
+/* Saved Pc.  Get it from sigcontext if within sigtramp.  */
+
+extern CORE_ADDR fbsd_kern_frame_saved_pc (struct frame_info *);
+#undef FRAME_SAVED_PC
+#define FRAME_SAVED_PC(FRAME) \
+  (kernel_debugging ? fbsd_kern_frame_saved_pc(FRAME) : \
+  (((FRAME)->signal_handler_caller \
+    ? sigtramp_saved_pc (FRAME) \
+    : read_memory_integer ((FRAME)->frame + 4, 4)) \
+   ))
+
 #endif  /* TM_FBSD_H */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9610012016.AA00447>