diff --git a/gdb/frame.c b/gdb/frame.c index 67e0607..8ad349b 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -57,71 +57,6 @@ static struct frame_info *get_prev_frame_raw (struct frame_info *this_frame); frames (e.g. "set heuristic-fence-post" in mips-tdep.c, or anything which reads new symbols)), we should call reinit_frame_cache. */ -struct frame_info -{ - /* 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: Perhaps 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; - - /* The frame's low-level unwinder and corresponding cache. The - low-level unwinder is responsible for unwinding register values - for the previous frame. The low-level unwind methods are - selected based on the presence, or otherwise, of register unwind - information such as CFI. */ - void *prologue_cache; - const struct frame_unwind *unwind; - - /* Cached copy of the previous frame's architecture. */ - struct - { - int p; - struct gdbarch *arch; - } prev_arch; - - /* Cached copy of the previous frame's resume address. */ - struct { - int p; - CORE_ADDR value; - } prev_pc; - - /* Cached copy of the previous frame's function address. */ - struct - { - CORE_ADDR addr; - int p; - } prev_func; - - /* This frame's ID. */ - struct - { - int p; - struct frame_id value; - } this_id; - - /* The frame's high-level base methods, and corresponding cache. - The high level base methods are selected based on the frame's - debug info. */ - const struct frame_base *base; - void *base_cache; - - /* Pointers to the next (down, inner, younger) and previous (up, - outer, older) frame_info's in the frame cache. */ - struct frame_info *next; /* down, inner, younger */ - int prev_p; - struct frame_info *prev; /* up, outer, older */ - - /* The reason why we could not set PREV, or UNWIND_NO_REASON if we - could. Only valid when PREV_P is set. */ - enum unwind_stop_reason stop_reason; -}; - /* Flag to control debugging. */ int frame_debug; diff --git a/gdb/frame.h b/gdb/frame.h index febef5c..900d263 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -80,8 +80,6 @@ struct ui_file; /* The frame object. */ -struct frame_info; - /* 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 resume or a frame cache destruct. It of course assumes that the @@ -440,6 +438,72 @@ enum unwind_stop_reason UNWIND_NO_SAVED_PC, }; + +struct frame_info +{ + /* 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: Perhaps 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; + + /* The frame's low-level unwinder and corresponding cache. The + low-level unwinder is responsible for unwinding register values + for the previous frame. The low-level unwind methods are + selected based on the presence, or otherwise, of register unwind + information such as CFI. */ + void *prologue_cache; + const struct frame_unwind *unwind; + + /* Cached copy of the previous frame's architecture. */ + struct + { + int p; + struct gdbarch *arch; + } prev_arch; + + /* Cached copy of the previous frame's resume address. */ + struct { + int p; + CORE_ADDR value; + } prev_pc; + + /* Cached copy of the previous frame's function address. */ + struct + { + CORE_ADDR addr; + int p; + } prev_func; + + /* This frame's ID. */ + struct + { + int p; + struct frame_id value; + } this_id; + + /* The frame's high-level base methods, and corresponding cache. + The high level base methods are selected based on the frame's + debug info. */ + const struct frame_base *base; + void *base_cache; + + /* Pointers to the next (down, inner, younger) and previous (up, + outer, older) frame_info's in the frame cache. */ + struct frame_info *next; /* down, inner, younger */ + int prev_p; + struct frame_info *prev; /* up, outer, older */ + + /* The reason why we could not set PREV, or UNWIND_NO_REASON if we + could. Only valid when PREV_P is set. */ + enum unwind_stop_reason stop_reason; +}; + /* Return the reason why we can't unwind past this frame. */ enum unwind_stop_reason get_frame_unwind_stop_reason (struct frame_info *); diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c index 6aa1d08..7239700 100644 --- a/gdb/mi/mi-main.c +++ b/gdb/mi/mi-main.c @@ -1277,6 +1277,11 @@ mi_execute_command (char *cmd, int from_tty) { struct gdb_exception result; ptid_t previous_ptid = inferior_ptid; + struct frame_info *previous_frame; + if (has_stack_frames()) + previous_frame = get_selected_frame (NULL); + else + previous_frame = NULL; if (do_timings) { @@ -1338,6 +1343,29 @@ mi_execute_command (char *cmd, int from_tty) } } + /* =frame-selected notification */ + if (ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ())) + && previous_frame + && strcmp (command->command, "stack-select-frame") != 0) + { + struct mi_interp *mi = top_level_interpreter_data (); + struct frame_info *fi = get_selected_frame (NULL); + int report_change = 0; + + if (fi->level != previous_frame->level) + report_change = ((command->frame == -1) + || (fi->level != command->frame)); + + if (report_change) + { + target_terminal_ours (); + fprintf_unfiltered (mi->event_channel, + "frame-selected,id=\"%d\"", + get_selected_frame(NULL)->level); + gdb_flush (mi->event_channel); + } + } + mi_parse_free (command); }