TUI: Make sure to update registers if frame information has changed
authorPatrick Palka <patrick@parcs.ath.cx>
Wed, 1 Jul 2015 12:02:09 +0000 (08:02 -0400)
committerPatrick Palka <patrick@parcs.ath.cx>
Wed, 1 Jul 2015 16:13:57 +0000 (12:13 -0400)
When I replaced TUI's frame_changed hook to fix PR tui/13378 I assumed
that there's no reason to refresh register information following a call
to "up", "down" or "frame".  This assumption was made to fix the problem
of refreshing frame information twice following a sync-execution normal
stop (once in tui_normal_stop and then in tui_before_prompt) -- the
second refresh removing any highlights made by the first.

I was wrong about that -- GDB's snapshot of register information is
per-frame, and when the frame changes, registers do too (most
prominently the %rip and %rsp registers).  So e.g. GDB 7.8 would
highlight such register changes after invoking "up", "down" or "frame",
and current GDB does not.

To fix this regression, this patch adds another (sufficient) condition
for refreshing register information: in
tui_refresh_frame_and_register_information, always refresh register
information if frame information has changed.  This makes register
information get refreshed following a call to "up", "down" or "frame"
while still avoiding the "double refresh" issue following a normal stop.

This condition may seem to obsolete the existing registers_too_p
parameter, but it does not: following a normal stop, it is possible that
registers may have changed while frame information had not.  We could be
on the exact same PC with different register values.  The new condition
would not catch such a case, but the registers_too_p condition will.  So
both conditions seem necessary (and either one is sufficient).

gdb/ChangeLog:

* tui/tui-hooks.c (tui_refresh_frame_and_register_information):
Update commentary.  Always refresh the registers when frame
information has changed.
* tui/tui-stack.c (tui_show_frame_info): Update commentary.
Change return type to int.  Return 1 if frame information has
changed, 1 otherwise.
(tui_before_prompt): Update commentary.
* tui/tui-stack.h (tui_show_frame_info): Change return type to
int.

gdb/ChangeLog
gdb/tui/tui-hooks.c
gdb/tui/tui-stack.c
gdb/tui/tui-stack.h

index 2dc32d8b969665c1d7c2de2a50bedeb85e941f0d..7c3200ae65ee84db1dd071612df9da6958746da3 100644 (file)
@@ -1,3 +1,15 @@
+2015-07-01  Patrick Palka  <patrick@parcs.ath.cx>
+
+       * tui/tui-hooks.c (tui_refresh_frame_and_register_information):
+       Update commentary.  Always refresh the registers when frame
+       information has changed.
+       * tui/tui-stack.c (tui_show_frame_info): Update commentary.
+       Change return type to int.  Return 1 if frame information has
+       changed, 0 otherwise.
+       (tui_before_prompt): Update commentary.
+       * tui/tui-stack.h (tui_show_frame_info): Change return type to
+       int.
+
 2015-06-30  Patrick Palka  <patrick@parcs.ath.cx>
 
        PR tui/13378
index 59872091c9c973bfd4d51a93c4f033ae78d80d87..0eb2f071e817b6e1e4a310d4c6e0d960d457c4fc 100644 (file)
@@ -122,7 +122,8 @@ tui_about_to_proceed (void)
 /* Refresh TUI's frame and register information.  This is a hook intended to be
    used to update the screen after potential frame and register changes.
 
-   REGISTERS_TOO_P controls whether to refresh our register information.  */
+   REGISTERS_TOO_P controls whether to refresh our register information even
+   if frame information hasn't changed.  */
 
 static void
 tui_refresh_frame_and_register_information (int registers_too_p)
@@ -130,6 +131,7 @@ tui_refresh_frame_and_register_information (int registers_too_p)
   struct frame_info *fi;
   CORE_ADDR pc;
   struct cleanup *old_chain;
+  int frame_info_changed_p;
 
   if (!has_stack_frames ())
     return;
@@ -156,10 +158,11 @@ tui_refresh_frame_and_register_information (int registers_too_p)
 
   /* Display the frame position (even if there is no symbols or the PC
      is not known).  */
-  tui_show_frame_info (fi);
+  frame_info_changed_p = tui_show_frame_info (fi);
 
   /* Refresh the register window if it's visible.  */
-  if (tui_is_window_visible (DATA_WIN) && registers_too_p)
+  if (tui_is_window_visible (DATA_WIN)
+      && (frame_info_changed_p || registers_too_p))
     {
       tui_refreshing_registers = 1;
       tui_check_data_values (fi);
@@ -199,8 +202,9 @@ tui_before_prompt (const char *current_gdb_prompt)
 {
   /* This refresh is intended to catch changes to the selected frame following
      a call to "up", "down" or "frame".  As such we don't necessarily want to
-     refresh registers here as they could not have changed.  Registers will be
-     refreshed after a normal stop or by our tui_register_changed_hook.  */
+     refresh registers here unless the frame actually changed by one of these
+     commands.  Registers will otherwise be refreshed after a normal stop or by
+     our tui_register_changed_hook.  */
   tui_refresh_frame_and_register_information (/*registers_too_p=*/0);
 }
 
index 65d18fe4f0f29ca358b16ddaf1089fc423e6f71e..e36f8bd1ac63bc753da6c71ff8ef697dba311949 100644 (file)
@@ -351,9 +351,12 @@ tui_update_locator_fullname (const char *fullname)
 }
 
 /* Function to print the frame information for the TUI.  The windows are
-   refreshed only if frame information has changed since the last refresh.  */
+   refreshed only if frame information has changed since the last refresh.
 
-void
+   Return 1 if frame information has changed (and windows subsequently
+   refreshed), 0 otherwise.  */
+
+int
 tui_show_frame_info (struct frame_info *fi)
 {
   struct tui_win_info *win_info;
@@ -391,7 +394,7 @@ tui_show_frame_info (struct frame_info *fi)
         not changed.  If frame information has not changed, then the windows'
         contents will not change.  So don't bother refreshing the windows.  */
       if (!locator_changed_p)
-       return;
+       return 0;
 
       tui_show_locator_content ();
       start_line = 0;
@@ -462,6 +465,8 @@ tui_show_frame_info (struct frame_info *fi)
            }
          tui_update_exec_info (win_info);
        }
+
+      return 1;
     }
   else
     {
@@ -469,7 +474,7 @@ tui_show_frame_info (struct frame_info *fi)
        = tui_set_locator_info (NULL, NULL, NULL, 0, (CORE_ADDR) 0);
 
       if (!locator_changed_p)
-       return;
+       return 0;
 
       tui_show_locator_content ();
       for (i = 0; i < (tui_source_windows ())->count; i++)
@@ -478,6 +483,8 @@ tui_show_frame_info (struct frame_info *fi)
          tui_clear_source_content (win_info, EMPTY_SOURCE_PROMPT);
          tui_update_exec_info (win_info);
        }
+
+      return 1;
     }
 }
 
index 2a34f9ea7412220452512b5e5bc3a988bfcec991..b89ddc4703dcead2900308f5af2d5ee876adcfda 100644 (file)
@@ -26,6 +26,6 @@ struct frame_info;
 
 extern void tui_update_locator_fullname (const char *);
 extern void tui_show_locator_content (void);
-extern void tui_show_frame_info (struct frame_info *);
+extern int tui_show_frame_info (struct frame_info *);
 
 #endif