aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog28
-rw-r--r--gdb/breakpoint.c23
-rw-r--r--gdb/breakpoint.h8
-rw-r--r--gdb/frame.c50
-rw-r--r--gdb/frame.h16
-rw-r--r--gdb/infrun.c41
-rw-r--r--gdb/stack.c11
7 files changed, 113 insertions, 64 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 37b511d..8c3ca23 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 6f604f1..1861370 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -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 ("\
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
index 3a58aad..7ab300f 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -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;
diff --git a/gdb/frame.c b/gdb/frame.c
index 85de9b8..5c52ed1 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -28,6 +28,56 @@
#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
diff --git a/gdb/frame.h b/gdb/frame.h
index cdbcd48..c1df5fc 100644
--- a/gdb/frame.h
+++ b/gdb/frame.h
@@ -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);
diff --git a/gdb/infrun.c b/gdb/infrun.c
index e9fea2a..faca420 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -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 ());
}
diff --git a/gdb/stack.c b/gdb/stack.c
index 509883b..014c274 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1545,17 +1545,6 @@ select_and_print_frame (struct frame_info *fi)
}
}
-
-/* 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.