Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Dmitry Dzhus <dima@sphinx.net.ru>
To: gdb-patches@sources.redhat.com
Subject: =frame-selected MI notification
Date: Thu, 27 Aug 2009 17:01:00 -0000	[thread overview]
Message-ID: <87iqg99xb5.fsf@sphinx.net.ru> (raw)

[-- Attachment #1: Type: text/plain, Size: 944 bytes --]

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.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: gdb-frame-notification.patch --]
[-- Type: text/x-patch, Size: 6554 bytes --]

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);
     }
 

[-- Attachment #3: Type: text/plain, Size: 48 bytes --]

-- 
Happy Hacking.

http://sphinx.net.ru
ã‚€

             reply	other threads:[~2009-08-27 16:50 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-08-27 17:01 Dmitry Dzhus [this message]
2009-08-27 20:54 ` Tom Tromey
2009-08-28  6:44   ` Vladimir Prus
2009-08-29  5:40     ` Nick Roberts
2009-08-29  7:53       ` Vladimir Prus
2009-08-31 23:11         ` Tom Tromey
2009-09-01 15:13         ` Dmitry Dzhus
2009-08-31 23:19     ` Tom Tromey
2009-09-01  5:35       ` Vladimir Prus
2009-09-02 19:35         ` Tom Tromey
2009-09-01 18:54   ` Dmitry Dzhus

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87iqg99xb5.fsf@sphinx.net.ru \
    --to=dima@sphinx.net.ru \
    --cc=gdb-patches@sources.redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox