2002-12-03 Andrew Cagney <ac131313@redhat.com>
* frame.h (get_frame_id): Convert to a function. (null_frame_id, frame_id_p): Declare. (frame_id_eq, frame_id_inner): Declare. (frame_id_build): New function. * frame.c (get_frame_id): Update. Use null_frame_id. (frame_find_by_id): Rewrite using frame_id_p, frame_id_eq and frame_id_inner. (null_frame_id, frame_id_p): Define. (frame_id_eq, frame_id_inner): Define. (frame_id_build): New function. * varobj.c (varobj_create): Update. (varobj_update): Update. * valops.c (value_assign): Update. (new_root_variable): Update. * infrun.c (save_inferior_status): Update. * breakpoint.c (watch_command_1): Update.
This commit is contained in:
parent
179f9f7a5a
commit
7a424e9969
7 changed files with 120 additions and 34 deletions
|
@ -1,3 +1,22 @@
|
||||||
|
2002-12-03 Andrew Cagney <ac131313@redhat.com>
|
||||||
|
|
||||||
|
* frame.h (get_frame_id): Convert to a function.
|
||||||
|
(null_frame_id, frame_id_p): Declare.
|
||||||
|
(frame_id_eq, frame_id_inner): Declare.
|
||||||
|
(frame_id_build): New function.
|
||||||
|
* frame.c (get_frame_id): Update. Use null_frame_id.
|
||||||
|
(frame_find_by_id): Rewrite using frame_id_p, frame_id_eq and
|
||||||
|
frame_id_inner.
|
||||||
|
(null_frame_id, frame_id_p): Define.
|
||||||
|
(frame_id_eq, frame_id_inner): Define.
|
||||||
|
(frame_id_build): New function.
|
||||||
|
* varobj.c (varobj_create): Update.
|
||||||
|
(varobj_update): Update.
|
||||||
|
* valops.c (value_assign): Update.
|
||||||
|
(new_root_variable): Update.
|
||||||
|
* infrun.c (save_inferior_status): Update.
|
||||||
|
* breakpoint.c (watch_command_1): Update.
|
||||||
|
|
||||||
2002-12-03 J. Brobecker <brobecker@gnat.com>
|
2002-12-03 J. Brobecker <brobecker@gnat.com>
|
||||||
|
|
||||||
* config/pa/tm-hppah.h (SNAP1): Remove unused macro.
|
* config/pa/tm-hppah.h (SNAP1): Remove unused macro.
|
||||||
|
|
|
@ -5400,7 +5400,7 @@ watch_command_1 (char *arg, int accessflag, int from_tty)
|
||||||
if (frame)
|
if (frame)
|
||||||
{
|
{
|
||||||
prev_frame = get_prev_frame (frame);
|
prev_frame = get_prev_frame (frame);
|
||||||
get_frame_id (frame, &b->watchpoint_frame);
|
b->watchpoint_frame = get_frame_id (frame);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
81
gdb/frame.c
81
gdb/frame.c
|
@ -35,24 +35,64 @@
|
||||||
#include "annotate.h"
|
#include "annotate.h"
|
||||||
#include "language.h"
|
#include "language.h"
|
||||||
|
|
||||||
/* Return a frame uniq ID that can be used to, later re-find the
|
/* Return a frame uniq ID that can be used to, later, re-find the
|
||||||
frame. */
|
frame. */
|
||||||
|
|
||||||
void
|
struct frame_id
|
||||||
get_frame_id (struct frame_info *fi, struct frame_id *id)
|
get_frame_id (struct frame_info *fi)
|
||||||
{
|
{
|
||||||
if (fi == NULL)
|
if (fi == NULL)
|
||||||
{
|
{
|
||||||
id->base = 0;
|
return null_frame_id;
|
||||||
id->pc = 0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
id->base = fi->frame;
|
struct frame_id id;
|
||||||
id->pc = fi->pc;
|
id.base = fi->frame;
|
||||||
|
id.pc = fi->pc;
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const struct frame_id null_frame_id; /* All zeros. */
|
||||||
|
|
||||||
|
struct frame_id
|
||||||
|
frame_id_build (CORE_ADDR base, CORE_ADDR func_or_pc)
|
||||||
|
{
|
||||||
|
struct frame_id id;
|
||||||
|
id.base = base;
|
||||||
|
id.pc = func_or_pc;
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
frame_id_p (struct frame_id l)
|
||||||
|
{
|
||||||
|
/* The .func can be NULL but the .base cannot. */
|
||||||
|
return (l.base != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
frame_id_eq (struct frame_id l, struct frame_id r)
|
||||||
|
{
|
||||||
|
/* If .base is different, the frames are different. */
|
||||||
|
if (l.base != r.base)
|
||||||
|
return 0;
|
||||||
|
/* Add a test to check that the frame ID's are for the same function
|
||||||
|
here. */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
frame_id_inner (struct frame_id l, struct frame_id r)
|
||||||
|
{
|
||||||
|
/* Only return non-zero when strictly inner than. Note that, per
|
||||||
|
comment in "frame.h", there is some fuzz here. Frameless
|
||||||
|
functions are not strictly inner than (same .base but different
|
||||||
|
.func). */
|
||||||
|
return INNER_THAN (l.base, r.base);
|
||||||
|
}
|
||||||
|
|
||||||
struct frame_info *
|
struct frame_info *
|
||||||
frame_find_by_id (struct frame_id id)
|
frame_find_by_id (struct frame_id id)
|
||||||
{
|
{
|
||||||
|
@ -60,29 +100,24 @@ frame_find_by_id (struct frame_id id)
|
||||||
|
|
||||||
/* ZERO denotes the null frame, let the caller decide what to do
|
/* ZERO denotes the null frame, let the caller decide what to do
|
||||||
about it. Should it instead return get_current_frame()? */
|
about it. Should it instead return get_current_frame()? */
|
||||||
if (id.base == 0 && id.pc == 0)
|
if (!frame_id_p (id))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (frame = get_current_frame ();
|
for (frame = get_current_frame ();
|
||||||
frame != NULL;
|
frame != NULL;
|
||||||
frame = get_prev_frame (frame))
|
frame = get_prev_frame (frame))
|
||||||
{
|
{
|
||||||
struct frame_id this;
|
struct frame_id this = get_frame_id (frame);
|
||||||
get_frame_id (frame, &this);
|
if (frame_id_eq (id, this))
|
||||||
if (INNER_THAN (this.base, id.base))
|
/* An exact match. */
|
||||||
/* ``inner/current < frame < id.base''. Keep looking along
|
return frame;
|
||||||
the frame chain. */
|
if (frame_id_inner (id, this))
|
||||||
continue;
|
/* Gone to far. */
|
||||||
if (INNER_THAN (id.base, this.base))
|
|
||||||
/* ``inner/current < id.base < frame''. Oops, gone past it.
|
|
||||||
Just give up. */
|
|
||||||
return NULL;
|
return NULL;
|
||||||
/* FIXME: cagney/2002-04-21: This isn't sufficient. It should
|
/* Either, we're not yet gone far enough out along the frame
|
||||||
use id.pc / this.pc to check that the two frames belong to
|
chain (inner(this,id), or we're comparing frameless functions
|
||||||
the same function. Otherwise we'll do things like match
|
(same .base, different .func, no test available). Struggle
|
||||||
dummy frames or mis-match frameless functions. However,
|
on until we've definitly gone to far. */
|
||||||
until someone notices, stick with the existing behavour. */
|
|
||||||
return frame;
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
41
gdb/frame.h
41
gdb/frame.h
|
@ -31,8 +31,8 @@ struct frame_info;
|
||||||
|
|
||||||
/* The frame object's ID. This provides a per-frame unique identifier
|
/* The frame object's ID. This provides a per-frame unique identifier
|
||||||
that can be used to relocate a `struct frame_info' after a target
|
that can be used to relocate a `struct frame_info' after a target
|
||||||
resume or a frame cache destruct (assuming the target hasn't
|
resume or a frame cache destruct. It of course assumes that the
|
||||||
unwound the stack past that frame - a problem handled elsewhere). */
|
inferior hasn't unwound the stack past that frame. */
|
||||||
|
|
||||||
struct frame_id
|
struct frame_id
|
||||||
{
|
{
|
||||||
|
@ -47,6 +47,38 @@ struct frame_id
|
||||||
CORE_ADDR pc;
|
CORE_ADDR pc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Methods for constructing and comparing Frame IDs.
|
||||||
|
|
||||||
|
NOTE: Given frameless functions A and B, where A calls B (and hence
|
||||||
|
B is inner-to A). The relationships: !eq(A,B); !eq(B,A);
|
||||||
|
!inner(A,B); !inner(B,A); all hold. This is because, while B is
|
||||||
|
inner to A, B is not strictly inner to A (being frameless, they
|
||||||
|
have the same .base value). */
|
||||||
|
|
||||||
|
/* For convenience. All fields are zero. */
|
||||||
|
extern const struct frame_id null_frame_id;
|
||||||
|
|
||||||
|
/* Construct a frame ID. The second parameter isn't yet well defined.
|
||||||
|
It might be the containing function, or the resume PC (see comment
|
||||||
|
above in `struct frame_id')? A func/pc of zero indicates a
|
||||||
|
wildcard (i.e., do not use func in frame ID comparisons). */
|
||||||
|
extern struct frame_id frame_id_build (CORE_ADDR base,
|
||||||
|
CORE_ADDR func_or_pc);
|
||||||
|
|
||||||
|
/* Returns non-zero when L is a valid frame (a valid frame has a
|
||||||
|
non-zero .base). */
|
||||||
|
extern int frame_id_p (struct frame_id l);
|
||||||
|
|
||||||
|
/* Returns non-zero when L and R identify the same frame, or, if
|
||||||
|
either L or R have a zero .func, then the same frame base. */
|
||||||
|
extern int frame_id_eq (struct frame_id l, struct frame_id r);
|
||||||
|
|
||||||
|
/* Returns non-zero when L is strictly inner-than R (they have
|
||||||
|
different frame .bases). Neither L, nor R can be `null'. See note
|
||||||
|
above about frameless functions. */
|
||||||
|
extern int frame_id_inner (struct frame_id l, struct frame_id r);
|
||||||
|
|
||||||
|
|
||||||
/* For every stopped thread, GDB tracks two frames: current and
|
/* For every stopped thread, GDB tracks two frames: current and
|
||||||
selected. Current frame is the inner most frame of the selected
|
selected. Current frame is the inner most frame of the selected
|
||||||
thread. Selected frame is the one being examined by the the GDB
|
thread. Selected frame is the one being examined by the the GDB
|
||||||
|
@ -176,8 +208,9 @@ extern void find_frame_sal (struct frame_info *frame,
|
||||||
extern CORE_ADDR get_frame_base (struct frame_info *);
|
extern CORE_ADDR get_frame_base (struct frame_info *);
|
||||||
|
|
||||||
/* Return the per-frame unique identifer. Can be used to relocate a
|
/* Return the per-frame unique identifer. Can be used to relocate a
|
||||||
frame after a frame cache flush (and other similar operations). */
|
frame after a frame cache flush (and other similar operations). If
|
||||||
extern void get_frame_id (struct frame_info *fi, struct frame_id *id);
|
FI is NULL, return the null_frame_id. */
|
||||||
|
extern struct frame_id get_frame_id (struct frame_info *fi);
|
||||||
|
|
||||||
/* The frame's level: 0 for innermost, 1 for its caller, ...; or -1
|
/* The frame's level: 0 for innermost, 1 for its caller, ...; or -1
|
||||||
for an invalid frame). */
|
for an invalid frame). */
|
||||||
|
|
|
@ -3856,7 +3856,7 @@ save_inferior_status (int restore_stack_info)
|
||||||
|
|
||||||
inf_status->registers = regcache_dup (current_regcache);
|
inf_status->registers = regcache_dup (current_regcache);
|
||||||
|
|
||||||
get_frame_id (deprecated_selected_frame, &inf_status->selected_frame_id);
|
inf_status->selected_frame_id = get_frame_id (deprecated_selected_frame);
|
||||||
return inf_status;
|
return inf_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -649,7 +649,7 @@ value_assign (struct value *toval, struct value *fromval)
|
||||||
/* Since modifying a register can trash the frame chain, we
|
/* Since modifying a register can trash the frame chain, we
|
||||||
save the old frame and then restore the new frame
|
save the old frame and then restore the new frame
|
||||||
afterwards. */
|
afterwards. */
|
||||||
get_frame_id (deprecated_selected_frame, &old_frame);
|
old_frame = get_frame_id (deprecated_selected_frame);
|
||||||
|
|
||||||
/* Figure out which frame this is in currently. */
|
/* Figure out which frame this is in currently. */
|
||||||
if (VALUE_LVAL (toval) == lval_register)
|
if (VALUE_LVAL (toval) == lval_register)
|
||||||
|
|
|
@ -487,7 +487,7 @@ varobj_create (char *objname,
|
||||||
Since select_frame is so benign, just call it for all cases. */
|
Since select_frame is so benign, just call it for all cases. */
|
||||||
if (fi != NULL)
|
if (fi != NULL)
|
||||||
{
|
{
|
||||||
get_frame_id (fi, &var->root->frame);
|
var->root->frame = get_frame_id (fi);
|
||||||
old_fi = deprecated_selected_frame;
|
old_fi = deprecated_selected_frame;
|
||||||
select_frame (fi);
|
select_frame (fi);
|
||||||
}
|
}
|
||||||
|
@ -898,7 +898,7 @@ varobj_update (struct varobj **varp, struct varobj ***changelist)
|
||||||
|
|
||||||
/* Save the selected stack frame, since we will need to change it
|
/* Save the selected stack frame, since we will need to change it
|
||||||
in order to evaluate expressions. */
|
in order to evaluate expressions. */
|
||||||
get_frame_id (deprecated_selected_frame, &old_fid);
|
old_fid = get_frame_id (deprecated_selected_frame);
|
||||||
|
|
||||||
/* Update the root variable. value_of_root can return NULL
|
/* Update the root variable. value_of_root can return NULL
|
||||||
if the variable is no longer around, i.e. we stepped out of
|
if the variable is no longer around, i.e. we stepped out of
|
||||||
|
@ -1344,8 +1344,7 @@ new_root_variable (void)
|
||||||
var->root->lang = NULL;
|
var->root->lang = NULL;
|
||||||
var->root->exp = NULL;
|
var->root->exp = NULL;
|
||||||
var->root->valid_block = NULL;
|
var->root->valid_block = NULL;
|
||||||
var->root->frame.base = 0;
|
var->root->frame = null_frame_id;
|
||||||
var->root->frame.pc = 0;
|
|
||||||
var->root->use_selected_frame = 0;
|
var->root->use_selected_frame = 0;
|
||||||
var->root->rootvar = NULL;
|
var->root->rootvar = NULL;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue