This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[rfc] Work around function epilogues in update_watchpoint
- From: "Ulrich Weigand" <uweigand at de dot ibm dot com>
- To: gdb-patches at sourceware dot org
- Date: Thu, 17 Feb 2011 17:24:07 +0100 (CET)
- Subject: [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