From 101dcfbe4ad4c4b054b2bd6b289fbe579e2503c6 Mon Sep 17 00:00:00 2001 From: Andrew Cagney Date: Mon, 10 Jun 2002 23:25:50 +0000 Subject: [PATCH] * 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. --- gdb/ChangeLog | 28 ++++++++++++++++++++++++++- gdb/breakpoint.c | 23 +++++++--------------- gdb/breakpoint.h | 8 ++++---- gdb/frame.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ gdb/frame.h | 16 +++++++++++++++- gdb/infrun.c | 41 ++++++++++----------------------------- gdb/stack.c | 11 ----------- 7 files changed, 113 insertions(+), 64 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 37b511d3b4..8c3ca23c99 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,9 +1,35 @@ +2002-06-10 Andrew Cagney + + * 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 * ser-e7kpc.c: Fix duplicated define and call of _initialize_ser_e7000pc - 2002-06-09 Daniel Jacobowitz * signals/signals.c (target_signal_from_host): Fix #ifdef diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 6f604f1961..1861370eaa 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 3a58aad248..7ab300ffb6 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 85de9b8331..5c52ed1a0a 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 cdbcd48176..c1df5fcdda 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 e9fea2a0ac..faca42007a 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 509883b407..014c274c74 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. -- 2.34.1