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]

[rfa] Be more careful when checking watchpoints


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


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