This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[rfc] Work around function epilogues in update_watchpoint


Hello,

while testing the new hardware watchpoint support on ARM, I ran into
test case regressions with the recurse.exp test.  It turned out that
update_watchpoint was being called and attempted to recreate the
locations for a frame-related hardware watchpoint, but since the PC
happened to be in a function epilogue, the frame unwinders didn't
work correctly and update_watchpoint was unable to find the frame
where the watchpoint is defined.

This happens only if you have both a hardware watchpoint, *and* a
software watchpoint (which causes single-stepping the whole program
including epilogues).  This happens on arm since we only support
a single hardware watchpoint right now.

Now there is a similar problem in watchpoint_check, which has long
been worked around by calling gdbarch_in_function_epilogue_p.
However, no similar workaround exists in update_watchpoint  (this
is probably because all platforms that needed the epilogue work-
around so far have not supported any hardware watchpoints at all).

The patch below adds such a work-around in update_watchpoint
as well, which fixes the problem on ARM for me.

Also tested without regressions on i386-linux.

Any comments?  I'm planning on committing this in a couple of days.

Bye,
Ulrich


ChangeLog:

	* breakpoint.c (update_watchpoint): Do not attempt to recreate
	per-frame locations while within a function epilogue.

Index: gdb/breakpoint.c
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.c,v
retrieving revision 1.536
diff -u -p -r1.536 breakpoint.c
--- gdb/breakpoint.c	15 Feb 2011 21:43:25 -0000	1.536
+++ gdb/breakpoint.c	17 Feb 2011 16:07:53 -0000
@@ -1374,11 +1374,6 @@ update_watchpoint (struct breakpoint *b,
   if (!watchpoint_in_thread_scope (b))
     return;
 
-  /* We don't free locations.  They are stored in the bp_location array
-     and update_global_location_list will eventually delete them and
-     remove breakpoints if needed.  */
-  b->loc = NULL;
-
   if (b->disposition == disp_del_at_next_stop)
     return;
  
@@ -1389,7 +1384,15 @@ update_watchpoint (struct breakpoint *b,
     within_current_scope = 1;
   else
     {
-      struct frame_info *fi;
+      struct frame_info *fi = get_current_frame ();
+      struct gdbarch *frame_arch = get_frame_arch (fi);
+      CORE_ADDR frame_pc = get_frame_pc (fi);
+
+      /* If we're in a function epilogue, unwinding may not work
+	 properly, so do not attempt to recreate locations at this
+	 point.  See similar comments in watchpoint_check.  */
+      if (gdbarch_in_function_epilogue_p (frame_arch, frame_pc))
+	return;
 
       /* Save the current frame's ID so we can restore it after
          evaluating the watchpoint expression on its own frame.  */
@@ -1405,6 +1408,11 @@ update_watchpoint (struct breakpoint *b,
 	select_frame (fi);
     }
 
+  /* We don't free locations.  They are stored in the bp_location array
+     and update_global_location_list will eventually delete them and
+     remove breakpoints if needed.  */
+  b->loc = NULL;
+
   if (within_current_scope && reparse)
     {
       char *s;
-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]