0 for innermost, 1 for its caller, ...
or -1 for frame specified by address with no defined level. */
-int selected_frame_level;
+/* Level of the selected frame: 0 for innermost, 1 for its caller, ...
+ or -1 for NULL frame. */
+
+int
+frame_relative_level (struct frame_info *fi)
+{
+ if (fi == NULL)
+ return -1;
+ else
+ return fi->level;
+}
/* Zero means do things normally; we are interacting directly with the
user. One means print the full filename and linenumber when a
}
calling_frame_info = get_prev_frame (fi);
- if (!addr_exp && selected_frame_level >= 0)
+ if (!addr_exp && frame_relative_level (selected_frame) >= 0)
{
- printf_filtered ("Stack level %d, frame at ", selected_frame_level);
+ printf_filtered ("Stack level %d, frame at ",
+ frame_relative_level (selected_frame));
print_address_numeric (fi->frame, 1, gdb_stdout);
printf_filtered (":\n");
}
}
\f
-/* Select frame FI, and note that its stack level is LEVEL.
- LEVEL may be -1 if an actual level number is not known. */
+/* Select frame FI (or NULL - to invalidate the current frame). */
void
-select_frame (struct frame_info *fi, int level)
+select_frame (struct frame_info *fi)
{
register struct symtab *s;
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__,
- "Conflicting frame levels fi->level=%d, level=%d",
- (fi ? fi->level : -1),
- level);
+ /* NOTE: cagney/2002-05-04: FI can be NULL. This occures when the
+ frame is being invalidated. */
if (selected_frame_level_changed_hook)
- selected_frame_level_changed_hook (level);
+ selected_frame_level_changed_hook (frame_relative_level (fi));
/* Ensure that symbols for this frame are read in. Also, determine the
source language of this frame, and switch to it if desired. */
}
\f
-/* Select frame FI, noting that its stack level is LEVEL. Also print
- the stack frame and show the source if this is the tui version. */
-void
-select_and_print_frame (struct frame_info *fi, int level)
+/* Select frame FI. Also print the stack frame and show the source if
+ this is the tui version. */
+static void
+select_and_print_frame (struct frame_info *fi)
{
- select_frame (fi, level);
+ select_frame (fi);
if (fi)
{
- print_stack_frame (fi, level, 1);
+ print_stack_frame (fi, frame_relative_level (fi), 1);
}
}
\f
record_selected_frame (CORE_ADDR *frameaddrp, int *levelp)
{
*frameaddrp = selected_frame ? selected_frame->frame : 0;
- *levelp = selected_frame_level;
+ *levelp = frame_relative_level (selected_frame);
}
/* Return the symbol-block in which the selected frame is executing.
frame = parse_frame_specification (level_exp);
- /* Try to figure out what level this frame is. But if there is
- no current stack, don't error out -- let the user set one. */
- frame1 = 0;
- if (get_current_frame ())
- {
- for (frame1 = get_prev_frame (0);
- frame1 && frame1 != frame;
- frame1 = get_prev_frame (frame1))
- level++;
- }
-
- if (!frame1)
- level = 0;
-
- select_frame (frame, level);
+ select_frame (frame);
}
/* The "frame" command. With no arg, print selected frame briefly.
frame_command (char *level_exp, int from_tty)
{
select_frame_command (level_exp, from_tty);
- show_and_print_stack_frame (selected_frame, selected_frame_level, 1);
+ show_and_print_stack_frame (selected_frame,
+ frame_relative_level (selected_frame), 1);
}
/* The XDB Compatibility command to print the current frame. */
{
if (target_has_stack == 0 || selected_frame == 0)
error ("No stack.");
- print_only_stack_frame (selected_frame, selected_frame_level, 1);
+ print_only_stack_frame (selected_frame,
+ frame_relative_level (selected_frame), 1);
}
/* Select the frame up one or COUNT stack levels
fi = find_relative_frame (selected_frame, &count1);
if (count1 != 0 && count_exp == 0)
error ("Initial frame selected; you cannot go up.");
- select_frame (fi, selected_frame_level + count - count1);
+ select_frame (fi);
}
static void
up_command (char *count_exp, int from_tty)
{
up_silently_base (count_exp);
- show_and_print_stack_frame (selected_frame, selected_frame_level, 1);
+ show_and_print_stack_frame (selected_frame,
+ frame_relative_level (selected_frame), 1);
}
/* Select the frame down one or COUNT stack levels
error ("Bottom (i.e., innermost) frame selected; you cannot go down.");
}
- select_frame (frame, selected_frame_level + count - count1);
+ select_frame (frame);
}
/* ARGSUSED */
down_command (char *count_exp, int from_tty)
{
down_silently_base (count_exp);
- show_and_print_stack_frame (selected_frame, selected_frame_level, 1);
+ show_and_print_stack_frame (selected_frame,
+ frame_relative_level (selected_frame), 1);
}
\f
void
if (!found)
printf_filtered ("'%s' not within current stack frame.\n", arg);
else if (fp != selected_frame)
- select_and_print_frame (fp, level);
+ select_and_print_frame (fp);
}
/* Gets the language of the current frame. */