2011-11-23 Thomas Klein <th.r.klein@web.de>
[deliverable/binutils-gdb.git] / gdb / stack.c
index 397b345dd25803f5e25f1c13fe07e84ece8f632d..9136daa3f15679ff9385755dc019df00da3a08c9 100644 (file)
@@ -96,6 +96,12 @@ static void print_frame (struct frame_info *frame, int print_level,
                         enum print_what print_what,  int print_args,
                         struct symtab_and_line sal);
 
+static void set_last_displayed_sal (int valid,
+                                   struct program_space *pspace,
+                                   CORE_ADDR addr,
+                                   struct symtab *symtab,
+                                   int line);
+
 /* Zero means do things normally; we are interacting directly with the
    user.  One means print the full filename and linenumber when a
    frame is printed, and do so in a format emacs18/emacs19.22 can
@@ -103,6 +109,14 @@ static void print_frame (struct frame_info *frame, int print_level,
    cases and in a slightly different syntax.  */
 
 int annotation_level = 0;
+
+/* These variables hold the last symtab and line we displayed to the user.
+ * This is where we insert a breakpoint or a skiplist entry by default.  */
+static int last_displayed_sal_valid = 0;
+static struct program_space *last_displayed_pspace = 0;
+static CORE_ADDR last_displayed_addr = 0;
+static struct symtab *last_displayed_symtab = 0;
+static int last_displayed_line = 0;
 \f
 
 /* Return 1 if we should display the address in addition to the location,
@@ -350,8 +364,51 @@ read_frame_arg (struct symbol *sym, struct frame_info *frame,
              if (!value_optimized_out (val)
                  && value_available_contents_eq (val, 0, entryval, 0, len))
                {
-                 entryval = NULL;
-                 val_equal = 1;
+                 /* Initialize it just to avoid a GCC false warning.  */
+                 struct value *val_deref = NULL, *entryval_deref;
+
+                 /* DW_AT_GNU_call_site_value does match with the current
+                    value.  If it is a reference still try to verify if
+                    dereferenced DW_AT_GNU_call_site_data_value does not
+                    differ.  */
+
+                 TRY_CATCH (except, RETURN_MASK_ERROR)
+                   {
+                     unsigned len_deref;
+
+                     val_deref = coerce_ref (val);
+                     if (value_lazy (val_deref))
+                       value_fetch_lazy (val_deref);
+                     len_deref = TYPE_LENGTH (value_type (val_deref));
+
+                     entryval_deref = coerce_ref (entryval);
+                     if (value_lazy (entryval_deref))
+                       value_fetch_lazy (entryval_deref);
+
+                     /* If the reference addresses match but dereferenced
+                        content does not match print them.  */
+                     if (val != val_deref
+                         && value_available_contents_eq (val_deref, 0,
+                                                         entryval_deref, 0,
+                                                         len_deref))
+                       val_equal = 1;
+                   }
+
+                 /* Value was not a reference; and its content matches.  */
+                 if (val == val_deref)
+                   val_equal = 1;
+                 /* If the dereferenced content could not be fetched do not
+                    display anything.  */
+                 else if (except.error == NO_ENTRY_VALUE_ERROR)
+                   val_equal = 1;
+                 else if (except.message)
+                   {
+                     entryval_error = alloca (strlen (except.message) + 1);
+                     strcpy (entryval_error, except.message);
+                   }
+
+                 if (val_equal)
+                   entryval = NULL;
                }
            }
 
@@ -829,9 +886,9 @@ print_frame_info (struct frame_info *frame, int print_level,
       CORE_ADDR pc;
 
       if (get_frame_pc_if_available (frame, &pc))
-       set_default_breakpoint (1, sal.pspace, pc, sal.symtab, sal.line);
+       set_last_displayed_sal (1, sal.pspace, pc, sal.symtab, sal.line);
       else
-       set_default_breakpoint (0, 0, 0, 0, 0);
+       set_last_displayed_sal (0, 0, 0, 0, 0);
     }
 
   annotate_frame_end ();
@@ -839,6 +896,106 @@ print_frame_info (struct frame_info *frame, int print_level,
   gdb_flush (gdb_stdout);
 }
 
+/* Remember the last symtab and line we displayed, which we use e.g.
+ * as the place to put a breakpoint when the `break' command is
+ * invoked with no arguments.  */
+
+static void
+set_last_displayed_sal (int valid, struct program_space *pspace,
+                       CORE_ADDR addr, struct symtab *symtab,
+                       int line)
+{
+  last_displayed_sal_valid = valid;
+  last_displayed_pspace = pspace;
+  last_displayed_addr = addr;
+  last_displayed_symtab = symtab;
+  last_displayed_line = line;
+}
+
+/* Forget the last sal we displayed.  */
+
+void
+clear_last_displayed_sal (void)
+{
+  last_displayed_sal_valid = 0;
+  last_displayed_pspace = 0;
+  last_displayed_addr = 0;
+  last_displayed_symtab = 0;
+  last_displayed_line = 0;
+}
+
+/* Is our record of the last sal we displayed valid?  If not,
+ * the get_last_displayed_* functions will return NULL or 0, as
+ * appropriate.  */
+
+int
+last_displayed_sal_is_valid (void)
+{
+  return last_displayed_sal_valid;
+}
+
+/* Get the pspace of the last sal we displayed, if it's valid.  */
+
+struct program_space *
+get_last_displayed_pspace (void)
+{
+  if (last_displayed_sal_valid)
+    return last_displayed_pspace;
+  return 0;
+}
+
+/* Get the address of the last sal we displayed, if it's valid.  */
+
+CORE_ADDR
+get_last_displayed_addr (void)
+{
+  if (last_displayed_sal_valid)
+    return last_displayed_addr;
+  return 0;
+}
+
+/* Get the symtab of the last sal we displayed, if it's valid.  */
+
+struct symtab*
+get_last_displayed_symtab (void)
+{
+  if (last_displayed_sal_valid)
+    return last_displayed_symtab;
+  return 0;
+}
+
+/* Get the line of the last sal we displayed, if it's valid.  */
+
+int
+get_last_displayed_line (void)
+{
+  if (last_displayed_sal_valid)
+    return last_displayed_line;
+  return 0;
+}
+
+/* Get the last sal we displayed, if it's valid.  */
+
+void
+get_last_displayed_sal (struct symtab_and_line *sal)
+{
+  if (last_displayed_sal_valid)
+    {
+      sal->pspace = last_displayed_pspace;
+      sal->pc = last_displayed_addr;
+      sal->symtab = last_displayed_symtab;
+      sal->line = last_displayed_line;
+    }
+  else
+    {
+      sal->pspace = 0;
+      sal->pc = 0;
+      sal->symtab = 0;
+      sal->line = 0;
+    }
+}
+
+
 /* Attempt to obtain the FUNNAME, FUNLANG and optionally FUNCP of the function
    corresponding to FRAME.  */
 
@@ -1582,7 +1739,7 @@ backtrace_command_1 (char *count_exp, int show_locals, int from_tty)
       enum unwind_stop_reason reason;
 
       reason = get_frame_unwind_stop_reason (trailing);
-      if (reason > UNWIND_FIRST_ERROR)
+      if (reason >= UNWIND_FIRST_ERROR)
        printf_filtered (_("Backtrace stopped: %s\n"),
                         frame_stop_reason_string (reason));
     }
This page took 0.02584 seconds and 4 git commands to generate.