From patchwork Sat Jun 27 02:35:25 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 7406 Received: (qmail 39337 invoked by alias); 27 Jun 2015 02:35:55 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 39226 invoked by uid 89); 27 Jun 2015 02:35:54 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.0 required=5.0 tests=AWL, BAYES_05, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_LOW autolearn=no version=3.3.2 X-HELO: mail-qk0-f180.google.com Received: from mail-qk0-f180.google.com (HELO mail-qk0-f180.google.com) (209.85.220.180) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Sat, 27 Jun 2015 02:35:52 +0000 Received: by qkbp125 with SMTP id p125so64560022qkb.2 for ; Fri, 26 Jun 2015 19:35:50 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=vSaL1CL2ZGENYkNk0nzDcuHJ8XU68s3gUfx0k8g37Mg=; b=KSu2U8shLQcFaUKiuSETmgOTb5nNOL+YqyBJtfiv5FFrCtkl2m8WwCDAF3DPIdvDlP cRoAYi9diP8w2aeIL9EInYK6osy+NuEGjgeEX7CxDaFSNywvVwibNo3Vt1aJ+LFMLYIQ nlzul1w4DKQvgPfrh7WhcFkSUMEYaqLCslTwQCjSQmAy0PLz2DrSeBEtKpzoLP6Kc/Ok 235Q81PZVcpHZMaF78AEGOxyGNUjOW26OCDppfzc4z57wiRWN0CLEohoKZ9DnTtaKDIF NPZ8Plh55DvajNG3gResGTrZgeEd48JTqnXsTeFHLIleDlr7yuAwKEc3DOA1hNbAtzAH oj5g== X-Gm-Message-State: ALoCoQks3Gqp62gr1oA9LxDxTEDbdgm2maBkw0hcbuV8cHZJHLdTTCvwAtSw6OT2lwO55muuzySR X-Received: by 10.140.29.55 with SMTP id a52mr6293713qga.25.1435372550559; Fri, 26 Jun 2015 19:35:50 -0700 (PDT) Received: from localhost.localdomain (ool-4353acd8.dyn.optonline.net. [67.83.172.216]) by mx.google.com with ESMTPSA id k205sm7892029qhk.39.2015.06.26.19.35.49 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 26 Jun 2015 19:35:50 -0700 (PDT) From: Patrick Palka To: gdb-patches@sourceware.org Cc: Patrick Palka Subject: [PATCH 3/3] Replace TUI's select_frame hook (PR tui/13378) Date: Fri, 26 Jun 2015 22:35:25 -0400 Message-Id: <1435372525-1374-3-git-send-email-patrick@parcs.ath.cx> In-Reply-To: <1435372525-1374-1-git-send-email-patrick@parcs.ath.cx> References: <1435372525-1374-1-git-send-email-patrick@parcs.ath.cx> The select_frame hook is used by TUI to update TUI's frame and register information following changes to the selected frame. The problem with this hook is that it gets called after every single frame change, even if the frame change is only temporary or internal. This is the primary cause of flickering and slowdown when running the inferior under TUI with conditional breakpoints set. Internal GDB events are the source of many calls to select_frame and these internal events are triggered frequently, especially when a few conditional breakpoints are set. This patch removes the select_frame hook altogether and instead makes the frame and register information get updated in two key places (using observers): after an inferior stops, and right before displaying a prompt. The latter hook covers the case when frame information must be updated following a call to "up", "down", "run", "continue" etc and the former covers the case when frame information must be updated after the inferior stops in async execution mode. Together these hooks should cover all the cases when frame information ought to be refreshed (and when the relevant windows ought to be subsequently updated). Effectively, with this patch, frame/PC changes that do not immediately precede an inferior-stop event or a prompt display event no longer cause TUI's frame and register information to be updated. And as a result of this change and of the previous change to tui_show_frame_info, the TUI is much more disciplined about updating the screen, and so the flicker as described in the PR is totally gone. 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. Handle the case where there is no stack. (tui_before_prompt): New function. (tui_before_prompt_observer): New observer. (tui_install_hooks): Register tui_before_prompt_observer to call tui_before_prompt. Remove reference to deprecated_selected_frame_level_changed_hook. (tui_remove_hooks): Detach and unset tui_before_prompt_observer. Remove reference to deprecated_selected_frame_level_changed_hook. * tui/tui-hooks.h (tui_refresh_frame_and_register_information): Export. * tui/tui-interp.c: Include "tui/tui-hooks.h". (tui_on_sync_execution_done): Call tui_refresh_frame_and_register_information if tui_active. --- gdb/frame.c | 2 -- gdb/frame.h | 2 -- gdb/stack.c | 2 -- gdb/tui/tui-hooks.c | 64 ++++++++++++++++++++++++++++++---------------------- gdb/tui/tui-hooks.h | 5 ++++ gdb/tui/tui-interp.c | 4 ++++ 6 files changed, 46 insertions(+), 33 deletions(-) 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..a0994c4 100644 --- a/gdb/tui/tui-hooks.c +++ b/gdb/tui/tui-hooks.c @@ -119,46 +119,46 @@ 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/...). */ -static void -tui_selected_frame_level_changed_hook (int level) +/* See tui-hooks.h. */ + +void +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) - return; - old_chain = make_cleanup_restore_target_terminal (); target_terminal_ours_for_output (); - fi = get_selected_frame (NULL); - /* Ensure that symbols for this frame are read in. Also, determine - the source language of this frame, and switch to it if - desired. */ - if (get_frame_pc_if_available (fi, &pc)) + if (has_stack_frames ()) { - struct symtab *s; - - s = find_pc_line_symtab (pc); - /* elz: This if here fixes the problem with the pc not being - displayed in the tui asm layout, with no debug symbols. The - value of s would be 0 here, and select_source_symtab would - abort the command by calling the 'error' function. */ - if (s) - select_source_symtab (s); + fi = get_selected_frame (NULL); + /* Ensure that symbols for this frame are read in. Also, determine + the source language of this frame, and switch to it if + desired. */ + if (get_frame_pc_if_available (fi, &pc)) + { + struct symtab *s; + + s = find_pc_line_symtab (pc); + /* elz: This if here fixes the problem with the pc not being + displayed in the tui asm layout, with no debug symbols. The + value of s would be 0 here, and select_source_symtab would + abort the command by calling the 'error' function. */ + if (s) + select_source_symtab (s); + } } + else + fi = NULL; /* Display the frame position (even if there is no symbols or the PC is not known). */ tui_show_frame_info (fi); /* Refresh the register window if it's visible. */ - if (tui_is_window_visible (DATA_WIN)) + if (fi != NULL && tui_is_window_visible (DATA_WIN)) { tui_refreshing_registers = 1; tui_check_data_values (fi); @@ -191,19 +191,26 @@ 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 (); +} + /* 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; /* 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 +225,8 @@ 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); deprecated_register_changed_hook = tui_register_changed_hook; } @@ -226,7 +235,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 +250,8 @@ 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; } void _initialize_tui_hooks (void); diff --git a/gdb/tui/tui-hooks.h b/gdb/tui/tui-hooks.h index ab6afc9..303d9bb 100644 --- a/gdb/tui/tui-hooks.h +++ b/gdb/tui/tui-hooks.h @@ -20,6 +20,11 @@ #ifndef TUI_HOOKS_H #define TUI_HOOKS_H +/* 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. */ + +extern void tui_refresh_frame_and_register_information (void); + extern void tui_install_hooks (void); extern void tui_remove_hooks (void); diff --git a/gdb/tui/tui-interp.c b/gdb/tui/tui-interp.c index 1a5639d..4284037 100644 --- a/gdb/tui/tui-interp.c +++ b/gdb/tui/tui-interp.c @@ -27,6 +27,7 @@ #include "tui/tui-data.h" #include "readline/readline.h" #include "tui/tui-win.h" +#include "tui/tui-hooks.h" #include "tui/tui.h" #include "tui/tui-io.h" #include "infrun.h" @@ -107,6 +108,9 @@ tui_on_sync_execution_done (void) { if (!interp_quiet_p (tui_interp)) display_gdb_prompt (NULL); + + if (tui_active) + tui_refresh_frame_and_register_information (); } /* Observer for the command_error notification. */