[PATCH 1/3] Add a select_frame_reason enum parameter to select_frame

Maxime Coste
2013-04-26T19:03:29Z

select_frame calls specify if the frame is selected due to
a breakpoint/signal (REASON_STOP), a user command (REASON_USER)
or just as an implementation detail (REASON_IMPL_DETAIL) which
should restore the previous frame once finished.
---
gdb/ada-lang.c | 4 ++--
gdb/breakpoint.c | 10 +++++-----
gdb/frame.c | 6 +++---
gdb/frame.h | 16 +++++++++++++++-
gdb/infrun.c | 8 ++++----
gdb/mi/mi-main.c | 2 +-
gdb/python/py-frame.c | 2 +-
gdb/stack.c | 9 +++++----
gdb/thread.c | 8 ++++----
gdb/valops.c | 2 +-
gdb/varobj.c | 6 +++---
11 files changed, 44 insertions(+), 29 deletions(-)

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index fdfc0b4..d45731b 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -11167,7 +11167,7 @@ ada_find_printable_frame (struct frame_info *fi)
{
if (!is_known_support_routine (fi))
{
- select_frame (fi);
+ select_frame (fi, REASON_STOP);
break;
}
}
@@ -11222,7 +11222,7 @@ ada_unhandled_exception_name_addr_from_raise (void)
if (fi == NULL)
return 0;

- select_frame (fi);
+ select_frame (fi, REASON_STOP);
return parse_and_eval_address ("id.full_name");
}

diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 35ada7a..843a4d1 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -1761,7 +1761,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
fi = frame_find_by_id (b->watchpoint_frame);
within_current_scope = (fi != NULL);
if (within_current_scope)
- select_frame (fi);
+ select_frame (fi, REASON_IMPL_DETAIL);
}

/* We don't free locations. They are stored in the bp_location array
@@ -1996,7 +1996,7 @@ in which its expression is valid.\n"),

/* Restore the selected frame. */
if (frame_saved)
- select_frame (frame_find_by_id (saved_frame_id));
+ select_frame (frame_find_by_id (saved_frame_id), REASON_IMPL_DETAIL);
}

@@ -4765,7 +4765,7 @@ watchpoint_check (void *p)
/* If we end up stopping, the current frame will get selected
in normal_stop. So this call to select_frame won't affect
the user. */
- select_frame (fr);
+ select_frame (fr, REASON_IMPL_DETAIL);
}

if (within_current_scope)
@@ -5091,7 +5091,7 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
of the inlined function; the current frame will be the
call site. */
if (w == NULL || w->cond_exp_valid_block == NULL)
- select_frame (get_current_frame ());
+ select_frame (get_current_frame (), REASON_IMPL_DETAIL);
else
{
struct frame_info *frame;
@@ -5112,7 +5112,7 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
intuitive. */
frame = block_innermost_frame (w->cond_exp_valid_block);
if (frame != NULL)
- select_frame (frame);
+ select_frame (frame, REASON_IMPL_DETAIL);
else
within_current_scope = 0;
}
diff --git a/gdb/frame.c b/gdb/frame.c
index 8d4e2c8..0a0acda 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -1382,7 +1382,7 @@ get_selected_frame (const char *message)
/* Hey! Don't trust this. It should really be re-finding the
last selected frame of the currently selected thread. This,
though, is better than nothing. */
- select_frame (get_current_frame ());
+ select_frame (get_current_frame (), REASON_IMPL_DETAIL);
}
/* There is always a frame. */
gdb_assert (selected_frame != NULL);
@@ -1412,7 +1412,7 @@ deprecated_safe_get_selected_frame (void)
/* Select frame FI (or NULL - to invalidate the current frame). */

void
-select_frame (struct frame_info *fi)
+select_frame (struct frame_info *fi, enum select_frame_reason reason)
{
selected_frame = fi;
/* NOTE: cagney/2002-05-04: FI can be NULL. This occurs when the
@@ -1548,7 +1548,7 @@ reinit_frame_cache (void)
annotate_frames_invalid ();

current_frame = NULL; /* Invalidate cache */
- select_frame (NULL);
+ select_frame (NULL, REASON_IMPL_DETAIL);
frame_stash_invalidate ();
if (frame_debug)
fprintf_unfiltered (gdb_stdlog, "{ reinit_frame_cache () }\n");
diff --git a/gdb/frame.h b/gdb/frame.h
index 31b9cb7..34115b4 100644
--- a/gdb/frame.h
+++ b/gdb/frame.h
@@ -219,6 +219,20 @@ enum frame_type
SENTINEL_FRAME
};

+/* Reason why a frame is being selected, so that select_frame is aware
+ of why it is being called */
+
+enum select_frame_reason
+{
+ /* Selected for as an implementation detail, user selected
+ frame should be restored */
+ REASON_IMPL_DETAIL,
+ /* Selecting this frame was a user request. */
+ REASON_USER,
+ /* A the inferior was stopped due to breakpoint/signal... */
+ REASON_STOP,
+};
+
/* For every stopped thread, GDB tracks two frames: current and
selected. Current frame is the inner most frame of the selected
thread. Selected frame is the one being examined by the GDB
@@ -268,7 +282,7 @@ extern struct frame_info *get_selected_frame_if_set (void);

/* Select a specific frame. NULL, apparently implies re-select the
inner most frame. */
-extern void select_frame (struct frame_info *);
+extern void select_frame (struct frame_info *, enum select_frame_reason);

/* Given a FRAME, return the next (more inner, younger) or previous
(more outer, older) frame. */
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 5d6a9af..9d0e9e7 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -6029,7 +6029,7 @@ normal_stop (void)

if (!stop_stack_dummy)
{
- select_frame (get_current_frame ());
+ select_frame (get_current_frame (), REASON_STOP);

/* Print current location without a level number, if
we have changed functions or hit a breakpoint.
@@ -6124,7 +6124,7 @@ normal_stop (void)
stopped (e.g. the dummy call previously hit a breakpoint).
We can't know which case we have so just always re-establish
a selected frame here. */
- select_frame (get_current_frame ());
+ select_frame (get_current_frame (), REASON_IMPL_DETAIL);
}

done:
@@ -6925,7 +6925,7 @@ restore_selected_frame (void *args)
return 0;
}

- select_frame (frame);
+ select_frame (frame, REASON_IMPL_DETAIL);

return (1);
}
@@ -6967,7 +6967,7 @@ restore_infcall_control_state (struct infcall_control_state *inf_status)
RETURN_MASK_ERROR) == 0)
/* Error in restoring the selected frame. Select the innermost
frame. */
- select_frame (get_current_frame ());
+ select_frame (get_current_frame (), REASON_IMPL_DETAIL);
}

xfree (inf_status);
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index 94fda8f..0f0f3f5 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -2116,7 +2116,7 @@ mi_cmd_execute (struct mi_parse *parse)
fid = find_relative_frame (get_current_frame (), &frame);
if (frame == 0)
/* find_relative_frame was successful */
- select_frame (fid);
+ select_frame (fid, REASON_USER);
else
error (_("Invalid frame id: %d"), frame);
}
diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c
index e2eb9c5..d5926b0 100644
--- a/gdb/python/py-frame.c
+++ b/gdb/python/py-frame.c
@@ -511,7 +511,7 @@ frapy_select (PyObject *self, PyObject *args)
{
FRAPY_REQUIRE_VALID (self, fi);

- select_frame (fi);
+ select_frame (fi, REASON_USER);
}
GDB_PY_HANDLE_EXCEPTION (except);

diff --git a/gdb/stack.c b/gdb/stack.c
index c072a2e..e4aaab6 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -2116,7 +2116,7 @@ args_plus_locals_info (char *ignore, int from_tty)
static void
select_and_print_frame (struct frame_info *frame)
{
- select_frame (frame);
+ select_frame (frame, REASON_USER);
if (frame)
print_stack_frame (frame, 1, SRC_AND_LOC);
}
@@ -2185,7 +2185,8 @@ find_relative_frame (struct frame_info *frame, int *level_offset_ptr)
void
select_frame_command (char *level_exp, int from_tty)
{
- select_frame (parse_frame_specification_1 (level_exp, "No stack.", NULL));
+ select_frame (parse_frame_specification_1 (level_exp, "No stack.", NULL),
+ REASON_USER);
}

/* The "frame" command. With no argument, print the selected frame
@@ -2222,7 +2223,7 @@ up_silently_base (char *count_exp)
frame = find_relative_frame (get_selected_frame ("No stack."), &count);
if (count != 0 && count_exp == NULL)
error (_("Initial frame selected; you cannot go up."));
- select_frame (frame);
+ select_frame (frame, REASON_USER);
}

static void
@@ -2261,7 +2262,7 @@ down_silently_base (char *count_exp)
error (_("Bottom (innermost) frame selected; you cannot go down."));
}

- select_frame (frame);
+ select_frame (frame, REASON_USER);
}

static void
diff --git a/gdb/thread.c b/gdb/thread.c
index 2a1d723..0a11ce9 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -1016,7 +1016,7 @@ restore_selected_frame (struct frame_id a_frame_id, int frame_level)
/* This means there was no selected frame. */
if (frame_level == -1)
{
- select_frame (NULL);
+ select_frame (NULL, REASON_IMPL_DETAIL);
return;
}

@@ -1037,7 +1037,7 @@ restore_selected_frame (struct frame_id a_frame_id, int frame_level)
&& frame_id_eq (get_frame_id (frame), a_frame_id))
{
/* Cool, all is fine. */
- select_frame (frame);
+ select_frame (frame, REASON_IMPL_DETAIL);
return;
}

@@ -1045,13 +1045,13 @@ restore_selected_frame (struct frame_id a_frame_id, int frame_level)
if (frame != NULL)
{
/* Cool, refound it. */
- select_frame (frame);
+ select_frame (frame, REASON_IMPL_DETAIL);
return;
}

/* Nothing else to do, the frame layout really changed. Select the
innermost stack frame. */
- select_frame (get_current_frame ());
+ select_frame (get_current_frame (), REASON_IMPL_DETAIL);

/* Warn the user. */
if (frame_level > 0 && !ui_out_is_mi_like_p (current_uiout))
diff --git a/gdb/valops.c b/gdb/valops.c
index 93c09d8..d801809 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -1419,7 +1419,7 @@ value_assign (struct value *toval, struct value *fromval)
struct frame_info *fi = frame_find_by_id (old_frame);

if (fi != NULL)
- select_frame (fi);
+ select_frame (fi, REASON_IMPL_DETAIL);
}

break;
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 467e59a..c158d69 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -707,7 +707,7 @@ varobj_create (char *objname,
var->root->frame = get_frame_id (fi);
var->root->thread_id = pid_to_thread_id (inferior_ptid);
old_id = get_frame_id (get_selected_frame (NULL));
- select_frame (fi);
+ select_frame (fi, REASON_IMPL_DETAIL);
}

/* We definitely need to catch errors here.
@@ -746,7 +746,7 @@ varobj_create (char *objname,

/* Reset the selected frame. */
if (frame_id_p (old_id))
- select_frame (frame_find_by_id (old_id));
+ select_frame (frame_find_by_id (old_id), REASON_IMPL_DETAIL);
}

/* If the variable object name is null, that means this
@@ -3405,7 +3405,7 @@ check_scope (struct varobj *var)
pc >= BLOCK_END (var->root->valid_block))
scope = 0;
else
- select_frame (fi);
+ select_frame (fi, REASON_IMPL_DETAIL);
}
return scope;
}
--
1.8.2.1