[3/3] Replace TUI's select_frame hook (PR tui/13378)

Message ID 1435667837-16337-1-git-send-email-patrick@parcs.ath.cx
State New, archived
Headers

Commit Message

Patrick Palka June 30, 2015, 12:37 p.m. UTC
  This version adds a tui_normal_stop observer in place of augmenting the
tui_on_sync_execution_done observer.  And tui_refresh_frame_and_register_information
can now be made a static function.

The observer takes a print_frame parameter that is supposed to inform us
whether the frame should be printed.  This boolean seems to only be true for
when the inferior has exited.  Since tui_refresh_frame_and_register_information
already handles this case by checking has_stack_frames() this patch elects to
ignore this parameter in the observer.

gdb/ChangeLog:

	* frame.c (select_frame): Remove reference to
	deprecated_selected_frame_level_changed_hook.
	* frame.h (deprecated_selected_frame_level_changed_hook): Remove
	declaration.
	* stack.c (deprecated_selected_frame_level_changed_hook):
	Likewise.
	* tui/tui-hooks.c (tui_selected_frame_level_changed_hook):
	Rename to ...
	(tui_refresh_frame_and_register_information): ... this.  Bail
	out if there is no stack.
	(tui_before_prompt): New function.
	(tui_normal_stop): New function.
	(tui_before_prompt_observer): New observer.
	(tui_normal_stop_observer): New observer.
	(tui_install_hooks): Register tui_before_prompt_observer to
	call tui_before_prompt and tui_normal_stop_observer to call
	tui_normal_stop.  Remove reference to
	deprecated_selected_frame_level_changed_hook.
	(tui_remove_hooks): Detach and unset tui_before_prompt_observer
	and tui_normal_stop_observer.  Remove reference to
	deprecated_selected_frame_level_changed_hook.
---
 gdb/frame.c         |  2 --
 gdb/frame.h         |  2 --
 gdb/stack.c         |  2 --
 gdb/tui/tui-hooks.c | 40 +++++++++++++++++++++++++++++++---------
 4 files changed, 31 insertions(+), 15 deletions(-)
  

Comments

Pedro Alves June 30, 2015, 2:08 p.m. UTC | #1
On 06/30/2015 01:37 PM, Patrick Palka wrote:
> This version adds a tui_normal_stop observer in place of augmenting the
> tui_on_sync_execution_done observer.  And tui_refresh_frame_and_register_information
> can now be made a static function.
> 
> The observer takes a print_frame parameter that is supposed to inform us
> whether the frame should be printed.  This boolean seems to only be true for

s/only be true/only be false/

> when the inferior has exited.  Since tui_refresh_frame_and_register_information
> already handles this case by checking has_stack_frames() this patch elects to
> ignore this parameter in the observer.

This is OK.  I'll take a look at patch 2 soon.

Did you find that we still need deprecated_print_frame_info_listing_hook?

Thanks,
Pedro Alves
  
Patrick Palka June 30, 2015, 2:54 p.m. UTC | #2
On Tue, Jun 30, 2015 at 10:08 AM, Pedro Alves <palves@redhat.com> wrote:
> On 06/30/2015 01:37 PM, Patrick Palka wrote:
>> This version adds a tui_normal_stop observer in place of augmenting the
>> tui_on_sync_execution_done observer.  And tui_refresh_frame_and_register_information
>> can now be made a static function.
>>
>> The observer takes a print_frame parameter that is supposed to inform us
>> whether the frame should be printed.  This boolean seems to only be true for
>
> s/only be true/only be false/
>
>> when the inferior has exited.  Since tui_refresh_frame_and_register_information
>> already handles this case by checking has_stack_frames() this patch elects to
>> ignore this parameter in the observer.
>
> This is OK.  I'll take a look at patch 2 soon.
>
> Did you find that we still need deprecated_print_frame_info_listing_hook?

It still seems to be "necessary" -- at least, I can't outright remove it.

The only caller of deprecated_print_frame_info_listing_hook is in
print_frame_info and its use looks like this:

 if (deprecated_print_frame_info_listing_hook)
    (*deprecated_print_frame_info_listing_hook) (...);
 else
   { ... other code ... }

If I remove the hook by replacing the above code with

  { ... other code ... }

Then a regression occurs: the TUI decides to make sure that the
currently executing line always sits at the top of the window instead
of only scrolling the screen when the currently executing line is not
invisible.

But if I disable the hook by replacing the body of code in print_frame_info with

  if (deprecated_print_frame_info_listing_hook)
    ;
  else
    { ... other code ... }

Then everything seems to be OK.  So the code in  the else branch is
interfering with TUI somehow.  I will investigate further.

>
> Thanks,
> Pedro Alves
>
  
Patrick Palka June 30, 2015, 2:56 p.m. UTC | #3
On Tue, Jun 30, 2015 at 10:54 AM, Patrick Palka <patrick@parcs.ath.cx> wrote:
> On Tue, Jun 30, 2015 at 10:08 AM, Pedro Alves <palves@redhat.com> wrote:
>> On 06/30/2015 01:37 PM, Patrick Palka wrote:
>>> This version adds a tui_normal_stop observer in place of augmenting the
>>> tui_on_sync_execution_done observer.  And tui_refresh_frame_and_register_information
>>> can now be made a static function.
>>>
>>> The observer takes a print_frame parameter that is supposed to inform us
>>> whether the frame should be printed.  This boolean seems to only be true for
>>
>> s/only be true/only be false/
>>
>>> when the inferior has exited.  Since tui_refresh_frame_and_register_information
>>> already handles this case by checking has_stack_frames() this patch elects to
>>> ignore this parameter in the observer.
>>
>> This is OK.  I'll take a look at patch 2 soon.
>>
>> Did you find that we still need deprecated_print_frame_info_listing_hook?
>
> It still seems to be "necessary" -- at least, I can't outright remove it.
>
> The only caller of deprecated_print_frame_info_listing_hook is in
> print_frame_info and its use looks like this:
>
>  if (deprecated_print_frame_info_listing_hook)
>     (*deprecated_print_frame_info_listing_hook) (...);
>  else
>    { ... other code ... }
>
> If I remove the hook by replacing the above code with
>
>   { ... other code ... }
>
> Then a regression occurs: the TUI decides to make sure that the
> currently executing line always sits at the top of the window instead
> of only scrolling the screen when the currently executing line is not
> invisible.

I meant to say not _visible_.
  
Patrick Palka June 30, 2015, 3:12 p.m. UTC | #4
On Tue, Jun 30, 2015 at 10:54 AM, Patrick Palka <patrick@parcs.ath.cx> wrote:
> On Tue, Jun 30, 2015 at 10:08 AM, Pedro Alves <palves@redhat.com> wrote:
>> On 06/30/2015 01:37 PM, Patrick Palka wrote:
>>> This version adds a tui_normal_stop observer in place of augmenting the
>>> tui_on_sync_execution_done observer.  And tui_refresh_frame_and_register_information
>>> can now be made a static function.
>>>
>>> The observer takes a print_frame parameter that is supposed to inform us
>>> whether the frame should be printed.  This boolean seems to only be true for
>>
>> s/only be true/only be false/
>>
>>> when the inferior has exited.  Since tui_refresh_frame_and_register_information
>>> already handles this case by checking has_stack_frames() this patch elects to
>>> ignore this parameter in the observer.
>>
>> This is OK.  I'll take a look at patch 2 soon.
>>
>> Did you find that we still need deprecated_print_frame_info_listing_hook?
>
> It still seems to be "necessary" -- at least, I can't outright remove it.
>
> The only caller of deprecated_print_frame_info_listing_hook is in
> print_frame_info and its use looks like this:
>
>  if (deprecated_print_frame_info_listing_hook)
>     (*deprecated_print_frame_info_listing_hook) (...);
>  else
>    { ... other code ... }
>
> If I remove the hook by replacing the above code with
>
>   { ... other code ... }
>
> Then a regression occurs: the TUI decides to make sure that the
> currently executing line always sits at the top of the window instead
> of only scrolling the screen when the currently executing line is not
> invisible.
>
> But if I disable the hook by replacing the body of code in print_frame_info with
>
>   if (deprecated_print_frame_info_listing_hook)
>     ;
>   else
>     { ... other code ... }
>
> Then everything seems to be OK.  So the code in  the else branch is
> interfering with TUI somehow.  I will investigate further.

The call to "print_source_lines (sal.symtab, sal.line, sal.line + 1,
0);" in the else branch eventually calls "tui_show_source (sal.line);"
which adjusts the source window so that sal.line is the very first
line visible.

I'm not sure how easy this would be to fix properly.  We want to avoid
calling print_source_lines in print_frame_info when the TUI is active.
Of course, I can just guard the code with "if (tui_active)" but that's
not a good fix.  Instead of removing the hook yet, what about making
it (tui_print_frame_info_listing_hook) a no-op in the interim?

BTW, in the CLI, this call to print_source_lines is responsible for
printing the stopped-at source line to stdout, e.g.

(gdb) start
....
Temporary breakpoint 2, main () at 13378.c:9
9         int i = 0;  // THIS LINE
(gdb)
  
Pedro Alves June 30, 2015, 3:47 p.m. UTC | #5
On 06/30/2015 04:12 PM, Patrick Palka wrote:
> On Tue, Jun 30, 2015 at 10:54 AM, Patrick Palka <patrick@parcs.ath.cx> wrote:

> The call to "print_source_lines (sal.symtab, sal.line, sal.line + 1,
> 0);" in the else branch eventually calls "tui_show_source (sal.line);"
> which adjusts the source window so that sal.line is the very first
> line visible.
> 
> I'm not sure how easy this would be to fix properly.  We want to avoid
> calling print_source_lines in print_frame_info when the TUI is active.
> Of course, I can just guard the code with "if (tui_active)" but that's
> not a good fix. 

Indeed.

> Instead of removing the hook yet, what about making
> it (tui_print_frame_info_listing_hook) a no-op in the interim?

If that works, fine with me.  Fine with me to leave it be as is too.

> 
> BTW, in the CLI, this call to print_source_lines is responsible for
> printing the stopped-at source line to stdout, e.g.

Yeah.  Maybe if we move the print_stop_event call out of normal_stop
into TUI/CLI normal_stop observers, then we can tailor CLI/TUI/MI to
print what they need.  I actually moved it here:

 https://github.com/palves/gdb/commits/palves/merge-more-async-and-sync
 https://github.com/palves/gdb/commit/c0a88ed037b645fb9f072290000dc11044524639

That's WIP (still ugly) post 7.10 material.

> 
> (gdb) start
> ....
> Temporary breakpoint 2, main () at 13378.c:9
> 9         int i = 0;  // THIS LINE
> (gdb)

Thanks,
Pedro Alves
  

Patch

diff --git a/gdb/frame.c b/gdb/frame.c
index b3cbf23..da5bfb9 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -1576,8 +1576,6 @@  select_frame (struct frame_info *fi)
   selected_frame = fi;
   /* NOTE: cagney/2002-05-04: FI can be NULL.  This occurs when the
      frame is being invalidated.  */
-  if (deprecated_selected_frame_level_changed_hook)
-    deprecated_selected_frame_level_changed_hook (frame_relative_level (fi));
 
   /* FIXME: kseitz/2002-08-28: It would be nice to call
      selected_frame_level_changed_event() right here, but due to limitations
diff --git a/gdb/frame.h b/gdb/frame.h
index 53a93e0..be64c57 100644
--- a/gdb/frame.h
+++ b/gdb/frame.h
@@ -763,8 +763,6 @@  extern void args_info (char *, int);
 
 extern void locals_info (char *, int);
 
-extern void (*deprecated_selected_frame_level_changed_hook) (int);
-
 extern void return_command (char *, int);
 
 /* Set FRAME's unwinder temporarily, so that we can call a sniffer.
diff --git a/gdb/stack.c b/gdb/stack.c
index eea575a..39803d9 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -52,8 +52,6 @@ 
 #include "symfile.h"
 #include "extension.h"
 
-void (*deprecated_selected_frame_level_changed_hook) (int);
-
 /* The possible choices of "set print frame-arguments", and the value
    of this setting.  */
 
diff --git a/gdb/tui/tui-hooks.c b/gdb/tui/tui-hooks.c
index 8d84551..b7218ff 100644
--- a/gdb/tui/tui-hooks.c
+++ b/gdb/tui/tui-hooks.c
@@ -119,18 +119,17 @@  tui_about_to_proceed (void)
   tui_target_has_run = 1;
 }
 
-/* The selected frame has changed.  This is happens after a target
-   stop or when the user explicitly changes the frame
-   (up/down/thread/...).  */
+/* 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.  */
+
 static void
-tui_selected_frame_level_changed_hook (int level)
+tui_refresh_frame_and_register_information (void)
 {
   struct frame_info *fi;
   CORE_ADDR pc;
   struct cleanup *old_chain;
 
-  /* Negative level means that the selected frame was cleared.  */
-  if (level < 0)
+  if (!has_stack_frames ())
     return;
 
   old_chain = make_cleanup_restore_target_terminal ();
@@ -191,19 +190,35 @@  tui_inferior_exit (struct inferior *inf)
   tui_display_main ();
 }
 
+/* Observer for the before_prompt notification.  */
+
+static void
+tui_before_prompt (const char *current_gdb_prompt)
+{
+  tui_refresh_frame_and_register_information ();
+}
+
+/* Observer for the normal_stop notification.  */
+
+static void
+tui_normal_stop (struct bpstats *bs, int print_frame)
+{
+  tui_refresh_frame_and_register_information ();
+}
+
 /* Observers created when installing TUI hooks.  */
 static struct observer *tui_bp_created_observer;
 static struct observer *tui_bp_deleted_observer;
 static struct observer *tui_bp_modified_observer;
 static struct observer *tui_inferior_exit_observer;
 static struct observer *tui_about_to_proceed_observer;
+static struct observer *tui_before_prompt_observer;
+static struct observer *tui_normal_stop_observer;
 
 /* Install the TUI specific hooks.  */
 void
 tui_install_hooks (void)
 {
-  deprecated_selected_frame_level_changed_hook
-    = tui_selected_frame_level_changed_hook;
   deprecated_print_frame_info_listing_hook
     = tui_print_frame_info_listing_hook;
 
@@ -218,6 +233,10 @@  tui_install_hooks (void)
     = observer_attach_inferior_exit (tui_inferior_exit);
   tui_about_to_proceed_observer
     = observer_attach_about_to_proceed (tui_about_to_proceed);
+  tui_before_prompt_observer
+    = observer_attach_before_prompt (tui_before_prompt);
+  tui_normal_stop_observer
+    = observer_attach_normal_stop (tui_normal_stop);
 
   deprecated_register_changed_hook = tui_register_changed_hook;
 }
@@ -226,7 +245,6 @@  tui_install_hooks (void)
 void
 tui_remove_hooks (void)
 {
-  deprecated_selected_frame_level_changed_hook = 0;
   deprecated_print_frame_info_listing_hook = 0;
   deprecated_query_hook = 0;
   deprecated_register_changed_hook = 0;
@@ -242,6 +260,10 @@  tui_remove_hooks (void)
   tui_inferior_exit_observer = NULL;
   observer_detach_about_to_proceed (tui_about_to_proceed_observer);
   tui_about_to_proceed_observer = NULL;
+  observer_detach_before_prompt (tui_before_prompt_observer);
+  tui_before_prompt_observer = NULL;
+  observer_detach_normal_stop (tui_normal_stop_observer);
+  tui_normal_stop_observer = NULL;
 }
 
 void _initialize_tui_hooks (void);