From 7cc19214aa83761f61b42a8eed01732d39495972 Mon Sep 17 00:00:00 2001 From: Andrew Cagney Date: Wed, 10 Apr 2002 22:14:02 +0000 Subject: [PATCH] * stack.c (select_frame): Check that selected_frame and the specified level are as expected. * blockframe.c (get_prev_frame): Set the `level' from next_frame. Update copyright. * frame.h (struct frame_info): Add field `level'. Update copyright. Work-in-progress PR gdb/464. --- gdb/ChangeLog | 10 ++++++++++ gdb/blockframe.c | 11 +++++++---- gdb/frame.h | 16 ++++++++++++++-- gdb/stack.c | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 6 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a216d7d7603..39a50f3c506 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +2002-04-10 Andrew Cagney + + * stack.c (select_frame): Check that selected_frame and the + specified level are as expected. + * blockframe.c (get_prev_frame): Set the `level' from next_frame. + Update copyright. + * frame.h (struct frame_info): Add field `level'. Update + copyright. + Work-in-progress PR gdb/464. + 2002-04-10 Andrew Cagney * maint.c (maint_print_section_info): Rename print_section_info. diff --git a/gdb/blockframe.c b/gdb/blockframe.c index 8626ede70e9..49bda4a255a 100644 --- a/gdb/blockframe.c +++ b/gdb/blockframe.c @@ -1,7 +1,9 @@ -/* Get info from stack frames; - convert between frames, blocks, functions and pc values. - Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. +/* Get info from stack frames; convert between frames, blocks, + functions and pc values. + + Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software + Foundation, Inc. This file is part of GDB. @@ -393,6 +395,7 @@ get_prev_frame (struct frame_info *next_frame) next_frame->prev = prev; prev->next = next_frame; prev->frame = address; + prev->level = next_frame->level + 1; /* This change should not be needed, FIXME! We should determine whether any targets *need* INIT_FRAME_PC to happen diff --git a/gdb/frame.h b/gdb/frame.h index 5f952c58a12..a9898906932 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -1,6 +1,7 @@ /* Definitions for dealing with stack frames, for GDB, the GNU debugger. - Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, - 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + + Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, + 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GDB. @@ -63,6 +64,17 @@ struct frame_info For other frames, it is a pc saved in the next frame. */ CORE_ADDR pc; + /* Level of this frame. The inner-most (youngest) frame is at + level 0. As you move towards the outer-most (oldest) frame, + the level increases. This is a cached value. It could just as + easily be computed by counting back from the selected frame to + the inner most frame. */ + /* NOTE: cagney/2002-04-05: Perhaphs a level of ``-1'' should be + reserved to indicate a bogus frame - one that has been created + just to keep GDB happy (GDB always needs a frame). For the + moment leave this as speculation. */ + int level; + /* Nonzero if this is a frame associated with calling a signal handler. Set by machine-dependent code. On some machines, if diff --git a/gdb/stack.c b/gdb/stack.c index bedb6ee6fda..a348934b480 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -1458,6 +1458,38 @@ select_frame (struct frame_info *fi, int level) selected_frame = fi; selected_frame_level = level; + /* FIXME: cagney/2002-04-05: It can't be this easy (and looking at + the increasingly complex list of checkes, it wasn't)! GDB is + dragging around, and constantly updating, the global variable + selected_frame_level. Surely all that was needed was for the + level to be computed direct from the frame (by counting back to + the inner-most frame) or, as has been done here using a cached + value. For moment, check that the expected and the actual level + are consistent. If, after a few weeks, no one reports that this + assertion has failed, the global selected_frame_level and many + many parameters can all be deleted. */ + if (fi == NULL && level == -1) + /* Ok. The target is clearing the selected frame as part of a + cache flush. */ + ; + else if (fi != NULL && fi->level == level) + /* Ok. What you would expect. Level is redundant. */ + ; + else if (fi != NULL && level == -1) + /* Ok. See breakpoint.c. The watchpoint code changes the + selected frame to the frame that contains the watchpoint and + then, later changes it back to the old value. The -1 is used + as a marker so that the watchpoint code can easily detect that + things are not what they should be. Why the watchpoint code + can't mindlessly save/restore the selected frame I don't know, + hopefully it can be simplified that way. Hopefully the global + selected_frame can be replaced by a frame parameter, making + still more simplification possible. */ + ; + else + internal_error (__FILE__, __LINE__, + "oops! fi=0x%p, fi->level=%d, level=%d", + fi, fi ? fi->level : -1, level); if (selected_frame_level_changed_hook) selected_frame_level_changed_hook (level); -- 2.30.2