* infrun.c (struct inferior_status): Replace fields
authorAndrew Cagney <cagney@redhat.com>
Mon, 10 Jun 2002 23:25:50 +0000 (23:25 +0000)
committerAndrew Cagney <cagney@redhat.com>
Mon, 10 Jun 2002 23:25:50 +0000 (23:25 +0000)
selected_frame_address and selected_level with field
selected_frame_id.
(save_inferior_status): Update.  Use get_frame_id.
(struct restore_selected_frame_args): Delete.
(restore_selected_frame): Update.  Use frame_find_by_id.
(restore_inferior_status): Update.

* breakpoint.h (struct breakpoint): Change type of
watchpoint_frame to frame_id.
* breakpoint.c (insert_breakpoints): Use frame_find_by_id.  Remove
call to get_current_frame.
(do_enable_breakpoint): Use frame_find_by_id.  Remove call to
get_current_frame.
(watchpoint_check): Use frame_find_by_id.

* frame.h (record_selected_frame): Delete declaration.
* stack.c (record_selected_frame): Delete function.

* frame.h (struct frame_id): Define.
(get_frame_id): Declare.
(frame_find_by_id): Declare.
* frame.c (frame_find_by_id): New function.
(get_frame_id): New function.

gdb/ChangeLog
gdb/breakpoint.c
gdb/breakpoint.h
gdb/frame.c
gdb/frame.h
gdb/infrun.c
gdb/stack.c

index 37b511d3b4e53b56f4cad826473bc26f9ebe49c0..8c3ca23c9951a15bce816b121eb1151e41ceac90 100644 (file)
@@ -1,9 +1,35 @@
+2002-06-10  Andrew Cagney  <ac131313@redhat.com>
+
+       * infrun.c (struct inferior_status): Replace fields
+       selected_frame_address and selected_level with field
+       selected_frame_id.
+       (save_inferior_status): Update.  Use get_frame_id.
+       (struct restore_selected_frame_args): Delete.
+       (restore_selected_frame): Update.  Use frame_find_by_id.
+       (restore_inferior_status): Update.
+
+       * breakpoint.h (struct breakpoint): Change type of
+       watchpoint_frame to frame_id.
+       * breakpoint.c (insert_breakpoints): Use frame_find_by_id.  Remove
+       call to get_current_frame.
+       (do_enable_breakpoint): Use frame_find_by_id.  Remove call to
+       get_current_frame.
+       (watchpoint_check): Use frame_find_by_id.
+
+       * frame.h (record_selected_frame): Delete declaration.
+       * stack.c (record_selected_frame): Delete function.
+       
+       * frame.h (struct frame_id): Define.
+       (get_frame_id): Declare.
+       (frame_find_by_id): Declare.
+       * frame.c (frame_find_by_id): New function.
+       (get_frame_id): New function.
+
 2002-06-10  Andrey Volkov <avolkov@transas.com>
 
        * ser-e7kpc.c: Fix duplicated define and call of 
         _initialize_ser_e7000pc
            
-           
 2002-06-09  Daniel Jacobowitz  <drow@mvista.com>
 
        * signals/signals.c (target_signal_from_host): Fix #ifdef
index 6f604f1961ad8adc6fe76ac892c3eb8b133a6df5..1861370eaa79cd13486c28ade2eb4234b248f65a 100644 (file)
@@ -909,13 +909,7 @@ insert_breakpoints (void)
        else
          {
            struct frame_info *fi;
-
-           /* There might be no current frame at this moment if we are
-              resuming from a step over a breakpoint.
-              Set up current frame before trying to find the watchpoint
-              frame.  */
-           get_current_frame ();
-           fi = find_frame_addr_in_frame_chain (b->watchpoint_frame);
+           fi = frame_find_by_id (b->watchpoint_frame);
            within_current_scope = (fi != NULL);
            if (within_current_scope)
              select_frame (fi);
@@ -2320,7 +2314,7 @@ watchpoint_check (PTR p)
          any chance of handling watchpoints on local variables, we'll need
          the frame chain (so we can determine if we're in scope).  */
       reinit_frame_cache ();
-      fr = find_frame_addr_in_frame_chain (b->watchpoint_frame);
+      fr = frame_find_by_id (b->watchpoint_frame);
       within_current_scope = (fr != NULL);
       /* in_function_epilogue_p() returns a non-zero value if we're still
         in the function but the stack frame has already been invalidated.
@@ -5321,10 +5315,12 @@ watch_command_1 (char *arg, int accessflag, int from_tty)
   if (frame)
     {
       prev_frame = get_prev_frame (frame);
-      b->watchpoint_frame = frame->frame;
+      get_frame_id (frame, &b->watchpoint_frame);
     }
   else
-    b->watchpoint_frame = (CORE_ADDR) 0;
+    {
+      memset (&b->watchpoint_frame, 0, sizeof (b->watchpoint_frame));
+    }
 
   /* If the expression is "local", then set up a "watchpoint scope"
      breakpoint at the point where we've left the scope of the watchpoint
@@ -7266,12 +7262,7 @@ do_enable_breakpoint (struct breakpoint *bpt, enum bpdisp disposition)
       if (bpt->exp_valid_block != NULL)
        {
          struct frame_info *fr =
-
-         /* Ensure that we have the current frame.  Else, this
-            next query may pessimistically be answered as, "No,
-            not within current scope". */
-         get_current_frame ();
-         fr = find_frame_addr_in_frame_chain (bpt->watchpoint_frame);
+         fr = frame_find_by_id (bpt->watchpoint_frame);
          if (fr == NULL)
            {
              printf_filtered ("\
index 3a58aad24876d890f6570534f2ee37b9ff41521d..7ab300ffb65efac794e9500c99558d38da537716 100644 (file)
@@ -270,10 +270,10 @@ struct breakpoint
        it the watchpoint_scope breakpoint or something like that. FIXME).  */
     struct breakpoint *related_breakpoint;
 
-    /* Holds the frame address which identifies the frame this watchpoint
-       should be evaluated in, or NULL if the watchpoint should be evaluated
-       on the outermost frame.  */
-    CORE_ADDR watchpoint_frame;
+    /* Holds the frame address which identifies the frame this
+       watchpoint should be evaluated in, or `null' if the watchpoint
+       should be evaluated on the outermost frame.  */
+    struct frame_id watchpoint_frame;
 
     /* Thread number for thread-specific breakpoint, or -1 if don't care */
     int thread;
index 85de9b83311a2e390699b03c573a4ba6cc690548..5c52ed1a0a2c5e664e26c24e8a3b6b40de87a62c 100644 (file)
 #include "regcache.h"
 #include "gdb_assert.h"
 
+/* Return a frame uniq ID that can be used to, later re-find the
+   frame.  */
+
+void
+get_frame_id (struct frame_info *fi, struct frame_id *id)
+{
+  if (fi == NULL)
+    {
+      id->base = 0;
+      id->pc = 0;
+    }
+  else
+    {
+      id->base = FRAME_FP (fi);
+      id->pc = fi->pc;
+    }
+}
+
+struct frame_info *
+frame_find_by_id (struct frame_id id)
+{
+  struct frame_info *frame;
+
+  /* ZERO denotes the null frame, let the caller decide what to do
+     about it.  Should it instead return get_current_frame()?  */
+  if (id.base == 0 && id.pc == 0)
+    return NULL;
+
+  for (frame = get_current_frame ();
+       frame != NULL;
+       frame = get_prev_frame (frame))
+    {
+      if (INNER_THAN (FRAME_FP (frame), id.base))
+       /* ``inner/current < frame < id.base''.  Keep looking along
+           the frame chain.  */
+       continue;
+      if (INNER_THAN (id.base, FRAME_FP (frame)))
+       /* ``inner/current < id.base < frame''.  Oops, gone past it.
+           Just give up.  */
+       return NULL;
+      /* FIXME: cagney/2002-04-21: This isn't sufficient.  It should
+        use id.pc to check that the two frames belong to the same
+        function.  Otherwise we'll do things like match dummy frames
+        or mis-match frameless functions.  However, until someone
+        notices, stick with the existing behavour.  */
+      return frame;
+    }
+  return NULL;
+}
+
 /* FIND_SAVED_REGISTER ()
 
    Return the address in which frame FRAME's value of register REGNUM
index cdbcd4817646dd66a31c5e82959eb20ea6db6113..c1df5fcdda630563bbfe5234fd2ad42ecb5e4afa 100644 (file)
@@ -274,7 +274,21 @@ extern void show_stack_frame (struct frame_info *);
 
 extern void select_frame (struct frame_info *);
 
-extern void record_selected_frame (CORE_ADDR *, int *);
+/* Return an ID that can be used to re-find a frame.  */
+
+struct frame_id
+{
+  /* The frame's address.  This should be constant through out the
+     lifetime of a frame.  */
+  CORE_ADDR base;
+  /* The frame's current PC.  While this changes, the function that
+     the PC falls into, does not.  */
+  CORE_ADDR pc;
+};
+
+extern void get_frame_id (struct frame_info *fi, struct frame_id *id);
+
+extern struct frame_info *frame_find_by_id (struct frame_id id);
 
 extern void print_frame_info (struct frame_info *, int, int, int);
 
index e9fea2a0ac7ce313f51ca6e1f6c448c393d0ba32..faca42007a2420b625c806c3f52e56964914bb8a 100644 (file)
@@ -3910,7 +3910,6 @@ struct inferior_status
   CORE_ADDR step_resume_break_address;
   int stop_after_trap;
   int stop_soon_quietly;
-  CORE_ADDR selected_frame_address;
   char *stop_registers;
 
   /* These are here because if call_function_by_hand has written some
@@ -3918,7 +3917,9 @@ struct inferior_status
      any registers.  */
   char *registers;
 
-  int selected_level;
+  /* A frame unique identifier.  */
+  struct frame_id selected_frame_id;
+
   int breakpoint_proceeded;
   int restore_stack_info;
   int proceed_to_finish;
@@ -3987,38 +3988,21 @@ save_inferior_status (int restore_stack_info)
 
   read_register_bytes (0, inf_status->registers, REGISTER_BYTES);
 
-  record_selected_frame (&(inf_status->selected_frame_address),
-                        &(inf_status->selected_level));
+  get_frame_id (selected_frame, &inf_status->selected_frame_id);
   return inf_status;
 }
 
-struct restore_selected_frame_args
-{
-  CORE_ADDR frame_address;
-  int level;
-};
-
 static int
 restore_selected_frame (void *args)
 {
-  struct restore_selected_frame_args *fr =
-  (struct restore_selected_frame_args *) args;
+  struct frame_id *fid =  (struct frame_id *) args;
   struct frame_info *frame;
-  int level = fr->level;
 
-  frame = find_relative_frame (get_current_frame (), &level);
+  frame = frame_find_by_id (*fid);
 
   /* If inf_status->selected_frame_address is NULL, there was no
      previously selected frame.  */
-  if (frame == NULL ||
-  /*  FRAME_FP (frame) != fr->frame_address || */
-  /* elz: deleted this check as a quick fix to the problem that
-     for function called by hand gdb creates no internal frame
-     structure and the real stack and gdb's idea of stack are
-     different if nested calls by hands are made.
-
-     mvs: this worries me.  */
-      level != 0)
+  if (frame == NULL)
     {
       warning ("Unable to restore previously selected frame.\n");
       return 0;
@@ -4066,19 +4050,14 @@ restore_inferior_status (struct inferior_status *inf_status)
 
   if (target_has_stack && inf_status->restore_stack_info)
     {
-      struct restore_selected_frame_args fr;
-      fr.level = inf_status->selected_level;
-      fr.frame_address = inf_status->selected_frame_address;
       /* The point of catch_errors is that if the stack is clobbered,
-         walking the stack might encounter a garbage pointer and error()
-         trying to dereference it.  */
-      if (catch_errors (restore_selected_frame, &fr,
+         walking the stack might encounter a garbage pointer and
+         error() trying to dereference it.  */
+      if (catch_errors (restore_selected_frame, &inf_status->selected_frame_id,
                        "Unable to restore previously selected frame:\n",
                        RETURN_MASK_ERROR) == 0)
        /* Error in restoring the selected frame.  Select the innermost
           frame.  */
-
-
        select_frame (get_current_frame ());
 
     }
index 509883b40700ee6a23e25498adaa3c90b8594e70..014c274c7405bd9688a35c0df341b642f95d9e02 100644 (file)
@@ -1545,17 +1545,6 @@ select_and_print_frame (struct frame_info *fi)
     }
 }
 \f
-
-/* Store the selected frame and its level into *FRAMEP and *LEVELP.
-   If there is no selected frame, *FRAMEP is set to NULL.  */
-
-void
-record_selected_frame (CORE_ADDR *frameaddrp, int *levelp)
-{
-  *frameaddrp = selected_frame ? selected_frame->frame : 0;
-  *levelp = frame_relative_level (selected_frame);
-}
-
 /* Return the symbol-block in which the selected frame is executing.
    Can return zero under various legitimate circumstances.