Fix "list" command in the TUI
PR tui/18932 notes that "list" no longer works in the TUI. At some point in the past, it switched the TUI source window to show the specified source; but now this source briefly flashes before the TUI reverts to showing the current stack frame's source. This patch fixes this bug by introducing a new observer that notices when the user selected context has changed. Then, the existing before-prompt observer is updated to request the correct update: either one based on the current stack frame, or one based on the user's source symtab_and_line. gdb/ChangeLog 2019-12-20 Tom Tromey <tom@tromey.com> PR tui/18932: * tui/tui-hooks.c (tui_refresh_frame_and_register_information): Rename parameters. Handle the not-from-stack-frame case. (from_stack, from_source_symtab): New globals. (tui_before_prompt, tui_normal_stop): Update. (tui_context_changed, tui_symtab_changed): New functions. (tui_attach_detach_observers): Attach new observers. gdb/testsuite/ChangeLog 2019-12-20 Tom Tromey <tom@tromey.com> * gdb.tui/list-before.exp: New file. Change-Id: I62013825f6c1afdd568a1c7a8c019b0c881131af
This commit is contained in:
parent
a75cd9a2c1
commit
fc9d2d724f
|
@ -1,3 +1,13 @@
|
|||
2019-12-20 Tom Tromey <tom@tromey.com>
|
||||
|
||||
PR tui/18932:
|
||||
* tui/tui-hooks.c (tui_refresh_frame_and_register_information):
|
||||
Rename parameters. Handle the not-from-stack-frame case.
|
||||
(from_stack, from_source_symtab): New globals.
|
||||
(tui_before_prompt, tui_normal_stop): Update.
|
||||
(tui_context_changed, tui_symtab_changed): New functions.
|
||||
(tui_attach_detach_observers): Attach new observers.
|
||||
|
||||
2019-12-20 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* source.c (struct current_source_location) <set, symtab, line>:
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2019-12-20 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* gdb.tui/list-before.exp: New file.
|
||||
|
||||
2019-12-20 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* gdb.tui/list.exp: Check for source on initial listing.
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
# Copyright 2019 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Ensure that "list" before starting the TUI will affect the view.
|
||||
|
||||
load_lib "tuiterm.exp"
|
||||
|
||||
standard_testfile tui-layout.c
|
||||
|
||||
if {[build_executable "failed to prepare" ${testfile} ${srcfile}] == -1} {
|
||||
return -1
|
||||
}
|
||||
|
||||
Term::clean_restart 24 80 $testfile
|
||||
|
||||
gdb_test "list main"
|
||||
|
||||
if {![Term::enter_tui]} {
|
||||
unsupported "TUI not supported"
|
||||
}
|
||||
|
||||
Term::check_contents "initial source listing" "21 *return 0"
|
|
@ -105,53 +105,52 @@ tui_event_modify_breakpoint (struct breakpoint *b)
|
|||
tui_update_all_breakpoint_info (nullptr);
|
||||
}
|
||||
|
||||
/* 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.
|
||||
/* This is set to true if the next window refresh should come from the
|
||||
current stack frame. */
|
||||
|
||||
REGISTERS_TOO_P controls whether to refresh our register information even
|
||||
if frame information hasn't changed. */
|
||||
static bool from_stack;
|
||||
|
||||
/* This is set to true if the next window refresh should come from the
|
||||
current source symtab. */
|
||||
|
||||
static bool from_source_symtab;
|
||||
|
||||
/* 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_refresh_frame_and_register_information (bool registers_too_p)
|
||||
tui_refresh_frame_and_register_information ()
|
||||
{
|
||||
struct frame_info *fi;
|
||||
CORE_ADDR pc;
|
||||
int frame_info_changed_p;
|
||||
|
||||
if (!has_stack_frames ())
|
||||
if (!from_stack && !from_source_symtab)
|
||||
return;
|
||||
|
||||
target_terminal::scoped_restore_terminal_state term_state;
|
||||
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 (from_stack && has_stack_frames ())
|
||||
{
|
||||
struct symtab *s;
|
||||
struct frame_info *fi = get_selected_frame (NULL);
|
||||
|
||||
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);
|
||||
/* Display the frame position (even if there is no symbols or
|
||||
the PC is not known). */
|
||||
int frame_info_changed_p = tui_show_frame_info (fi);
|
||||
|
||||
/* Refresh the register window if it's visible. */
|
||||
if (tui_is_window_visible (DATA_WIN)
|
||||
&& (frame_info_changed_p || from_stack))
|
||||
{
|
||||
tui_refreshing_registers = 1;
|
||||
TUI_DATA_WIN->check_register_values (fi);
|
||||
tui_refreshing_registers = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Display the frame position (even if there is no symbols or the PC
|
||||
is not known). */
|
||||
frame_info_changed_p = tui_show_frame_info (fi);
|
||||
|
||||
/* Refresh the register window if it's visible. */
|
||||
if (tui_is_window_visible (DATA_WIN)
|
||||
&& (frame_info_changed_p || registers_too_p))
|
||||
else if (!from_stack)
|
||||
{
|
||||
tui_refreshing_registers = 1;
|
||||
TUI_DATA_WIN->check_register_values (fi);
|
||||
tui_refreshing_registers = 0;
|
||||
/* Make sure that the source window is displayed. */
|
||||
tui_add_win_to_layout (SRC_WIN);
|
||||
|
||||
struct symtab_and_line sal = get_current_source_symtab_and_line ();
|
||||
tui_update_source_windows_with_line (sal);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,12 +182,9 @@ tui_inferior_exit (struct inferior *inf)
|
|||
static void
|
||||
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 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=*/false);
|
||||
tui_refresh_frame_and_register_information ();
|
||||
from_stack = false;
|
||||
from_source_symtab = false;
|
||||
}
|
||||
|
||||
/* Observer for the normal_stop notification. */
|
||||
|
@ -196,9 +192,23 @@ tui_before_prompt (const char *current_gdb_prompt)
|
|||
static void
|
||||
tui_normal_stop (struct bpstats *bs, int print_frame)
|
||||
{
|
||||
/* This refresh is intended to catch changes to the selected frame and to
|
||||
registers following a normal stop. */
|
||||
tui_refresh_frame_and_register_information (/*registers_too_p=*/true);
|
||||
from_stack = true;
|
||||
}
|
||||
|
||||
/* Observer for user_selected_context_changed. */
|
||||
|
||||
static void
|
||||
tui_context_changed (user_selected_what ignore)
|
||||
{
|
||||
from_stack = true;
|
||||
}
|
||||
|
||||
/* Observer for current_source_symtab_and_line_changed. */
|
||||
|
||||
static void
|
||||
tui_symtab_changed ()
|
||||
{
|
||||
from_source_symtab = true;
|
||||
}
|
||||
|
||||
/* Token associated with observers registered while TUI hooks are
|
||||
|
@ -236,6 +246,10 @@ tui_attach_detach_observers (bool attach)
|
|||
tui_normal_stop, attach);
|
||||
attach_or_detach (gdb::observers::register_changed,
|
||||
tui_register_changed, attach);
|
||||
attach_or_detach (gdb::observers::user_selected_context_changed,
|
||||
tui_context_changed, attach);
|
||||
attach_or_detach (gdb::observers::current_source_symtab_and_line_changed,
|
||||
tui_symtab_changed, attach);
|
||||
}
|
||||
|
||||
/* Install the TUI specific hooks. */
|
||||
|
|
Loading…
Reference in New Issue