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]

Re: [PATCH] Allow writing to registers before the program starts


On Wed, May 03, 2006 at 03:02:43PM +0100, Andrew STUBBS wrote:
> Reverting the valops.c portion of this patch solves the problem for me. 
> I have tested it and it produced no regressions.
> 
> Ok to apply the attached reversion?

No, this patch is incorrect.  I don't recall exactly why, but I think
it will mess up writing to the saved registers after using "up".
I happen to know the actual cause of the problem you're trying to
fix; there's a nasty hack in CodeSourcery's branch to fix it, but
the real fix is more work than I've had time for yet.  It's a
representation problem.

As a starting point, here's my fix for the same problem:

Index: frame.c
===================================================================
RCS file: /cvs/src/src/gdb/frame.c,v
retrieving revision 1.211
diff -u -p -r1.211 frame.c
--- frame.c	17 Dec 2005 22:33:59 -0000	1.211
+++ frame.c	2 Apr 2006 02:31:24 -0000
@@ -395,16 +395,26 @@ frame_find_by_id (struct frame_id id)
 {
   struct frame_info *frame;
 
+#if 0
   /* ZERO denotes the null frame, let the caller decide what to do
      about it.  Should it instead return get_current_frame()?  */
   if (!frame_id_p (id))
     return NULL;
+#endif
 
   for (frame = get_current_frame ();
        frame != NULL;
        frame = get_prev_frame (frame))
     {
       struct frame_id this = get_frame_id (frame);
+#if 1
+      /* We use an invalid frame id to mean "could not unwind from
+	 here"!  This hack fixes the "value being assigned to is
+	 no longer active" problem.  This strongly suggests that
+	 we need to change the representation.  */
+      if (!frame_id_p (id) && !frame_id_p (this))
+	return frame;
+#endif
       if (frame_id_eq (id, this))
 	/* An exact match.  */
 	return frame;


Basically, the problem comes about because we signal the end of the
stack by returning an invalid frame ID from ->this_id in the unwinder.
But we also use invalid IDs in various places to mean "no frame at all"
or "no frame in particular".  I think this causes trouble in other
places as well.  For instance you can't use outer/inner on the ID of
the last frame.

Sometimes, we don't have any idea what ID to use for the last frame. We
use the null ID in that case.  This is somewhat reasonable, but could
be problematic - we can't tell it apart from a completely different
frame that we can't unwind either.  The opposite could also be
problematic; using $sp might mean the frame ID changes unexpectedly
when we're within the same logical frame.  Maybe use a different
sentinal ID than the current one.

But it's the other case that I find more interesting.  A lot of the
times we know exactly what this frame's ID is, but have made a
conscious decision to stop unwinding (e.g. because the next frame's
stack pointer would be a sentinel value).  If we had a different
way to signal "stop unwinding here" but return a valid ID... I think
much of this awkwardness would go away.

-- 
Daniel Jacobowitz
CodeSourcery


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