* blockframe.c (frameless_look_for_prologue): Mark frames
authorPeter Schauer <Peter.Schauer@mytum.de>
Sat, 18 Jan 1997 10:33:06 +0000 (10:33 +0000)
committerPeter Schauer <Peter.Schauer@mytum.de>
Sat, 18 Jan 1997 10:33:06 +0000 (10:33 +0000)
with a zero PC as frameless to improve backtraces from core dumps
caused by dereferencing a NULL function pointer.

gdb/ChangeLog
gdb/blockframe.c

index a3fce8028577af6a543f1c3b5cb989072f383c5d..ca9b19938aeaac3bb8c92a8de07d77b6c24522ff 100644 (file)
@@ -1,3 +1,9 @@
+Sat Jan 18 02:31:29 1997  Peter Schauer  (pes@regent.e-technik.tu-muenchen.de)
+
+       * blockframe.c (frameless_look_for_prologue):  Mark frames
+       with a zero PC as frameless to improve backtraces from core dumps
+       caused by dereferencing a NULL function pointer.
+
 Thu Jan 16 14:10:41 1997  Geoffrey Noer  <noer@cygnus.com>
 
        * config/mn10300/tm-mn10300.h: fix BREAKPOINT definition
index de2a30be7362d50eee0eb59ae6a0c3b4f993ed55..bcc9e0ff5a6764e869de6d54e7e6de21c0563597 100644 (file)
@@ -1,6 +1,6 @@
 /* Get info from stack frames;
    convert between frames, blocks, functions and pc values.
-   Copyright 1986, 1987, 1988, 1989, 1991, 1994, 1995, 1996
+   Copyright 1986, 1987, 1988, 1989, 1991, 1994, 1995, 1996, 1997
              Free Software Foundation, Inc.
 
 This file is part of GDB.
@@ -260,6 +260,12 @@ frameless_look_for_prologue (frame)
 #endif
       return after_prologue == func_start;
     }
+  else if (frame->pc == 0)
+    /* A frame with a zero PC is usually created by dereferencing a NULL
+       function pointer, normally causing an immediate core dump of the
+       inferior. Mark function as frameless, as the inferior has no chance
+       of setting up a stack frame.  */
+    return 1;
   else
     /* If we can't find the start of the function, we don't really
        know whether the function is frameless, but we should be able
@@ -850,20 +856,23 @@ sigtramp_saved_pc (frame)
 }
 #endif /* SIGCONTEXT_PC_OFFSET */
 
+#ifdef USE_GENERIC_DUMMY_FRAMES
+
 /*
- * DUMMY FRAMES
+ * GENERIC DUMMY FRAMES
  * 
  * The following code serves to maintain the dummy stack frames for
  * inferior function calls (ie. when gdb calls into the inferior via
  * call_function_by_hand).  This code saves the machine state before 
- * the call in host memory, so it must maintain an independant stack 
+ * the call in host memory, so we must maintain an independant stack 
  * and keep it consistant etc.  I am attempting to make this code 
  * generic enough to be used by many targets.
  *
  * The cheapest and most generic way to do CALL_DUMMY on a new target
  * is probably to define CALL_DUMMY to be empty, CALL_DUMMY_LENGTH to zero,
  * and CALL_DUMMY_LOCATION to AT_ENTRY.  Then you must remember to define
- * PUSH_RETURN_ADDRESS, because there won't be a call instruction to do it.
+ * PUSH_RETURN_ADDRESS, because no call instruction will be being
+ * executed by the target.
  */
 
 static struct dummy_frame *dummy_frame_stack = NULL;
@@ -878,51 +887,16 @@ generic_find_dummy_frame (pc, fp)
      CORE_ADDR fp;
 {
   struct dummy_frame * dummyframe;
-#ifdef NEED_TEXT_START_END
-  CORE_ADDR bkpt_address;
-  extern CORE_ADDR text_end;
-#endif
 
-#if CALL_DUMMY_LOCATION == AT_ENTRY_POINT
   if (pc != entry_point_address ())
     return 0;
-#endif /* AT_ENTRY_POINT */
-
-#if CALL_DUMMY_LOCATION == BEFORE_TEXT_END
-  bkpt_address = text_end - CALL_DUMMY_LENGTH + CALL_DUMMY_BREAKPOINT_OFFSET;
-  if (pc != bkpt_address)
-    return 0;
-#endif /* BEFORE_TEXT_END */
-
-#if CALL_DUMMY_LOCATION == AFTER_TEXT_END
-  bkpt_address = text_end + CALL_DUMMY_BREAKPOINT_OFFSET;
-  if (pc != bkpt_address)
-    return 0;
-#endif /* AFTER_TEXT_END */
-
-#if CALL_DUMMY_LOCATION == ON_STACK
-  /* compute the displacement from the CALL_DUMMY breakpoint 
-     to the frame pointer */
-  if (1 INNER_THAN 2)
-    pc += CALL_DUMMY_LENGTH - CALL_DUMMY_BREAKPOINT_OFFSET;
-  else
-    pc += CALL_DUMMY_BREAKPOINT_OFFSET;
-#endif /* ON_STACK */
 
   for (dummyframe = dummy_frame_stack; dummyframe != NULL;
        dummyframe = dummyframe->next)
     if (fp == dummyframe->fp || fp == dummyframe->sp)
-      {
-       /* The frame in question lies between the saved fp and sp, inclusive */
-#if CALL_DUMMY_LOCATION == ON_STACK
-       /* NOTE: a better way to do this might be simply to test whether 
-          the pc lies between the saved (sp, fp) and CALL_DUMMY_LENGTH.
-          */
-
-       if (pc == dummyframe->fp || pc == dummyframe->sp)
-#endif /* ON_STACK */
-         return dummyframe->regs;
-      }
+      /* The frame in question lies between the saved fp and sp, inclusive */
+      return dummyframe->regs;
+
   return 0;
 }
 
@@ -1020,11 +994,9 @@ generic_frame_chain_valid (fp, fi)
      CORE_ADDR fp;
      struct frame_info *fi;
 {
-#if CALL_DUMMY_LOCATION == AT_ENTRY_POINT
   if (PC_IN_CALL_DUMMY(FRAME_SAVED_PC(fi), fp, fp))
     return 1;   /* don't prune CALL_DUMMY frames */
   else          /* fall back to default algorithm (see frame.h) */
-#endif
     return (fp != 0 && !inside_entry_file (FRAME_SAVED_PC(fi)));
 }
  
@@ -1126,6 +1098,7 @@ generic_get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
   if (raw_buffer)
     read_register_gen (regnum, raw_buffer);
 }
+#endif /* USE_GENERIC_DUMMY_FRAMES */
 
 void
 _initialize_blockframe ()