Teach the testsuite that GDBserver reliably reports program exits.
[deliverable/binutils-gdb.git] / gdb / frame.c
index a817e4d6eb8b75d240f3a34b41592b65e5e7dd2e..eace738903fedb47d857f73c9652880d5fff673e 100644 (file)
@@ -1,8 +1,6 @@
 /* Cache and manage frames for GDB, the GNU debugger.
 
-   Copyright (C) 1986, 1987, 1989, 1991, 1994, 1995, 1996, 1998, 2000, 2001,
-   2002, 2003, 2004, 2007, 2008, 2009, 2010, 2011
-   Free Software Foundation, Inc.
+   Copyright (C) 1986-2013 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -44,7 +42,8 @@
 #include "gdbthread.h"
 #include "block.h"
 #include "inline-frame.h"
-#include  "tracepoint.h"
+#include "tracepoint.h"
+#include "hashtab.h"
 
 static struct frame_info *get_prev_frame_1 (struct frame_info *this_frame);
 static struct frame_info *get_prev_frame_raw (struct frame_info *this_frame);
@@ -130,43 +129,112 @@ struct frame_info
   enum unwind_stop_reason stop_reason;
 };
 
-/* A frame stash used to speed up frame lookups.  */
+/* A frame stash used to speed up frame lookups.  Create a hash table
+   to stash frames previously accessed from the frame cache for
+   quicker subsequent retrieval.  The hash table is emptied whenever
+   the frame cache is invalidated.  */
 
-/* We currently only stash one frame at a time, as this seems to be
-   sufficient for now.  */
-static struct frame_info *frame_stash = NULL;
+static htab_t frame_stash;
 
-/* Add the following FRAME to the frame stash.  */
+/* Internal function to calculate a hash from the frame_id addresses,
+   using as many valid addresses as possible.  Frames below level 0
+   are not stored in the hash table.  */
+
+static hashval_t
+frame_addr_hash (const void *ap)
+{
+  const struct frame_info *frame = ap;
+  const struct frame_id f_id = frame->this_id.value;
+  hashval_t hash = 0;
+
+  gdb_assert (f_id.stack_addr_p || f_id.code_addr_p
+             || f_id.special_addr_p);
+
+  if (f_id.stack_addr_p)
+    hash = iterative_hash (&f_id.stack_addr,
+                          sizeof (f_id.stack_addr), hash);
+  if (f_id.code_addr_p)
+    hash = iterative_hash (&f_id.code_addr,
+                          sizeof (f_id.code_addr), hash);
+  if (f_id.special_addr_p)
+    hash = iterative_hash (&f_id.special_addr,
+                          sizeof (f_id.special_addr), hash);
+
+  return hash;
+}
+
+/* Internal equality function for the hash table.  This function
+   defers equality operations to frame_id_eq.  */
+
+static int
+frame_addr_hash_eq (const void *a, const void *b)
+{
+  const struct frame_info *f_entry = a;
+  const struct frame_info *f_element = b;
+
+  return frame_id_eq (f_entry->this_id.value,
+                     f_element->this_id.value);
+}
+
+/* Internal function to create the frame_stash hash table.  100 seems
+   to be a good compromise to start the hash table at.  */
+
+static void
+frame_stash_create (void)
+{
+  frame_stash = htab_create (100,
+                            frame_addr_hash,
+                            frame_addr_hash_eq,
+                            NULL);
+}
+
+/* Internal function to add a frame to the frame_stash hash table.  Do
+   not store frames below 0 as they may not have any addresses to
+   calculate a hash.  */
 
 static void
 frame_stash_add (struct frame_info *frame)
 {
-  frame_stash = frame;
+  /* Do not stash frames below level 0.  */
+  if (frame->level >= 0)
+    {
+      struct frame_info **slot;
+
+      slot = (struct frame_info **) htab_find_slot (frame_stash,
+                                                   frame,
+                                                   INSERT);
+      *slot = frame;
+    }
 }
 
-/* Search the frame stash for an entry with the given frame ID.
-   If found, return that frame.  Otherwise return NULL.  */
+/* Internal function to search the frame stash for an entry with the
+   given frame ID.  If found, return that frame.  Otherwise return
+   NULL.  */
 
 static struct frame_info *
 frame_stash_find (struct frame_id id)
 {
-  if (frame_stash && frame_id_eq (frame_stash->this_id.value, id))
-    return frame_stash;
+  struct frame_info dummy;
+  struct frame_info *frame;
 
-  return NULL;
+  dummy.this_id.value = id;
+  frame = htab_find (frame_stash, &dummy);
+  return frame;
 }
 
-/* Invalidate the frame stash by removing all entries in it.  */
+/* Internal function to invalidate the frame stash by removing all
+   entries in it.  This only occurs when the frame cache is
+   invalidated.  */
 
 static void
 frame_stash_invalidate (void)
 {
-  frame_stash = NULL;
+  htab_empty (frame_stash);
 }
 
 /* Flag to control debugging.  */
 
-int frame_debug;
+unsigned int frame_debug;
 static void
 show_frame_debug (struct ui_file *file, int from_tty,
                  struct cmd_list_element *c, const char *value)
@@ -197,7 +265,7 @@ show_backtrace_past_entry (struct ui_file *file, int from_tty,
                    value);
 }
 
-static int backtrace_limit = INT_MAX;
+static unsigned int backtrace_limit = UINT_MAX;
 static void
 show_backtrace_limit (struct ui_file *file, int from_tty,
                      struct cmd_list_element *c, const char *value)
@@ -227,8 +295,8 @@ fprint_frame_id (struct ui_file *file, struct frame_id id)
   fprint_field (file, "code", id.code_addr_p, id.code_addr);
   fprintf_unfiltered (file, ",");
   fprint_field (file, "special", id.special_addr_p, id.special_addr);
-  if (id.inline_depth)
-    fprintf_unfiltered (file, ",inlined=%d", id.inline_depth);
+  if (id.artificial_depth)
+    fprintf_unfiltered (file, ",artificial=%d", id.artificial_depth);
   fprintf_unfiltered (file, "}");
 }
 
@@ -246,8 +314,8 @@ fprint_frame_type (struct ui_file *file, enum frame_type type)
     case INLINE_FRAME:
       fprintf_unfiltered (file, "INLINE_FRAME");
       return;
-    case SENTINEL_FRAME:
-      fprintf_unfiltered (file, "SENTINEL_FRAME");
+    case TAILCALL_FRAME:
+      fprintf_unfiltered (file, "TAILCALL_FRAME");
       return;
     case SIGTRAMP_FRAME:
       fprintf_unfiltered (file, "SIGTRAMP_FRAME");
@@ -255,6 +323,9 @@ fprint_frame_type (struct ui_file *file, enum frame_type type)
     case ARCH_FRAME:
       fprintf_unfiltered (file, "ARCH_FRAME");
       return;
+    case SENTINEL_FRAME:
+      fprintf_unfiltered (file, "SENTINEL_FRAME");
+      return;
     default:
       fprintf_unfiltered (file, "<unknown type>");
       return;
@@ -304,13 +375,15 @@ fprint_frame (struct ui_file *file, struct frame_info *fi)
   fprintf_unfiltered (file, "}");
 }
 
-/* Given FRAME, return the enclosing normal frame for inlined
-   function frames.  Otherwise return the original frame.  */
+/* Given FRAME, return the enclosing frame as found in real frames read-in from
+   inferior memory.  Skip any previous frames which were made up by GDB.
+   Return the original frame if no immediate previous frames exist.  */
 
 static struct frame_info *
-skip_inlined_frames (struct frame_info *frame)
+skip_artificial_frames (struct frame_info *frame)
 {
-  while (get_frame_type (frame) == INLINE_FRAME)
+  while (get_frame_type (frame) == INLINE_FRAME
+        || get_frame_type (frame) == TAILCALL_FRAME)
     frame = get_prev_frame (frame);
 
   return frame;
@@ -345,17 +418,16 @@ get_frame_id (struct frame_info *fi)
          fprint_frame_id (gdb_stdlog, fi->this_id.value);
          fprintf_unfiltered (gdb_stdlog, " }\n");
        }
+      frame_stash_add (fi);
     }
 
-  frame_stash_add (fi);
-
   return fi->this_id.value;
 }
 
 struct frame_id
 get_stack_frame_id (struct frame_info *next_frame)
 {
-  return get_frame_id (skip_inlined_frames (next_frame));
+  return get_frame_id (skip_artificial_frames (next_frame));
 }
 
 struct frame_id
@@ -368,10 +440,10 @@ frame_unwind_caller_id (struct frame_info *next_frame)
      returning a null_frame_id (e.g., when a caller requests the frame
      ID of "main()"s caller.  */
 
-  next_frame = skip_inlined_frames (next_frame);
+  next_frame = skip_artificial_frames (next_frame);
   this_frame = get_prev_frame_1 (next_frame);
   if (this_frame)
-    return get_frame_id (skip_inlined_frames (this_frame));
+    return get_frame_id (skip_artificial_frames (this_frame));
   else
     return null_frame_id;
 }
@@ -436,12 +508,12 @@ frame_id_p (struct frame_id l)
 }
 
 int
-frame_id_inlined_p (struct frame_id l)
+frame_id_artificial_p (struct frame_id l)
 {
   if (!frame_id_p (l))
     return 0;
 
-  return (l.inline_depth != 0);
+  return (l.artificial_depth != 0);
 }
 
 int
@@ -473,8 +545,8 @@ frame_id_eq (struct frame_id l, struct frame_id r)
     /* An invalid special addr is a wild card (or unused).  Otherwise
        if special addresses are different, the frames are different.  */
     eq = 0;
-  else if (l.inline_depth != r.inline_depth)
-    /* If inline depths are different, the frames must be different.  */
+  else if (l.artificial_depth != r.artificial_depth)
+    /* If artifical depths are different, the frames must be different.  */
     eq = 0;
   else
     /* Frames are equal.  */
@@ -531,7 +603,7 @@ frame_id_inner (struct gdbarch *gdbarch, struct frame_id l, struct frame_id r)
   if (!l.stack_addr_p || !r.stack_addr_p)
     /* Like NaN, any operation involving an invalid ID always fails.  */
     inner = 0;
-  else if (l.inline_depth > r.inline_depth
+  else if (l.artificial_depth > r.artificial_depth
           && l.stack_addr == r.stack_addr
           && l.code_addr_p == r.code_addr_p
           && l.special_addr_p == r.special_addr_p
@@ -707,14 +779,14 @@ frame_unwind_pc (struct frame_info *this_frame)
 CORE_ADDR
 frame_unwind_caller_pc (struct frame_info *this_frame)
 {
-  return frame_unwind_pc (skip_inlined_frames (this_frame));
+  return frame_unwind_pc (skip_artificial_frames (this_frame));
 }
 
 int
 frame_unwind_caller_pc_if_available (struct frame_info *this_frame,
                                     CORE_ADDR *pc)
 {
-  return frame_unwind_pc_if_available (skip_inlined_frames (this_frame), pc);
+  return frame_unwind_pc_if_available (skip_artificial_frames (this_frame), pc);
 }
 
 int
@@ -775,7 +847,7 @@ get_frame_func (struct frame_info *this_frame)
 static enum register_status
 do_frame_register_read (void *src, int regnum, gdb_byte *buf)
 {
-  if (!frame_register_read (src, regnum, buf))
+  if (!deprecated_frame_register_read (src, regnum, buf))
     return REG_UNAVAILABLE;
   else
     return REG_VALID;
@@ -815,6 +887,11 @@ frame_pop (struct frame_info *this_frame)
   if (!prev_frame)
     error (_("Cannot pop the initial frame."));
 
+  /* Ignore TAILCALL_FRAME type frames, they were executed already before
+     entering THISFRAME.  */
+  while (get_frame_type (prev_frame) == TAILCALL_FRAME)
+    prev_frame = get_prev_frame (prev_frame);
+
   /* Make a copy of all the register values unwound from this frame.
      Save them in a scratch buffer so that there isn't a race between
      trying to extract the old values from the current regcache while
@@ -912,6 +989,12 @@ frame_unwind_register (struct frame_info *frame, int regnum, gdb_byte *buf)
 
   frame_register_unwind (frame, regnum, &optimized, &unavailable,
                         &lval, &addr, &realnum, buf);
+
+  if (optimized)
+    error (_("Register %d was optimized out"), regnum);
+  if (unavailable)
+    throw_error (NOT_AVAILABLE_ERROR,
+                _("Register %d is not available"), regnum);
 }
 
 void
@@ -1026,6 +1109,26 @@ get_frame_register_unsigned (struct frame_info *frame, int regnum)
   return frame_unwind_register_unsigned (frame->next, regnum);
 }
 
+int
+read_frame_register_unsigned (struct frame_info *frame, int regnum,
+                             ULONGEST *val)
+{
+  struct value *regval = get_frame_register_value (frame, regnum);
+
+  if (!value_optimized_out (regval)
+      && value_entirely_available (regval))
+    {
+      struct gdbarch *gdbarch = get_frame_arch (frame);
+      enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+      int size = register_size (gdbarch, VALUE_REGNUM (regval));
+
+      *val = extract_unsigned_integer (value_contents (regval), size, byte_order);
+      return 1;
+    }
+
+  return 0;
+}
+
 void
 put_frame_register (struct frame_info *frame, int regnum,
                    const gdb_byte *buf)
@@ -1045,12 +1148,7 @@ put_frame_register (struct frame_info *frame, int regnum,
     {
     case lval_memory:
       {
-       /* FIXME: write_memory doesn't yet take constant buffers.
-           Arrrg!  */
-       gdb_byte tmp[MAX_REGISTER_SIZE];
-
-       memcpy (tmp, buf, register_size (gdbarch, regnum));
-       write_memory (addr, tmp, register_size (gdbarch, regnum));
+       write_memory (addr, buf, register_size (gdbarch, regnum));
        break;
       }
     case lval_register:
@@ -1061,7 +1159,8 @@ put_frame_register (struct frame_info *frame, int regnum,
     }
 }
 
-/* frame_register_read ()
+/* This function is deprecated.  Use get_frame_register_value instead,
+   which provides more accurate information.
 
    Find and return the value of REGNUM for the specified stack frame.
    The number of bytes copied is REGISTER_SIZE (REGNUM).
@@ -1069,7 +1168,7 @@ put_frame_register (struct frame_info *frame, int regnum,
    Returns 0 if the register value could not be found.  */
 
 int
-frame_register_read (struct frame_info *frame, int regnum,
+deprecated_frame_register_read (struct frame_info *frame, int regnum,
                     gdb_byte *myaddr)
 {
   int optimized;
@@ -1190,7 +1289,7 @@ put_frame_register_bytes (struct frame_info *frame, int regnum,
        {
          gdb_byte buf[MAX_REGISTER_SIZE];
 
-         frame_register_read (frame, regnum, buf);
+         deprecated_frame_register_read (frame, regnum, buf);
          memcpy (buf + offset, myaddr, curr_len);
          put_frame_register (frame, regnum, buf);
        }
@@ -1300,8 +1399,8 @@ get_current_frame (void)
     {
       struct frame_info *sentinel_frame =
        create_sentinel_frame (current_program_space, get_current_regcache ());
-      if (catch_exceptions (uiout, unwind_to_current_frame, sentinel_frame,
-                           RETURN_MASK_ERROR) != 0)
+      if (catch_exceptions (current_uiout, unwind_to_current_frame,
+                           sentinel_frame, RETURN_MASK_ERROR) != 0)
        {
          /* Oops! Fake a current frame?  Is this useful?  It has a PC
              of zero, for instance.  */
@@ -1322,17 +1421,21 @@ has_stack_frames (void)
   if (!target_has_registers || !target_has_stack || !target_has_memory)
     return 0;
 
-  /* No current inferior, no frame.  */
-  if (ptid_equal (inferior_ptid, null_ptid))
-    return 0;
+  /* Traceframes are effectively a substitute for the live inferior.  */
+  if (get_traceframe_number () < 0)
+    {
+      /* No current inferior, no frame.  */
+      if (ptid_equal (inferior_ptid, null_ptid))
+       return 0;
 
-  /* Don't try to read from a dead thread.  */
-  if (is_exited (inferior_ptid))
-    return 0;
+      /* Don't try to read from a dead thread.  */
+      if (is_exited (inferior_ptid))
+       return 0;
 
-  /* ... or from a spinning thread.  */
-  if (is_executing (inferior_ptid))
-    return 0;
+      /* ... or from a spinning thread.  */
+      if (is_executing (inferior_ptid))
+       return 0;
+    }
 
   return 1;
 }
@@ -1607,6 +1710,15 @@ get_prev_frame_1 (struct frame_info *this_frame)
   if (get_frame_type (this_frame) == INLINE_FRAME)
     return get_prev_frame_raw (this_frame);
 
+  /* Check that this frame is unwindable.  If it isn't, don't try to
+     unwind to the prev frame.  */
+  this_frame->stop_reason
+    = this_frame->unwind->stop_reason (this_frame,
+                                      &this_frame->prologue_cache);
+
+  if (this_frame->stop_reason != UNWIND_NO_REASON)
+    return NULL;
+
   /* Check that this frame's ID was valid.  If it wasn't, don't try to
      unwind to the prev frame.  Be careful to not apply this test to
      the sentinel frame.  */
@@ -1638,7 +1750,7 @@ get_prev_frame_1 (struct frame_info *this_frame)
       
       /* gcc -fsplit-stack __morestack can continue the stack anywhere.  */
       this_pc_in_block = get_frame_address_in_block (this_frame);
-      morestack_msym = lookup_minimal_symbol_by_pc (this_pc_in_block);
+      morestack_msym = lookup_minimal_symbol_by_pc (this_pc_in_block).minsym;
       if (morestack_msym)
        morestack_name = SYMBOL_LINKAGE_NAME (morestack_msym);
       if (!morestack_name || strcmp (morestack_name, "__morestack") != 0)
@@ -2016,8 +2128,10 @@ get_frame_address_in_block (struct frame_info *this_frame)
   while (get_frame_type (next_frame) == INLINE_FRAME)
     next_frame = next_frame->next;
 
-  if (get_frame_type (next_frame) == NORMAL_FRAME
+  if ((get_frame_type (next_frame) == NORMAL_FRAME
+       || get_frame_type (next_frame) == TAILCALL_FRAME)
       && (get_frame_type (this_frame) == NORMAL_FRAME
+         || get_frame_type (this_frame) == TAILCALL_FRAME
          || get_frame_type (this_frame) == INLINE_FRAME))
     return pc - 1;
 
@@ -2076,6 +2190,8 @@ find_frame_sal (struct frame_info *frame, struct symtab_and_line *sal)
           we can't do much better.  */
        sal->pc = get_frame_pc (frame);
 
+      sal->pspace = get_frame_program_space (frame);
+
       return;
     }
 
@@ -2284,7 +2400,7 @@ frame_unwind_arch (struct frame_info *next_frame)
 struct gdbarch *
 frame_unwind_caller_arch (struct frame_info *next_frame)
 {
-  return frame_unwind_arch (skip_inlined_frames (next_frame));
+  return frame_unwind_arch (skip_artificial_frames (next_frame));
 }
 
 /* Stack pointer methods.  */
@@ -2330,20 +2446,11 @@ frame_stop_reason_string (enum unwind_stop_reason reason)
 {
   switch (reason)
     {
-    case UNWIND_NULL_ID:
-      return _("unwinder did not report frame ID");
-
-    case UNWIND_INNER_ID:
-      return _("previous frame inner to this frame (corrupt stack?)");
+#define SET(name, description) \
+    case name: return _(description);
+#include "unwind_stop_reasons.def"
+#undef SET
 
-    case UNWIND_SAME_ID:
-      return _("previous frame identical to this frame (corrupt stack?)");
-
-    case UNWIND_NO_SAVED_PC:
-      return _("frame did not save the PC");
-
-    case UNWIND_NO_REASON:
-    case UNWIND_FIRST_ERROR:
     default:
       internal_error (__FILE__, __LINE__,
                      "Invalid frame stop reason");
@@ -2416,6 +2523,8 @@ _initialize_frame (void)
 {
   obstack_init (&frame_cache_obstack);
 
+  frame_stash_create ();
+
   observer_attach_target_changed (frame_observer_target_changed);
 
   add_prefix_cmd ("backtrace", class_maintenance, set_backtrace_cmd, _("\
@@ -2455,23 +2564,23 @@ the rest of the stack trace."),
                           &set_backtrace_cmdlist,
                           &show_backtrace_cmdlist);
 
-  add_setshow_integer_cmd ("limit", class_obscure,
-                          &backtrace_limit, _("\
+  add_setshow_uinteger_cmd ("limit", class_obscure,
+                           &backtrace_limit, _("\
 Set an upper bound on the number of backtrace levels."), _("\
 Show the upper bound on the number of backtrace levels."), _("\
 No more than the specified number of frames can be displayed or examined.\n\
-Zero is unlimited."),
-                          NULL,
-                          show_backtrace_limit,
-                          &set_backtrace_cmdlist,
-                          &show_backtrace_cmdlist);
+Literal \"unlimited\" or zero means no limit."),
+                           NULL,
+                           show_backtrace_limit,
+                           &set_backtrace_cmdlist,
+                           &show_backtrace_cmdlist);
 
   /* Debug this files internals.  */
-  add_setshow_zinteger_cmd ("frame", class_maintenance, &frame_debug,  _("\
+  add_setshow_zuinteger_cmd ("frame", class_maintenance, &frame_debug,  _("\
 Set frame debugging."), _("\
 Show frame debugging."), _("\
 When non-zero, frame specific internal debugging is enabled."),
-                           NULL,
-                           show_frame_debug,
-                           &setdebuglist, &showdebuglist);
+                            NULL,
+                            show_frame_debug,
+                            &setdebuglist, &showdebuglist);
 }
This page took 0.056517 seconds and 4 git commands to generate.