[rfa] Be more careful when checking watchpoints

Daniel Jacobowitz drow@false.org
Tue Oct 17 19:49:00 GMT 2006


Software watchpoints of local variables are a very hard test of frame
unwinding: you have to be correct in the prologue, in the dynamic linker, in
the epilogue, and so on.  This is one failure case I encountered recently.
It doesn't trigger in mainline GDB, but does in an older one.

We step into a PowerPC GNU/Linux PLT entry.  There's no associated symbol.
The frame ends up with an id of {stack = $sp, code = 0}, which is considered
to match the frame where this was created, which had {stack = $sp, code =
funcaddr} (because code == 0 is a wildcard).  So, we go and try to read the
value of that variable using the current frame.  Eventually, there was a
segfault deep in the dwarf location list code, because the stub frame for
the PLT entry didn't have a frame base.

This is a bit of defensive programming.  If we find a frame with the "same"
ID as the one we're looking for, but it's pointing at a different function,
then assume the unwinding has gotten confused and the watchpoint has gone
out of scope.

Does this look OK?  Tested x86_64-pc-linux-gnu, no regressions.

-- 
Daniel Jacobowitz
CodeSourcery

2006-10-17  Daniel Jacobowitz  <dan@codesourcery.com>

	* breakpoint.c (watchpoint_check): Double-check the found frame.

Index: breakpoint.c
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.c,v
retrieving revision 1.229
diff -u -p -r1.229 breakpoint.c
--- breakpoint.c	8 Aug 2006 21:32:37 -0000	1.229
+++ breakpoint.c	17 Oct 2006 19:43:36 -0000
@@ -2492,6 +2492,13 @@ watchpoint_check (void *p)
       reinit_frame_cache ();
       fr = frame_find_by_id (b->watchpoint_frame);
       within_current_scope = (fr != NULL);
+
+      /* If we've gotten confused in the unwinder, we might have
+	 returned a frame that can't describe this variable.  */
+      if (within_current_scope
+	  && block_function (b->exp_valid_block) != get_frame_function (fr))
+	within_current_scope = 0;
+
       /* in_function_epilogue_p() returns a non-zero value if we're still
 	 in the function but the stack frame has already been invalidated.
 	 Since we can't rely on the values of local variables after the



More information about the Gdb-patches mailing list