From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6213 invoked by alias); 27 Aug 2009 16:50:14 -0000 Received: (qmail 6197 invoked by uid 22791); 27 Aug 2009 16:50:12 -0000 X-SWARE-Spam-Status: No, hits=-2.9 required=5.0 tests=AWL,BAYES_00,SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: sourceware.org Received: from lo.gmane.org (HELO lo.gmane.org) (80.91.229.12) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 27 Aug 2009 16:50:06 +0000 Received: from list by lo.gmane.org with local (Exim 4.50) id 1MgiAl-0007kI-CY for gdb-patches@sources.redhat.com; Thu, 27 Aug 2009 18:50:03 +0200 Received: from 95-24-218-197.broadband.corbina.ru ([95.24.218.197]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Thu, 27 Aug 2009 18:50:03 +0200 Received: from dima by 95-24-218-197.broadband.corbina.ru with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Thu, 27 Aug 2009 18:50:03 +0200 To: gdb-patches@sources.redhat.com From: Dmitry Dzhus Subject: =frame-selected MI notification Date: Thu, 27 Aug 2009 17:01:00 -0000 Message-ID: <87iqg99xb5.fsf@sphinx.net.ru> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1.50 (gnu/linux) X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2009-08/txt/msg00485.txt.bz2 --=-=-= Content-length: 944 This patch adds =frame-selected notification to GDB/MI. This notification is important, because it provides front-ends a way to find out that user has asked for frame change via frontend console using CLI command `up`, `down` or `frame N`. I had to move `frame_info` structure description to `frame.h` so its fields may be accessed from mi-main.c. I'm not sure if this is the correct approach. Nick Roberts once posted a patch which implements both =thread-selected and =frame-selected via observers: http://sourceware.org/ml/gdb-patches/2008-04/msg00377.html. Current implementation of =thread-selected in mi-main.c uses a different approach, comparing current thread ID before and after executing a command in `mi_execute_command` function. My patch does the same for frame level. I don't know how is it technically better. I think it would be nice if somebody reviewed Nick's patch once again or at least accepted the one proposed by me. --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=gdb-frame-notification.patch Content-length: 6554 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); } --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Content-length: 45 -- Happy Hacking. http://sphinx.net.ru む --=-=-=--