2020-01-01 14:20:01 +08:00
|
|
|
# Copyright 2019-2020 Free Software Foundation, Inc.
|
2019-07-02 06:01:58 +08:00
|
|
|
|
|
|
|
# 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/>.
|
|
|
|
|
|
|
|
# An ANSI terminal emulator for expect.
|
|
|
|
|
2019-07-20 06:15:58 +08:00
|
|
|
# The expect "spawn" function puts the tty name into the spawn_out
|
|
|
|
# array; but dejagnu doesn't export this globally. So, we have to
|
|
|
|
# wrap spawn with our own function, so that we can capture this value.
|
|
|
|
# The value is later used in calls to stty.
|
2020-06-12 19:29:43 +08:00
|
|
|
proc tuiterm_spawn { args } {
|
2019-07-20 06:15:58 +08:00
|
|
|
set result [uplevel builtin_spawn $args]
|
|
|
|
global gdb_spawn_name
|
|
|
|
upvar spawn_out spawn_out
|
[gdb/testsuite] Fix spawn in tuiterm.exp
When running gdb.stabs/weird.exp by itself it passes, but if we run a gdb.tui
test before it, we get:
...
$ make check RUNTESTFLAGS="gdb.stabs/weird.exp gdb.tui/basic.exp"
Running /data/gdb_versions/devel/src/gdb/testsuite/gdb.tui/basic.exp ...
Running /data/gdb_versions/devel/src/gdb/testsuite/gdb.stabs/weird.exp ...
ERROR: Couldn't make test case. -1 {spawn failed}
...
In more detail, using -v:
...
Executing on build: sed -f aout.sed weird.def weird.s (timeout = 300)
builtin_spawn [open ...]^M
pid is 19060 19061 -19060 -19061
spawn -open file10 failed, 1 can't read "spawn_out(slave,name)": \
no such variable, can't read "spawn_out(slave,name)": no such variable
while executing
"set gdb_spawn_name $spawn_out(slave,name)"
(procedure "spawn" line 5)
invoked from within
"spawn -ignore SIGHUP -leaveopen file10"
invoked from within
"catch "spawn -ignore SIGHUP -leaveopen $id" result2"
ERROR: Couldn't make test case. -1 {spawn failed}
...
When running the gdb.tui test, spawn gets renamed to a local version from
lib/tuiterm.exp. The local version calls expect's spawn, and then makes the
local spawn_out(slave,name) variable accessible in the global variable
gdb_spawn_name.
However, the weird.exp test-case uses remote_exec build, which ends up using
local_exec, which given that there's input/output redirection uses open:
...
set result [catch {open "| ${commandline} $inp |& tee $outpf" RDONLY} id]
...
followed by spawn using the -leaveopen option:
...
set result [catch "spawn -ignore SIGHUP -leaveopen $id" result2]
...
which apparently has the effect that spawn_out(slave,name) is not set.
Fix this in the lib/tuiterm.exp local spawn proc by detecting the case that
spawn_out(slave,name) is not set, and handling it accordingly.
Tested gdb.stabs/weird.exp and gdb.tui/*.exp on x86_64-linux.
gdb/testsuite/ChangeLog:
2020-02-27 Tom de Vries <tdevries@suse.de>
* lib/tuiterm.exp (spawn): Handle case that spawn_out(slave,name) is
not set.
2020-02-27 17:16:00 +08:00
|
|
|
if { [info exists spawn_out] } {
|
|
|
|
set gdb_spawn_name $spawn_out(slave,name)
|
|
|
|
} else {
|
|
|
|
unset gdb_spawn_name
|
|
|
|
}
|
2019-07-20 06:15:58 +08:00
|
|
|
return $result
|
|
|
|
}
|
|
|
|
|
2020-06-12 19:29:43 +08:00
|
|
|
# Initialize tuiterm.exp environment.
|
|
|
|
proc tuiterm_env_init { } {
|
|
|
|
# Override spawn with tui_spawn.
|
|
|
|
rename spawn builtin_spawn
|
|
|
|
rename tuiterm_spawn spawn
|
|
|
|
}
|
|
|
|
|
|
|
|
# Finalize tuiterm.exp environment.
|
|
|
|
proc tuiterm_env_finish { } {
|
|
|
|
# Restore spawn.
|
|
|
|
rename spawn tuiterm_spawn
|
|
|
|
rename builtin_spawn spawn
|
|
|
|
}
|
|
|
|
|
2019-07-02 06:01:58 +08:00
|
|
|
namespace eval Term {
|
|
|
|
variable _rows
|
|
|
|
variable _cols
|
|
|
|
variable _chars
|
|
|
|
|
|
|
|
variable _cur_x
|
|
|
|
variable _cur_y
|
|
|
|
|
|
|
|
variable _attrs
|
|
|
|
|
|
|
|
variable _last_char
|
|
|
|
|
Make TUI resizing tests more robust
As Sergio pointed out, the TUI resizing tests are flaky. Debugging
this showed three main problems.
1. expect's "stty" command processes its arguments one-by-one. So,
rather than requesting a single resize, it sends two separate resize
requests (one for rows and one for columns). This means gdb sees two
SIGWINCH signals and resizes the terminal twice.
I consider this a bug in expect, but I couldn't readily see how to
report a bug; and anyway the fix wouldn't propagate very quickly.
This patch works around this problem by explicitly doing two separate
resizes (so it will be robust if expect ever does change); and then by
waiting for each resize to complete before continuing.
2. gdb uses curses to drive the console rendering. Currently the test
suite looks for terminal text insertion sequences to decide when a
command has completed. However, it turns out that, sometimes, curses
can output things in non-obvious ways. I didn't debug into curses but
I guess this can happen due to output optimizations. No matter the
reason, sometimes the current approach of only tracking text
insertions is not enough to detect that gdb has finished rendering.
This patch fixes this problem by arranging to detect the termination
output after any curses command, not just insertion.
3. Detecting when a resize has completed is tricky. In fact, I could
not find a way to reliably do this.
This patch fixes this problem by adding a special maint
"tui-resize-message" setting to gdb. When this is enabled, gdb will
print a message after each SIGWINCH has been fully processed. The
test suite enables this mode and then waits for the message in order
to know when control can be returned to the calling test.
This patch also adds a timeout, to avoid the situation where the
terminal code fails to notice a change for some reason. This lets the
test at least try to continue.
gdb/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* tui/tui-win.c (resize_message): New global.
(show_tui_resize_message): New function.
(tui_async_resize_screen): Print message if requested.
(_initialize_tui_win): Add tui-resize-message setting.
* NEWS: Add entry for new commands.
gdb/doc/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* gdb.texinfo (Maintenance Commands): Document new command.
gdb/testsuite/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* lib/tuiterm.exp (_accept): Add wait_for parameter. Check output
after any command. Expect prompt after WAIT_FOR is seen.
(enter_tui): Enable resize messages.
(command): Expect command in output.
(get_line): Avoid error when cursor appears to be off-screen.
(dump_screen): Include screen size in title.
(_do_resize): New proc, from "resize".
(resize): Rewrite. Do resize in two steps.
* gdb.tui/empty.exp (layouts): Fix entries.
(check_boxes): Remove xfail.
(check_text): Dump screen on failure.
Change-Id: I420e0259cb99b21adcd28f671b99161eefa7a51d
2019-08-17 05:16:12 +08:00
|
|
|
variable _resize_count
|
|
|
|
|
2019-07-02 06:01:58 +08:00
|
|
|
# If ARG is empty, return DEF: otherwise ARG. This is useful for
|
|
|
|
# defaulting arguments in CSIs.
|
|
|
|
proc _default {arg def} {
|
|
|
|
if {$arg == ""} {
|
|
|
|
return $def
|
|
|
|
}
|
|
|
|
return $arg
|
|
|
|
}
|
|
|
|
|
|
|
|
# Erase in the line Y from SX to just before EX.
|
|
|
|
proc _clear_in_line {sx ex y} {
|
|
|
|
variable _attrs
|
|
|
|
variable _chars
|
|
|
|
set lattr [array get _attrs]
|
|
|
|
while {$sx < $ex} {
|
|
|
|
set _chars($sx,$y) [list " " $lattr]
|
|
|
|
incr sx
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Erase the lines from SY to just before EY.
|
|
|
|
proc _clear_lines {sy ey} {
|
|
|
|
variable _cols
|
|
|
|
while {$sy < $ey} {
|
|
|
|
_clear_in_line 0 $_cols $sy
|
|
|
|
incr sy
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Beep.
|
|
|
|
proc _ctl_0x07 {} {
|
|
|
|
}
|
|
|
|
|
|
|
|
# Backspace.
|
|
|
|
proc _ctl_0x08 {} {
|
|
|
|
variable _cur_x
|
|
|
|
incr _cur_x -1
|
|
|
|
if {$_cur_x < 0} {
|
|
|
|
variable _cur_y
|
|
|
|
variable _cols
|
|
|
|
set _cur_x [expr {$_cols - 1}]
|
|
|
|
incr _cur_y -1
|
|
|
|
if {$_cur_y < 0} {
|
|
|
|
set _cur_y 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Linefeed.
|
|
|
|
proc _ctl_0x0a {} {
|
|
|
|
variable _cur_y
|
|
|
|
variable _rows
|
|
|
|
incr _cur_y 1
|
|
|
|
if {$_cur_y >= $_rows} {
|
|
|
|
error "FIXME scroll"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Carriage return.
|
|
|
|
proc _ctl_0x0d {} {
|
|
|
|
variable _cur_x
|
|
|
|
set _cur_x 0
|
|
|
|
}
|
|
|
|
|
2019-07-29 05:02:35 +08:00
|
|
|
# Make room for characters.
|
|
|
|
proc _csi_@ {args} {
|
|
|
|
set n [_default [lindex $args 0] 1]
|
|
|
|
variable _cur_x
|
|
|
|
variable _cur_y
|
|
|
|
variable _chars
|
|
|
|
set in_x $_cur_x
|
|
|
|
set out_x [expr {$_cur_x + $n}]
|
|
|
|
for {set i 0} {$i < $n} {incr i} {
|
|
|
|
set _chars($out_x,$_cur_y) $_chars($in_x,$_cur_y)
|
|
|
|
incr in_x
|
|
|
|
incr out_x
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-02 06:01:58 +08:00
|
|
|
# Cursor Up.
|
|
|
|
proc _csi_A {args} {
|
|
|
|
variable _cur_y
|
|
|
|
set arg [_default [lindex $args 0] 1]
|
|
|
|
set _cur_y [expr {max ($_cur_y - $arg, 0)}]
|
|
|
|
}
|
|
|
|
|
|
|
|
# Cursor Down.
|
|
|
|
proc _csi_B {args} {
|
|
|
|
variable _cur_y
|
|
|
|
variable _rows
|
|
|
|
set arg [_default [lindex $args 0] 1]
|
|
|
|
set _cur_y [expr {min ($_cur_y + $arg, $_rows)}]
|
|
|
|
}
|
|
|
|
|
|
|
|
# Cursor Forward.
|
|
|
|
proc _csi_C {args} {
|
|
|
|
variable _cur_x
|
|
|
|
variable _cols
|
|
|
|
set arg [_default [lindex $args 0] 1]
|
|
|
|
set _cur_x [expr {min ($_cur_x + $arg, $_cols)}]
|
|
|
|
}
|
|
|
|
|
|
|
|
# Cursor Back.
|
|
|
|
proc _csi_D {args} {
|
|
|
|
variable _cur_x
|
|
|
|
set arg [_default [lindex $args 0] 1]
|
|
|
|
set _cur_x [expr {max ($_cur_x - $arg, 0)}]
|
|
|
|
}
|
|
|
|
|
|
|
|
# Cursor Next Line.
|
|
|
|
proc _csi_E {args} {
|
|
|
|
variable _cur_x
|
|
|
|
variable _cur_y
|
|
|
|
variable _rows
|
|
|
|
set arg [_default [lindex $args 0] 1]
|
|
|
|
set _cur_x 0
|
|
|
|
set _cur_y [expr {min ($_cur_y + $arg, $_rows)}]
|
|
|
|
}
|
|
|
|
|
|
|
|
# Cursor Previous Line.
|
|
|
|
proc _csi_F {args} {
|
|
|
|
variable _cur_x
|
|
|
|
variable _cur_y
|
|
|
|
variable _rows
|
|
|
|
set arg [_default [lindex $args 0] 1]
|
|
|
|
set _cur_x 0
|
|
|
|
set _cur_y [expr {max ($_cur_y - $arg, 0)}]
|
|
|
|
}
|
|
|
|
|
|
|
|
# Cursor Horizontal Absolute.
|
|
|
|
proc _csi_G {args} {
|
|
|
|
variable _cur_x
|
|
|
|
variable _cols
|
|
|
|
set arg [_default [lindex $args 0] 1]
|
|
|
|
set _cur_x [expr {min ($arg - 1, $_cols)}]
|
|
|
|
}
|
|
|
|
|
|
|
|
# Move cursor (don't know the official name of this one).
|
|
|
|
proc _csi_H {args} {
|
|
|
|
variable _cur_x
|
|
|
|
variable _cur_y
|
|
|
|
set _cur_y [expr {[_default [lindex $args 0] 1] - 1}]
|
|
|
|
set _cur_x [expr {[_default [lindex $args 1] 1] - 1}]
|
|
|
|
}
|
|
|
|
|
|
|
|
# Cursor Forward Tabulation.
|
|
|
|
proc _csi_I {args} {
|
|
|
|
set n [_default [lindex $args 0] 1]
|
|
|
|
variable _cur_x
|
|
|
|
variable _cols
|
|
|
|
incr _cur_x [expr {$n * 8 - $_cur_x % 8}]
|
|
|
|
if {$_cur_x >= $_cols} {
|
|
|
|
set _cur_x [expr {$_cols - 1}]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Erase.
|
|
|
|
proc _csi_J {args} {
|
|
|
|
variable _cur_x
|
|
|
|
variable _cur_y
|
|
|
|
variable _rows
|
|
|
|
variable _cols
|
|
|
|
set arg [_default [lindex $args 0] 0]
|
|
|
|
if {$arg == 0} {
|
|
|
|
_clear_in_line $_cur_x $_cols $_cur_y
|
|
|
|
_clear_lines [expr {$_cur_y + 1}] $_rows
|
|
|
|
} elseif {$arg == 1} {
|
|
|
|
_clear_lines 0 [expr {$_cur_y - 1}]
|
|
|
|
_clear_in_line 0 $_cur_x $_cur_y
|
|
|
|
} elseif {$arg == 2} {
|
|
|
|
_clear_lines 0 $_rows
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Erase Line.
|
|
|
|
proc _csi_K {args} {
|
|
|
|
variable _cur_x
|
|
|
|
variable _cur_y
|
|
|
|
variable _cols
|
|
|
|
set arg [_default [lindex $args 0] 0]
|
|
|
|
if {$arg == 0} {
|
|
|
|
# From cursor to end.
|
|
|
|
_clear_in_line $_cur_x $_cols $_cur_y
|
|
|
|
} elseif {$arg == 1} {
|
|
|
|
_clear_in_line 0 $_cur_x $_cur_y
|
|
|
|
} elseif {$arg == 2} {
|
|
|
|
_clear_in_line 0 $_cols $_cur_y
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Delete lines.
|
|
|
|
proc _csi_M {args} {
|
|
|
|
variable _cur_y
|
|
|
|
variable _rows
|
|
|
|
variable _cols
|
|
|
|
variable _chars
|
|
|
|
set count [_default [lindex $args 0] 1]
|
|
|
|
set y $_cur_y
|
|
|
|
set next_y [expr {$y + 1}]
|
|
|
|
while {$count > 0 && $next_y < $_rows} {
|
|
|
|
for {set x 0} {$x < $_cols} {incr x} {
|
|
|
|
set _chars($x,$y) $_chars($x,$next_y)
|
|
|
|
}
|
|
|
|
incr y
|
|
|
|
incr next_y
|
|
|
|
incr count -1
|
|
|
|
}
|
|
|
|
_clear_lines $next_y $_rows
|
|
|
|
}
|
|
|
|
|
|
|
|
# Erase chars.
|
|
|
|
proc _csi_X {args} {
|
|
|
|
set n [_default [lindex $args 0] 1]
|
2019-07-29 05:02:35 +08:00
|
|
|
# Erase characters but don't move cursor.
|
|
|
|
variable _cur_x
|
|
|
|
variable _cur_y
|
|
|
|
variable _attrs
|
|
|
|
variable _chars
|
|
|
|
set lattr [array get _attrs]
|
|
|
|
set x $_cur_x
|
|
|
|
for {set i 0} {$i < $n} {incr i} {
|
|
|
|
set _chars($x,$_cur_y) [list " " $lattr]
|
|
|
|
incr x
|
|
|
|
}
|
2019-07-02 06:01:58 +08:00
|
|
|
}
|
|
|
|
|
2019-07-13 08:18:10 +08:00
|
|
|
# Backward tab stops.
|
|
|
|
proc _csi_Z {args} {
|
|
|
|
set n [_default [lindex $args 0] 1]
|
|
|
|
variable _cur_x
|
|
|
|
set _cur_x [expr {max (int (($_cur_x - 1) / 8) * 8 - ($n - 1) * 8, 0)}]
|
|
|
|
}
|
|
|
|
|
2019-07-02 06:01:58 +08:00
|
|
|
# Repeat.
|
|
|
|
proc _csi_b {args} {
|
|
|
|
variable _last_char
|
|
|
|
set n [_default [lindex $args 0] 1]
|
|
|
|
_insert [string repeat $_last_char $n]
|
|
|
|
}
|
|
|
|
|
|
|
|
# Line Position Absolute.
|
|
|
|
proc _csi_d {args} {
|
|
|
|
variable _cur_y
|
|
|
|
set _cur_y [expr {[_default [lindex $args 0] 1] - 1}]
|
|
|
|
}
|
|
|
|
|
|
|
|
# Select Graphic Rendition.
|
|
|
|
proc _csi_m {args} {
|
|
|
|
variable _attrs
|
|
|
|
foreach item $args {
|
|
|
|
switch -exact -- $item {
|
|
|
|
"" - 0 {
|
|
|
|
set _attrs(intensity) normal
|
|
|
|
set _attrs(fg) default
|
|
|
|
set _attrs(bg) default
|
|
|
|
set _attrs(underline) 0
|
|
|
|
set _attrs(reverse) 0
|
|
|
|
}
|
|
|
|
1 {
|
|
|
|
set _attrs(intensity) bold
|
|
|
|
}
|
|
|
|
2 {
|
|
|
|
set _attrs(intensity) dim
|
|
|
|
}
|
|
|
|
4 {
|
|
|
|
set _attrs(underline) 1
|
|
|
|
}
|
|
|
|
7 {
|
|
|
|
set _attrs(reverse) 1
|
|
|
|
}
|
|
|
|
22 {
|
|
|
|
set _attrs(intensity) normal
|
|
|
|
}
|
|
|
|
24 {
|
|
|
|
set _attrs(underline) 0
|
|
|
|
}
|
|
|
|
27 {
|
|
|
|
set _attrs(reverse) 1
|
|
|
|
}
|
|
|
|
30 - 31 - 32 - 33 - 34 - 35 - 36 - 37 {
|
|
|
|
set _attrs(fg) $item
|
|
|
|
}
|
|
|
|
39 {
|
|
|
|
set _attrs(fg) default
|
|
|
|
}
|
|
|
|
40 - 41 - 42 - 43 - 44 - 45 - 46 - 47 {
|
|
|
|
set _attrs(bg) $item
|
|
|
|
}
|
|
|
|
49 {
|
|
|
|
set _attrs(bg) default
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Insert string at the cursor location.
|
|
|
|
proc _insert {str} {
|
|
|
|
verbose "INSERT <<$str>>"
|
|
|
|
variable _cur_x
|
|
|
|
variable _cur_y
|
|
|
|
variable _rows
|
|
|
|
variable _cols
|
|
|
|
variable _attrs
|
|
|
|
variable _chars
|
|
|
|
set lattr [array get _attrs]
|
|
|
|
foreach char [split $str {}] {
|
|
|
|
set _chars($_cur_x,$_cur_y) [list $char $lattr]
|
|
|
|
incr _cur_x
|
|
|
|
if {$_cur_x >= $_cols} {
|
|
|
|
set _cur_x 0
|
|
|
|
incr _cur_y
|
|
|
|
if {$_cur_y >= $_rows} {
|
|
|
|
error "FIXME scroll"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Initialize.
|
|
|
|
proc _setup {rows cols} {
|
|
|
|
global stty_init
|
|
|
|
set stty_init "rows $rows columns $cols"
|
|
|
|
|
|
|
|
variable _rows
|
|
|
|
variable _cols
|
|
|
|
variable _cur_x
|
|
|
|
variable _cur_y
|
|
|
|
variable _attrs
|
Make TUI resizing tests more robust
As Sergio pointed out, the TUI resizing tests are flaky. Debugging
this showed three main problems.
1. expect's "stty" command processes its arguments one-by-one. So,
rather than requesting a single resize, it sends two separate resize
requests (one for rows and one for columns). This means gdb sees two
SIGWINCH signals and resizes the terminal twice.
I consider this a bug in expect, but I couldn't readily see how to
report a bug; and anyway the fix wouldn't propagate very quickly.
This patch works around this problem by explicitly doing two separate
resizes (so it will be robust if expect ever does change); and then by
waiting for each resize to complete before continuing.
2. gdb uses curses to drive the console rendering. Currently the test
suite looks for terminal text insertion sequences to decide when a
command has completed. However, it turns out that, sometimes, curses
can output things in non-obvious ways. I didn't debug into curses but
I guess this can happen due to output optimizations. No matter the
reason, sometimes the current approach of only tracking text
insertions is not enough to detect that gdb has finished rendering.
This patch fixes this problem by arranging to detect the termination
output after any curses command, not just insertion.
3. Detecting when a resize has completed is tricky. In fact, I could
not find a way to reliably do this.
This patch fixes this problem by adding a special maint
"tui-resize-message" setting to gdb. When this is enabled, gdb will
print a message after each SIGWINCH has been fully processed. The
test suite enables this mode and then waits for the message in order
to know when control can be returned to the calling test.
This patch also adds a timeout, to avoid the situation where the
terminal code fails to notice a change for some reason. This lets the
test at least try to continue.
gdb/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* tui/tui-win.c (resize_message): New global.
(show_tui_resize_message): New function.
(tui_async_resize_screen): Print message if requested.
(_initialize_tui_win): Add tui-resize-message setting.
* NEWS: Add entry for new commands.
gdb/doc/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* gdb.texinfo (Maintenance Commands): Document new command.
gdb/testsuite/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* lib/tuiterm.exp (_accept): Add wait_for parameter. Check output
after any command. Expect prompt after WAIT_FOR is seen.
(enter_tui): Enable resize messages.
(command): Expect command in output.
(get_line): Avoid error when cursor appears to be off-screen.
(dump_screen): Include screen size in title.
(_do_resize): New proc, from "resize".
(resize): Rewrite. Do resize in two steps.
* gdb.tui/empty.exp (layouts): Fix entries.
(check_boxes): Remove xfail.
(check_text): Dump screen on failure.
Change-Id: I420e0259cb99b21adcd28f671b99161eefa7a51d
2019-08-17 05:16:12 +08:00
|
|
|
variable _resize_count
|
2019-07-02 06:01:58 +08:00
|
|
|
|
|
|
|
set _rows $rows
|
|
|
|
set _cols $cols
|
|
|
|
set _cur_x 0
|
|
|
|
set _cur_y 0
|
Make TUI resizing tests more robust
As Sergio pointed out, the TUI resizing tests are flaky. Debugging
this showed three main problems.
1. expect's "stty" command processes its arguments one-by-one. So,
rather than requesting a single resize, it sends two separate resize
requests (one for rows and one for columns). This means gdb sees two
SIGWINCH signals and resizes the terminal twice.
I consider this a bug in expect, but I couldn't readily see how to
report a bug; and anyway the fix wouldn't propagate very quickly.
This patch works around this problem by explicitly doing two separate
resizes (so it will be robust if expect ever does change); and then by
waiting for each resize to complete before continuing.
2. gdb uses curses to drive the console rendering. Currently the test
suite looks for terminal text insertion sequences to decide when a
command has completed. However, it turns out that, sometimes, curses
can output things in non-obvious ways. I didn't debug into curses but
I guess this can happen due to output optimizations. No matter the
reason, sometimes the current approach of only tracking text
insertions is not enough to detect that gdb has finished rendering.
This patch fixes this problem by arranging to detect the termination
output after any curses command, not just insertion.
3. Detecting when a resize has completed is tricky. In fact, I could
not find a way to reliably do this.
This patch fixes this problem by adding a special maint
"tui-resize-message" setting to gdb. When this is enabled, gdb will
print a message after each SIGWINCH has been fully processed. The
test suite enables this mode and then waits for the message in order
to know when control can be returned to the calling test.
This patch also adds a timeout, to avoid the situation where the
terminal code fails to notice a change for some reason. This lets the
test at least try to continue.
gdb/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* tui/tui-win.c (resize_message): New global.
(show_tui_resize_message): New function.
(tui_async_resize_screen): Print message if requested.
(_initialize_tui_win): Add tui-resize-message setting.
* NEWS: Add entry for new commands.
gdb/doc/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* gdb.texinfo (Maintenance Commands): Document new command.
gdb/testsuite/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* lib/tuiterm.exp (_accept): Add wait_for parameter. Check output
after any command. Expect prompt after WAIT_FOR is seen.
(enter_tui): Enable resize messages.
(command): Expect command in output.
(get_line): Avoid error when cursor appears to be off-screen.
(dump_screen): Include screen size in title.
(_do_resize): New proc, from "resize".
(resize): Rewrite. Do resize in two steps.
* gdb.tui/empty.exp (layouts): Fix entries.
(check_boxes): Remove xfail.
(check_text): Dump screen on failure.
Change-Id: I420e0259cb99b21adcd28f671b99161eefa7a51d
2019-08-17 05:16:12 +08:00
|
|
|
set _resize_count 0
|
2019-07-02 06:01:58 +08:00
|
|
|
array set _attrs {
|
|
|
|
intensity normal
|
|
|
|
fg default
|
|
|
|
bg default
|
|
|
|
underline 0
|
|
|
|
reverse 0
|
|
|
|
}
|
|
|
|
|
|
|
|
_clear_lines 0 $_rows
|
|
|
|
}
|
|
|
|
|
2019-12-23 07:52:56 +08:00
|
|
|
# Accept some output from gdb and update the screen. WAIT_FOR is
|
|
|
|
# a regexp matching the line to wait for. Return 0 on timeout, 1
|
|
|
|
# on success.
|
|
|
|
proc wait_for {wait_for} {
|
2019-07-02 06:01:58 +08:00
|
|
|
global expect_out
|
Make TUI resizing tests more robust
As Sergio pointed out, the TUI resizing tests are flaky. Debugging
this showed three main problems.
1. expect's "stty" command processes its arguments one-by-one. So,
rather than requesting a single resize, it sends two separate resize
requests (one for rows and one for columns). This means gdb sees two
SIGWINCH signals and resizes the terminal twice.
I consider this a bug in expect, but I couldn't readily see how to
report a bug; and anyway the fix wouldn't propagate very quickly.
This patch works around this problem by explicitly doing two separate
resizes (so it will be robust if expect ever does change); and then by
waiting for each resize to complete before continuing.
2. gdb uses curses to drive the console rendering. Currently the test
suite looks for terminal text insertion sequences to decide when a
command has completed. However, it turns out that, sometimes, curses
can output things in non-obvious ways. I didn't debug into curses but
I guess this can happen due to output optimizations. No matter the
reason, sometimes the current approach of only tracking text
insertions is not enough to detect that gdb has finished rendering.
This patch fixes this problem by arranging to detect the termination
output after any curses command, not just insertion.
3. Detecting when a resize has completed is tricky. In fact, I could
not find a way to reliably do this.
This patch fixes this problem by adding a special maint
"tui-resize-message" setting to gdb. When this is enabled, gdb will
print a message after each SIGWINCH has been fully processed. The
test suite enables this mode and then waits for the message in order
to know when control can be returned to the calling test.
This patch also adds a timeout, to avoid the situation where the
terminal code fails to notice a change for some reason. This lets the
test at least try to continue.
gdb/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* tui/tui-win.c (resize_message): New global.
(show_tui_resize_message): New function.
(tui_async_resize_screen): Print message if requested.
(_initialize_tui_win): Add tui-resize-message setting.
* NEWS: Add entry for new commands.
gdb/doc/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* gdb.texinfo (Maintenance Commands): Document new command.
gdb/testsuite/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* lib/tuiterm.exp (_accept): Add wait_for parameter. Check output
after any command. Expect prompt after WAIT_FOR is seen.
(enter_tui): Enable resize messages.
(command): Expect command in output.
(get_line): Avoid error when cursor appears to be off-screen.
(dump_screen): Include screen size in title.
(_do_resize): New proc, from "resize".
(resize): Rewrite. Do resize in two steps.
* gdb.tui/empty.exp (layouts): Fix entries.
(check_boxes): Remove xfail.
(check_text): Dump screen on failure.
Change-Id: I420e0259cb99b21adcd28f671b99161eefa7a51d
2019-08-17 05:16:12 +08:00
|
|
|
global gdb_prompt
|
|
|
|
variable _cur_x
|
|
|
|
variable _cur_y
|
|
|
|
|
|
|
|
set prompt_wait_for "$gdb_prompt \$"
|
|
|
|
|
|
|
|
while 1 {
|
|
|
|
gdb_expect {
|
|
|
|
-re "^\[\x07\x08\x0a\x0d\]" {
|
|
|
|
scan $expect_out(0,string) %c val
|
|
|
|
set hexval [format "%02x" $val]
|
|
|
|
verbose "+++ _ctl_0x${hexval}"
|
|
|
|
_ctl_0x${hexval}
|
|
|
|
}
|
|
|
|
-re "^\x1b(\[0-9a-zA-Z\])" {
|
|
|
|
verbose "+++ unsupported escape"
|
|
|
|
error "unsupported escape"
|
|
|
|
}
|
|
|
|
-re "^\x1b\\\[(\[0-9;\]*)(\[a-zA-Z@\])" {
|
|
|
|
set cmd $expect_out(2,string)
|
|
|
|
set params [split $expect_out(1,string) ";"]
|
|
|
|
verbose "+++ _csi_$cmd <<<$expect_out(1,string)>>>"
|
|
|
|
eval _csi_$cmd $params
|
|
|
|
}
|
|
|
|
-re "^\[^\x07\x08\x0a\x0d\x1b\]+" {
|
|
|
|
_insert $expect_out(0,string)
|
|
|
|
variable _last_char
|
|
|
|
set _last_char [string index $expect_out(0,string) end]
|
|
|
|
}
|
|
|
|
|
|
|
|
timeout {
|
|
|
|
# Assume a timeout means we somehow missed the
|
|
|
|
# expected result, and carry on.
|
2019-12-23 07:52:56 +08:00
|
|
|
return 0
|
Make TUI resizing tests more robust
As Sergio pointed out, the TUI resizing tests are flaky. Debugging
this showed three main problems.
1. expect's "stty" command processes its arguments one-by-one. So,
rather than requesting a single resize, it sends two separate resize
requests (one for rows and one for columns). This means gdb sees two
SIGWINCH signals and resizes the terminal twice.
I consider this a bug in expect, but I couldn't readily see how to
report a bug; and anyway the fix wouldn't propagate very quickly.
This patch works around this problem by explicitly doing two separate
resizes (so it will be robust if expect ever does change); and then by
waiting for each resize to complete before continuing.
2. gdb uses curses to drive the console rendering. Currently the test
suite looks for terminal text insertion sequences to decide when a
command has completed. However, it turns out that, sometimes, curses
can output things in non-obvious ways. I didn't debug into curses but
I guess this can happen due to output optimizations. No matter the
reason, sometimes the current approach of only tracking text
insertions is not enough to detect that gdb has finished rendering.
This patch fixes this problem by arranging to detect the termination
output after any curses command, not just insertion.
3. Detecting when a resize has completed is tricky. In fact, I could
not find a way to reliably do this.
This patch fixes this problem by adding a special maint
"tui-resize-message" setting to gdb. When this is enabled, gdb will
print a message after each SIGWINCH has been fully processed. The
test suite enables this mode and then waits for the message in order
to know when control can be returned to the calling test.
This patch also adds a timeout, to avoid the situation where the
terminal code fails to notice a change for some reason. This lets the
test at least try to continue.
gdb/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* tui/tui-win.c (resize_message): New global.
(show_tui_resize_message): New function.
(tui_async_resize_screen): Print message if requested.
(_initialize_tui_win): Add tui-resize-message setting.
* NEWS: Add entry for new commands.
gdb/doc/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* gdb.texinfo (Maintenance Commands): Document new command.
gdb/testsuite/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* lib/tuiterm.exp (_accept): Add wait_for parameter. Check output
after any command. Expect prompt after WAIT_FOR is seen.
(enter_tui): Enable resize messages.
(command): Expect command in output.
(get_line): Avoid error when cursor appears to be off-screen.
(dump_screen): Include screen size in title.
(_do_resize): New proc, from "resize".
(resize): Rewrite. Do resize in two steps.
* gdb.tui/empty.exp (layouts): Fix entries.
(check_boxes): Remove xfail.
(check_text): Dump screen on failure.
Change-Id: I420e0259cb99b21adcd28f671b99161eefa7a51d
2019-08-17 05:16:12 +08:00
|
|
|
}
|
2019-07-02 06:01:58 +08:00
|
|
|
}
|
Make TUI resizing tests more robust
As Sergio pointed out, the TUI resizing tests are flaky. Debugging
this showed three main problems.
1. expect's "stty" command processes its arguments one-by-one. So,
rather than requesting a single resize, it sends two separate resize
requests (one for rows and one for columns). This means gdb sees two
SIGWINCH signals and resizes the terminal twice.
I consider this a bug in expect, but I couldn't readily see how to
report a bug; and anyway the fix wouldn't propagate very quickly.
This patch works around this problem by explicitly doing two separate
resizes (so it will be robust if expect ever does change); and then by
waiting for each resize to complete before continuing.
2. gdb uses curses to drive the console rendering. Currently the test
suite looks for terminal text insertion sequences to decide when a
command has completed. However, it turns out that, sometimes, curses
can output things in non-obvious ways. I didn't debug into curses but
I guess this can happen due to output optimizations. No matter the
reason, sometimes the current approach of only tracking text
insertions is not enough to detect that gdb has finished rendering.
This patch fixes this problem by arranging to detect the termination
output after any curses command, not just insertion.
3. Detecting when a resize has completed is tricky. In fact, I could
not find a way to reliably do this.
This patch fixes this problem by adding a special maint
"tui-resize-message" setting to gdb. When this is enabled, gdb will
print a message after each SIGWINCH has been fully processed. The
test suite enables this mode and then waits for the message in order
to know when control can be returned to the calling test.
This patch also adds a timeout, to avoid the situation where the
terminal code fails to notice a change for some reason. This lets the
test at least try to continue.
gdb/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* tui/tui-win.c (resize_message): New global.
(show_tui_resize_message): New function.
(tui_async_resize_screen): Print message if requested.
(_initialize_tui_win): Add tui-resize-message setting.
* NEWS: Add entry for new commands.
gdb/doc/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* gdb.texinfo (Maintenance Commands): Document new command.
gdb/testsuite/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* lib/tuiterm.exp (_accept): Add wait_for parameter. Check output
after any command. Expect prompt after WAIT_FOR is seen.
(enter_tui): Enable resize messages.
(command): Expect command in output.
(get_line): Avoid error when cursor appears to be off-screen.
(dump_screen): Include screen size in title.
(_do_resize): New proc, from "resize".
(resize): Rewrite. Do resize in two steps.
* gdb.tui/empty.exp (layouts): Fix entries.
(check_boxes): Remove xfail.
(check_text): Dump screen on failure.
Change-Id: I420e0259cb99b21adcd28f671b99161eefa7a51d
2019-08-17 05:16:12 +08:00
|
|
|
|
|
|
|
# If the cursor appears just after the prompt, return. It
|
|
|
|
# isn't reliable to check this only after an insertion,
|
|
|
|
# because curses may make "unusual" redrawing decisions.
|
|
|
|
if {$wait_for == "$prompt_wait_for"} {
|
2019-07-02 06:01:58 +08:00
|
|
|
set prev [get_line $_cur_y $_cur_x]
|
Make TUI resizing tests more robust
As Sergio pointed out, the TUI resizing tests are flaky. Debugging
this showed three main problems.
1. expect's "stty" command processes its arguments one-by-one. So,
rather than requesting a single resize, it sends two separate resize
requests (one for rows and one for columns). This means gdb sees two
SIGWINCH signals and resizes the terminal twice.
I consider this a bug in expect, but I couldn't readily see how to
report a bug; and anyway the fix wouldn't propagate very quickly.
This patch works around this problem by explicitly doing two separate
resizes (so it will be robust if expect ever does change); and then by
waiting for each resize to complete before continuing.
2. gdb uses curses to drive the console rendering. Currently the test
suite looks for terminal text insertion sequences to decide when a
command has completed. However, it turns out that, sometimes, curses
can output things in non-obvious ways. I didn't debug into curses but
I guess this can happen due to output optimizations. No matter the
reason, sometimes the current approach of only tracking text
insertions is not enough to detect that gdb has finished rendering.
This patch fixes this problem by arranging to detect the termination
output after any curses command, not just insertion.
3. Detecting when a resize has completed is tricky. In fact, I could
not find a way to reliably do this.
This patch fixes this problem by adding a special maint
"tui-resize-message" setting to gdb. When this is enabled, gdb will
print a message after each SIGWINCH has been fully processed. The
test suite enables this mode and then waits for the message in order
to know when control can be returned to the calling test.
This patch also adds a timeout, to avoid the situation where the
terminal code fails to notice a change for some reason. This lets the
test at least try to continue.
gdb/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* tui/tui-win.c (resize_message): New global.
(show_tui_resize_message): New function.
(tui_async_resize_screen): Print message if requested.
(_initialize_tui_win): Add tui-resize-message setting.
* NEWS: Add entry for new commands.
gdb/doc/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* gdb.texinfo (Maintenance Commands): Document new command.
gdb/testsuite/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* lib/tuiterm.exp (_accept): Add wait_for parameter. Check output
after any command. Expect prompt after WAIT_FOR is seen.
(enter_tui): Enable resize messages.
(command): Expect command in output.
(get_line): Avoid error when cursor appears to be off-screen.
(dump_screen): Include screen size in title.
(_do_resize): New proc, from "resize".
(resize): Rewrite. Do resize in two steps.
* gdb.tui/empty.exp (layouts): Fix entries.
(check_boxes): Remove xfail.
(check_text): Dump screen on failure.
Change-Id: I420e0259cb99b21adcd28f671b99161eefa7a51d
2019-08-17 05:16:12 +08:00
|
|
|
} else {
|
|
|
|
set prev [get_line $_cur_y]
|
|
|
|
}
|
|
|
|
if {[regexp -- $wait_for $prev]} {
|
|
|
|
if {$wait_for == "$prompt_wait_for"} {
|
|
|
|
break
|
2019-07-02 06:01:58 +08:00
|
|
|
}
|
Make TUI resizing tests more robust
As Sergio pointed out, the TUI resizing tests are flaky. Debugging
this showed three main problems.
1. expect's "stty" command processes its arguments one-by-one. So,
rather than requesting a single resize, it sends two separate resize
requests (one for rows and one for columns). This means gdb sees two
SIGWINCH signals and resizes the terminal twice.
I consider this a bug in expect, but I couldn't readily see how to
report a bug; and anyway the fix wouldn't propagate very quickly.
This patch works around this problem by explicitly doing two separate
resizes (so it will be robust if expect ever does change); and then by
waiting for each resize to complete before continuing.
2. gdb uses curses to drive the console rendering. Currently the test
suite looks for terminal text insertion sequences to decide when a
command has completed. However, it turns out that, sometimes, curses
can output things in non-obvious ways. I didn't debug into curses but
I guess this can happen due to output optimizations. No matter the
reason, sometimes the current approach of only tracking text
insertions is not enough to detect that gdb has finished rendering.
This patch fixes this problem by arranging to detect the termination
output after any curses command, not just insertion.
3. Detecting when a resize has completed is tricky. In fact, I could
not find a way to reliably do this.
This patch fixes this problem by adding a special maint
"tui-resize-message" setting to gdb. When this is enabled, gdb will
print a message after each SIGWINCH has been fully processed. The
test suite enables this mode and then waits for the message in order
to know when control can be returned to the calling test.
This patch also adds a timeout, to avoid the situation where the
terminal code fails to notice a change for some reason. This lets the
test at least try to continue.
gdb/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* tui/tui-win.c (resize_message): New global.
(show_tui_resize_message): New function.
(tui_async_resize_screen): Print message if requested.
(_initialize_tui_win): Add tui-resize-message setting.
* NEWS: Add entry for new commands.
gdb/doc/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* gdb.texinfo (Maintenance Commands): Document new command.
gdb/testsuite/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* lib/tuiterm.exp (_accept): Add wait_for parameter. Check output
after any command. Expect prompt after WAIT_FOR is seen.
(enter_tui): Enable resize messages.
(command): Expect command in output.
(get_line): Avoid error when cursor appears to be off-screen.
(dump_screen): Include screen size in title.
(_do_resize): New proc, from "resize".
(resize): Rewrite. Do resize in two steps.
* gdb.tui/empty.exp (layouts): Fix entries.
(check_boxes): Remove xfail.
(check_text): Dump screen on failure.
Change-Id: I420e0259cb99b21adcd28f671b99161eefa7a51d
2019-08-17 05:16:12 +08:00
|
|
|
set wait_for $prompt_wait_for
|
2019-07-02 06:01:58 +08:00
|
|
|
}
|
|
|
|
}
|
2019-12-23 07:52:56 +08:00
|
|
|
|
|
|
|
return 1
|
2019-07-02 06:01:58 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
# Like ::clean_restart, but ensures that gdb starts in an
|
|
|
|
# environment where the TUI can work. ROWS and COLS are the size
|
2019-07-21 04:46:29 +08:00
|
|
|
# of the terminal. EXECUTABLE, if given, is passed to
|
|
|
|
# clean_restart.
|
|
|
|
proc clean_restart {rows cols {executable {}}} {
|
2019-07-02 06:01:58 +08:00
|
|
|
global env stty_init
|
|
|
|
save_vars {env(TERM) stty_init} {
|
|
|
|
setenv TERM ansi
|
|
|
|
_setup $rows $cols
|
2019-07-21 04:46:29 +08:00
|
|
|
if {$executable == ""} {
|
|
|
|
::clean_restart
|
|
|
|
} else {
|
|
|
|
::clean_restart $executable
|
|
|
|
}
|
2019-07-02 06:01:58 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-07 08:30:35 +08:00
|
|
|
# Setup ready for starting the tui, but don't actually start it.
|
|
|
|
# Returns 1 on success, 0 if TUI tests should be skipped.
|
|
|
|
proc prepare_for_tui {} {
|
2019-07-02 06:01:58 +08:00
|
|
|
if {[skip_tui_tests]} {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
gdb_test_no_output "set tui border-kind ascii"
|
Make TUI resizing tests more robust
As Sergio pointed out, the TUI resizing tests are flaky. Debugging
this showed three main problems.
1. expect's "stty" command processes its arguments one-by-one. So,
rather than requesting a single resize, it sends two separate resize
requests (one for rows and one for columns). This means gdb sees two
SIGWINCH signals and resizes the terminal twice.
I consider this a bug in expect, but I couldn't readily see how to
report a bug; and anyway the fix wouldn't propagate very quickly.
This patch works around this problem by explicitly doing two separate
resizes (so it will be robust if expect ever does change); and then by
waiting for each resize to complete before continuing.
2. gdb uses curses to drive the console rendering. Currently the test
suite looks for terminal text insertion sequences to decide when a
command has completed. However, it turns out that, sometimes, curses
can output things in non-obvious ways. I didn't debug into curses but
I guess this can happen due to output optimizations. No matter the
reason, sometimes the current approach of only tracking text
insertions is not enough to detect that gdb has finished rendering.
This patch fixes this problem by arranging to detect the termination
output after any curses command, not just insertion.
3. Detecting when a resize has completed is tricky. In fact, I could
not find a way to reliably do this.
This patch fixes this problem by adding a special maint
"tui-resize-message" setting to gdb. When this is enabled, gdb will
print a message after each SIGWINCH has been fully processed. The
test suite enables this mode and then waits for the message in order
to know when control can be returned to the calling test.
This patch also adds a timeout, to avoid the situation where the
terminal code fails to notice a change for some reason. This lets the
test at least try to continue.
gdb/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* tui/tui-win.c (resize_message): New global.
(show_tui_resize_message): New function.
(tui_async_resize_screen): Print message if requested.
(_initialize_tui_win): Add tui-resize-message setting.
* NEWS: Add entry for new commands.
gdb/doc/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* gdb.texinfo (Maintenance Commands): Document new command.
gdb/testsuite/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* lib/tuiterm.exp (_accept): Add wait_for parameter. Check output
after any command. Expect prompt after WAIT_FOR is seen.
(enter_tui): Enable resize messages.
(command): Expect command in output.
(get_line): Avoid error when cursor appears to be off-screen.
(dump_screen): Include screen size in title.
(_do_resize): New proc, from "resize".
(resize): Rewrite. Do resize in two steps.
* gdb.tui/empty.exp (layouts): Fix entries.
(check_boxes): Remove xfail.
(check_text): Dump screen on failure.
Change-Id: I420e0259cb99b21adcd28f671b99161eefa7a51d
2019-08-17 05:16:12 +08:00
|
|
|
gdb_test_no_output "maint set tui-resize-message on"
|
2020-01-07 08:30:35 +08:00
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
# Start the TUI. Returns 1 on success, 0 if TUI tests should be
|
|
|
|
# skipped.
|
|
|
|
proc enter_tui {} {
|
|
|
|
if {![prepare_for_tui]} {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
[gdb/testsuite] Fix check-read1 FAIL in gdb.tui/corefile-run.exp
With test-case gdb.tui/corefile-run.exp and make target check-read1, I run
into:
...
FAIL: gdb.tui/corefile-run.exp: run until the end
...
In more detail, using -v:
...
PASS: gdb.tui/corefile-run.exp: load corefile
^M+++ _ctl_0x0d
^[[17d+++ _csi_d <<<17>>>
^[[M+++ _csi_M <<<>>>
^[[24d+++ _csi_d <<<24>>>
(INSERT <<(>>
gINSERT <<g>>
dINSERT <<d>>
bINSERT <<b>>
)INSERT <<)>>
INSERT << >>
FAIL: gdb.tui/corefile-run.exp: run until the end
...
With some debugging code added in wait_for, what happens becomes more clear:
...
if {[regexp -- $wait_for $prev]} {
+ verbose -log "\nwait_for: MATCHED line ($_cur_y): \"$prev\""
+ verbose -log "wait_for: AGAINST regexp: \"$wait_for\""
...
In corefile-run.exp, we execute:
...
Term::command "run"
...
and in proc Term::command, we send the command, and then call wait_for:
...
proc command {cmd} {
send_gdb "$cmd\n"
wait_for [string_to_regexp $cmd]
}
...
which first waits for the command string, and then for the prompt.
In this case however, the matching of the command string triggers on a
previous line:
...
wait_for: MATCHED line (16): \
"(gdb) core-file corefile-run.core[New LWP 6426] <lots-of-spaces>"
wait_for: AGAINST regexp: "run"
...
and from there on things go out of sync, eventually resulting in the FAIL.
Fix this in proc command by more precisely specifying the expected pattern:
adding a ^$gdb_prompt prefix.
Add a command_no_prompt_prefix variant to use for initial terminal commands
where there's no prompt yet.
Tested gdb.tui/*.exp on x86_64-linux, with make target check and check-read1.
gdb/testsuite/ChangeLog:
2020-03-13 Tom de Vries <tdevries@suse.de>
* lib/tuiterm.exp (Term::command_no_prompt_prefix): New proc.
(Term::command): Use prompt prefix.
(Term::enter_tui): Use command_no_prompt_prefix instead of prefix.
* gdb.tui/tui-layout-asm-short-prog.exp: Use
command_no_prompt_prefix instead of prefix.
* gdb.tui/tui-layout-asm.exp: Same.
2020-03-13 07:31:15 +08:00
|
|
|
command_no_prompt_prefix "tui enable"
|
2019-07-02 06:01:58 +08:00
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
# Send the command CMD to gdb, then wait for a gdb prompt to be
|
|
|
|
# seen in the TUI. CMD should not end with a newline -- that will
|
|
|
|
# be supplied by this function.
|
|
|
|
proc command {cmd} {
|
[gdb/testsuite] Fix check-read1 FAIL in gdb.tui/corefile-run.exp
With test-case gdb.tui/corefile-run.exp and make target check-read1, I run
into:
...
FAIL: gdb.tui/corefile-run.exp: run until the end
...
In more detail, using -v:
...
PASS: gdb.tui/corefile-run.exp: load corefile
^M+++ _ctl_0x0d
^[[17d+++ _csi_d <<<17>>>
^[[M+++ _csi_M <<<>>>
^[[24d+++ _csi_d <<<24>>>
(INSERT <<(>>
gINSERT <<g>>
dINSERT <<d>>
bINSERT <<b>>
)INSERT <<)>>
INSERT << >>
FAIL: gdb.tui/corefile-run.exp: run until the end
...
With some debugging code added in wait_for, what happens becomes more clear:
...
if {[regexp -- $wait_for $prev]} {
+ verbose -log "\nwait_for: MATCHED line ($_cur_y): \"$prev\""
+ verbose -log "wait_for: AGAINST regexp: \"$wait_for\""
...
In corefile-run.exp, we execute:
...
Term::command "run"
...
and in proc Term::command, we send the command, and then call wait_for:
...
proc command {cmd} {
send_gdb "$cmd\n"
wait_for [string_to_regexp $cmd]
}
...
which first waits for the command string, and then for the prompt.
In this case however, the matching of the command string triggers on a
previous line:
...
wait_for: MATCHED line (16): \
"(gdb) core-file corefile-run.core[New LWP 6426] <lots-of-spaces>"
wait_for: AGAINST regexp: "run"
...
and from there on things go out of sync, eventually resulting in the FAIL.
Fix this in proc command by more precisely specifying the expected pattern:
adding a ^$gdb_prompt prefix.
Add a command_no_prompt_prefix variant to use for initial terminal commands
where there's no prompt yet.
Tested gdb.tui/*.exp on x86_64-linux, with make target check and check-read1.
gdb/testsuite/ChangeLog:
2020-03-13 Tom de Vries <tdevries@suse.de>
* lib/tuiterm.exp (Term::command_no_prompt_prefix): New proc.
(Term::command): Use prompt prefix.
(Term::enter_tui): Use command_no_prompt_prefix instead of prefix.
* gdb.tui/tui-layout-asm-short-prog.exp: Use
command_no_prompt_prefix instead of prefix.
* gdb.tui/tui-layout-asm.exp: Same.
2020-03-13 07:31:15 +08:00
|
|
|
global gdb_prompt
|
|
|
|
send_gdb "$cmd\n"
|
|
|
|
set str [string_to_regexp $cmd]
|
|
|
|
set str "^$gdb_prompt $str"
|
|
|
|
wait_for $str
|
|
|
|
}
|
|
|
|
|
|
|
|
# As proc command, but don't wait for a initial prompt. This is used for
|
|
|
|
# inital terminal commands, where there's no prompt yet.
|
|
|
|
proc command_no_prompt_prefix {cmd} {
|
2019-07-02 06:01:58 +08:00
|
|
|
send_gdb "$cmd\n"
|
[gdb/testsuite] Fix check-read1 FAIL in gdb.tui/corefile-run.exp
With test-case gdb.tui/corefile-run.exp and make target check-read1, I run
into:
...
FAIL: gdb.tui/corefile-run.exp: run until the end
...
In more detail, using -v:
...
PASS: gdb.tui/corefile-run.exp: load corefile
^M+++ _ctl_0x0d
^[[17d+++ _csi_d <<<17>>>
^[[M+++ _csi_M <<<>>>
^[[24d+++ _csi_d <<<24>>>
(INSERT <<(>>
gINSERT <<g>>
dINSERT <<d>>
bINSERT <<b>>
)INSERT <<)>>
INSERT << >>
FAIL: gdb.tui/corefile-run.exp: run until the end
...
With some debugging code added in wait_for, what happens becomes more clear:
...
if {[regexp -- $wait_for $prev]} {
+ verbose -log "\nwait_for: MATCHED line ($_cur_y): \"$prev\""
+ verbose -log "wait_for: AGAINST regexp: \"$wait_for\""
...
In corefile-run.exp, we execute:
...
Term::command "run"
...
and in proc Term::command, we send the command, and then call wait_for:
...
proc command {cmd} {
send_gdb "$cmd\n"
wait_for [string_to_regexp $cmd]
}
...
which first waits for the command string, and then for the prompt.
In this case however, the matching of the command string triggers on a
previous line:
...
wait_for: MATCHED line (16): \
"(gdb) core-file corefile-run.core[New LWP 6426] <lots-of-spaces>"
wait_for: AGAINST regexp: "run"
...
and from there on things go out of sync, eventually resulting in the FAIL.
Fix this in proc command by more precisely specifying the expected pattern:
adding a ^$gdb_prompt prefix.
Add a command_no_prompt_prefix variant to use for initial terminal commands
where there's no prompt yet.
Tested gdb.tui/*.exp on x86_64-linux, with make target check and check-read1.
gdb/testsuite/ChangeLog:
2020-03-13 Tom de Vries <tdevries@suse.de>
* lib/tuiterm.exp (Term::command_no_prompt_prefix): New proc.
(Term::command): Use prompt prefix.
(Term::enter_tui): Use command_no_prompt_prefix instead of prefix.
* gdb.tui/tui-layout-asm-short-prog.exp: Use
command_no_prompt_prefix instead of prefix.
* gdb.tui/tui-layout-asm.exp: Same.
2020-03-13 07:31:15 +08:00
|
|
|
set str [string_to_regexp $cmd]
|
|
|
|
wait_for "^$str"
|
2019-07-02 06:01:58 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
# Return the text of screen line N, without attributes. Lines are
|
|
|
|
# 0-based. If C is given, stop before column C. Columns are also
|
|
|
|
# zero-based.
|
|
|
|
proc get_line {n {c ""}} {
|
Make TUI resizing tests more robust
As Sergio pointed out, the TUI resizing tests are flaky. Debugging
this showed three main problems.
1. expect's "stty" command processes its arguments one-by-one. So,
rather than requesting a single resize, it sends two separate resize
requests (one for rows and one for columns). This means gdb sees two
SIGWINCH signals and resizes the terminal twice.
I consider this a bug in expect, but I couldn't readily see how to
report a bug; and anyway the fix wouldn't propagate very quickly.
This patch works around this problem by explicitly doing two separate
resizes (so it will be robust if expect ever does change); and then by
waiting for each resize to complete before continuing.
2. gdb uses curses to drive the console rendering. Currently the test
suite looks for terminal text insertion sequences to decide when a
command has completed. However, it turns out that, sometimes, curses
can output things in non-obvious ways. I didn't debug into curses but
I guess this can happen due to output optimizations. No matter the
reason, sometimes the current approach of only tracking text
insertions is not enough to detect that gdb has finished rendering.
This patch fixes this problem by arranging to detect the termination
output after any curses command, not just insertion.
3. Detecting when a resize has completed is tricky. In fact, I could
not find a way to reliably do this.
This patch fixes this problem by adding a special maint
"tui-resize-message" setting to gdb. When this is enabled, gdb will
print a message after each SIGWINCH has been fully processed. The
test suite enables this mode and then waits for the message in order
to know when control can be returned to the calling test.
This patch also adds a timeout, to avoid the situation where the
terminal code fails to notice a change for some reason. This lets the
test at least try to continue.
gdb/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* tui/tui-win.c (resize_message): New global.
(show_tui_resize_message): New function.
(tui_async_resize_screen): Print message if requested.
(_initialize_tui_win): Add tui-resize-message setting.
* NEWS: Add entry for new commands.
gdb/doc/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* gdb.texinfo (Maintenance Commands): Document new command.
gdb/testsuite/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* lib/tuiterm.exp (_accept): Add wait_for parameter. Check output
after any command. Expect prompt after WAIT_FOR is seen.
(enter_tui): Enable resize messages.
(command): Expect command in output.
(get_line): Avoid error when cursor appears to be off-screen.
(dump_screen): Include screen size in title.
(_do_resize): New proc, from "resize".
(resize): Rewrite. Do resize in two steps.
* gdb.tui/empty.exp (layouts): Fix entries.
(check_boxes): Remove xfail.
(check_text): Dump screen on failure.
Change-Id: I420e0259cb99b21adcd28f671b99161eefa7a51d
2019-08-17 05:16:12 +08:00
|
|
|
variable _rows
|
|
|
|
# This can happen during resizing, if the cursor seems to
|
|
|
|
# temporarily be off-screen.
|
|
|
|
if {$n >= $_rows} {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
2019-07-02 06:01:58 +08:00
|
|
|
set result ""
|
|
|
|
variable _cols
|
|
|
|
variable _chars
|
|
|
|
set c [_default $c $_cols]
|
|
|
|
set x 0
|
|
|
|
while {$x < $c} {
|
|
|
|
append result [lindex $_chars($x,$n) 0]
|
|
|
|
incr x
|
|
|
|
}
|
|
|
|
return $result
|
|
|
|
}
|
|
|
|
|
|
|
|
# Get just the character at (X, Y).
|
|
|
|
proc get_char {x y} {
|
|
|
|
variable _chars
|
|
|
|
return [lindex $_chars($x,$y) 0]
|
|
|
|
}
|
|
|
|
|
|
|
|
# Get the entire screen as a string.
|
|
|
|
proc get_all_lines {} {
|
|
|
|
variable _rows
|
|
|
|
variable _cols
|
|
|
|
variable _chars
|
|
|
|
|
|
|
|
set result ""
|
|
|
|
for {set y 0} {$y < $_rows} {incr y} {
|
|
|
|
for {set x 0} {$x < $_cols} {incr x} {
|
|
|
|
append result [lindex $_chars($x,$y) 0]
|
|
|
|
}
|
|
|
|
append result "\n"
|
|
|
|
}
|
|
|
|
|
|
|
|
return $result
|
|
|
|
}
|
|
|
|
|
|
|
|
# Get the text just before the cursor.
|
|
|
|
proc get_current_line {} {
|
|
|
|
variable _cur_x
|
|
|
|
variable _cur_y
|
|
|
|
return [get_line $_cur_y $_cur_x]
|
|
|
|
}
|
|
|
|
|
|
|
|
# Helper function for check_box. Returns empty string if the box
|
|
|
|
# is found, description of why not otherwise.
|
|
|
|
proc _check_box {x y width height} {
|
|
|
|
set x2 [expr {$x + $width - 1}]
|
|
|
|
set y2 [expr {$y + $height - 1}]
|
|
|
|
|
|
|
|
if {[get_char $x $y] != "+"} {
|
|
|
|
return "ul corner"
|
|
|
|
}
|
|
|
|
if {[get_char $x $y2] != "+"} {
|
|
|
|
return "ll corner"
|
|
|
|
}
|
|
|
|
if {[get_char $x2 $y] != "+"} {
|
|
|
|
return "ur corner"
|
|
|
|
}
|
|
|
|
if {[get_char $x2 $y2] != "+"} {
|
|
|
|
return "lr corner"
|
|
|
|
}
|
|
|
|
|
2020-01-10 08:04:25 +08:00
|
|
|
# Note we do not check the full horizonal borders of the box.
|
|
|
|
# The top will contain a title, and the bottom may as well, if
|
|
|
|
# it is overlapped by some other border. However, at most a
|
|
|
|
# title should appear as '+-VERY LONG TITLE-+', so we can
|
|
|
|
# check for the '+-' on the left, and '-+' on the right.
|
|
|
|
if {[get_char [expr {$x + 1}] $y] != "-"} {
|
|
|
|
return "ul title padding"
|
|
|
|
}
|
|
|
|
|
|
|
|
if {[get_char [expr {$x2 - 1}] $y] != "-"} {
|
|
|
|
return "ul title padding"
|
|
|
|
}
|
|
|
|
|
|
|
|
# Now check the vertical borders.
|
2019-07-02 06:01:58 +08:00
|
|
|
for {set i [expr {$y + 1}]} {$i < $y2 - 1} {incr i} {
|
|
|
|
if {[get_char $x $i] != "|"} {
|
|
|
|
return "left side $i"
|
|
|
|
}
|
|
|
|
if {[get_char $x2 $i] != "|"} {
|
|
|
|
return "right side $i"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
# Check for a box at the given coordinates.
|
|
|
|
proc check_box {test_name x y width height} {
|
|
|
|
set why [_check_box $x $y $width $height]
|
|
|
|
if {$why == ""} {
|
|
|
|
pass $test_name
|
|
|
|
} else {
|
|
|
|
dump_screen
|
|
|
|
fail "$test_name ($why)"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Check whether the text contents of the terminal match the
|
|
|
|
# regular expression. Note that text styling is not considered.
|
|
|
|
proc check_contents {test_name regexp} {
|
|
|
|
set contents [get_all_lines]
|
|
|
|
if {![gdb_assert {[regexp -- $regexp $contents]} $test_name]} {
|
|
|
|
dump_screen
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-07 08:35:02 +08:00
|
|
|
# Check the contents of a box on the screen. This is a little
|
|
|
|
# like check_contents, but doens't check the whole screen
|
|
|
|
# contents, only the contents of a single box. This procedure
|
|
|
|
# includes (effectively) a call to check_box to ensure there is a
|
|
|
|
# box where expected, if there is then the contents of the box are
|
|
|
|
# matched against REGEXP.
|
|
|
|
proc check_box_contents {test_name x y width height regexp} {
|
|
|
|
variable _chars
|
|
|
|
|
|
|
|
set why [_check_box $x $y $width $height]
|
|
|
|
if {$why != ""} {
|
|
|
|
dump_screen
|
|
|
|
fail "$test_name (box check: $why)"
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
# Now grab the contents of the box, join each line together
|
|
|
|
# with a newline character and match against REGEXP.
|
|
|
|
set result ""
|
|
|
|
for {set yy [expr {$y + 1}]} {$yy < [expr {$y + $height - 1}]} {incr yy} {
|
|
|
|
for {set xx [expr {$x + 1}]} {$xx < [expr {$x + $width - 1}]} {incr xx} {
|
|
|
|
append result [lindex $_chars($xx,$yy) 0]
|
|
|
|
}
|
|
|
|
append result "\n"
|
|
|
|
}
|
|
|
|
|
|
|
|
if {![gdb_assert {[regexp -- $regexp $result]} $test_name]} {
|
|
|
|
dump_screen
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-02 06:01:58 +08:00
|
|
|
# A debugging function to dump the current screen, with line
|
|
|
|
# numbers.
|
|
|
|
proc dump_screen {} {
|
|
|
|
variable _rows
|
Make TUI resizing tests more robust
As Sergio pointed out, the TUI resizing tests are flaky. Debugging
this showed three main problems.
1. expect's "stty" command processes its arguments one-by-one. So,
rather than requesting a single resize, it sends two separate resize
requests (one for rows and one for columns). This means gdb sees two
SIGWINCH signals and resizes the terminal twice.
I consider this a bug in expect, but I couldn't readily see how to
report a bug; and anyway the fix wouldn't propagate very quickly.
This patch works around this problem by explicitly doing two separate
resizes (so it will be robust if expect ever does change); and then by
waiting for each resize to complete before continuing.
2. gdb uses curses to drive the console rendering. Currently the test
suite looks for terminal text insertion sequences to decide when a
command has completed. However, it turns out that, sometimes, curses
can output things in non-obvious ways. I didn't debug into curses but
I guess this can happen due to output optimizations. No matter the
reason, sometimes the current approach of only tracking text
insertions is not enough to detect that gdb has finished rendering.
This patch fixes this problem by arranging to detect the termination
output after any curses command, not just insertion.
3. Detecting when a resize has completed is tricky. In fact, I could
not find a way to reliably do this.
This patch fixes this problem by adding a special maint
"tui-resize-message" setting to gdb. When this is enabled, gdb will
print a message after each SIGWINCH has been fully processed. The
test suite enables this mode and then waits for the message in order
to know when control can be returned to the calling test.
This patch also adds a timeout, to avoid the situation where the
terminal code fails to notice a change for some reason. This lets the
test at least try to continue.
gdb/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* tui/tui-win.c (resize_message): New global.
(show_tui_resize_message): New function.
(tui_async_resize_screen): Print message if requested.
(_initialize_tui_win): Add tui-resize-message setting.
* NEWS: Add entry for new commands.
gdb/doc/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* gdb.texinfo (Maintenance Commands): Document new command.
gdb/testsuite/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* lib/tuiterm.exp (_accept): Add wait_for parameter. Check output
after any command. Expect prompt after WAIT_FOR is seen.
(enter_tui): Enable resize messages.
(command): Expect command in output.
(get_line): Avoid error when cursor appears to be off-screen.
(dump_screen): Include screen size in title.
(_do_resize): New proc, from "resize".
(resize): Rewrite. Do resize in two steps.
* gdb.tui/empty.exp (layouts): Fix entries.
(check_boxes): Remove xfail.
(check_text): Dump screen on failure.
Change-Id: I420e0259cb99b21adcd28f671b99161eefa7a51d
2019-08-17 05:16:12 +08:00
|
|
|
variable _cols
|
2020-01-07 08:26:22 +08:00
|
|
|
verbose -log "Screen Dump ($_cols x $_rows):"
|
2019-07-02 06:01:58 +08:00
|
|
|
for {set y 0} {$y < $_rows} {incr y} {
|
|
|
|
set fmt [format %5d $y]
|
2020-01-07 08:26:22 +08:00
|
|
|
verbose -log "$fmt [get_line $y]"
|
2019-07-02 06:01:58 +08:00
|
|
|
}
|
|
|
|
}
|
2019-07-20 06:15:58 +08:00
|
|
|
|
|
|
|
# Resize the terminal.
|
Make TUI resizing tests more robust
As Sergio pointed out, the TUI resizing tests are flaky. Debugging
this showed three main problems.
1. expect's "stty" command processes its arguments one-by-one. So,
rather than requesting a single resize, it sends two separate resize
requests (one for rows and one for columns). This means gdb sees two
SIGWINCH signals and resizes the terminal twice.
I consider this a bug in expect, but I couldn't readily see how to
report a bug; and anyway the fix wouldn't propagate very quickly.
This patch works around this problem by explicitly doing two separate
resizes (so it will be robust if expect ever does change); and then by
waiting for each resize to complete before continuing.
2. gdb uses curses to drive the console rendering. Currently the test
suite looks for terminal text insertion sequences to decide when a
command has completed. However, it turns out that, sometimes, curses
can output things in non-obvious ways. I didn't debug into curses but
I guess this can happen due to output optimizations. No matter the
reason, sometimes the current approach of only tracking text
insertions is not enough to detect that gdb has finished rendering.
This patch fixes this problem by arranging to detect the termination
output after any curses command, not just insertion.
3. Detecting when a resize has completed is tricky. In fact, I could
not find a way to reliably do this.
This patch fixes this problem by adding a special maint
"tui-resize-message" setting to gdb. When this is enabled, gdb will
print a message after each SIGWINCH has been fully processed. The
test suite enables this mode and then waits for the message in order
to know when control can be returned to the calling test.
This patch also adds a timeout, to avoid the situation where the
terminal code fails to notice a change for some reason. This lets the
test at least try to continue.
gdb/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* tui/tui-win.c (resize_message): New global.
(show_tui_resize_message): New function.
(tui_async_resize_screen): Print message if requested.
(_initialize_tui_win): Add tui-resize-message setting.
* NEWS: Add entry for new commands.
gdb/doc/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* gdb.texinfo (Maintenance Commands): Document new command.
gdb/testsuite/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* lib/tuiterm.exp (_accept): Add wait_for parameter. Check output
after any command. Expect prompt after WAIT_FOR is seen.
(enter_tui): Enable resize messages.
(command): Expect command in output.
(get_line): Avoid error when cursor appears to be off-screen.
(dump_screen): Include screen size in title.
(_do_resize): New proc, from "resize".
(resize): Rewrite. Do resize in two steps.
* gdb.tui/empty.exp (layouts): Fix entries.
(check_boxes): Remove xfail.
(check_text): Dump screen on failure.
Change-Id: I420e0259cb99b21adcd28f671b99161eefa7a51d
2019-08-17 05:16:12 +08:00
|
|
|
proc _do_resize {rows cols} {
|
2019-07-20 06:15:58 +08:00
|
|
|
variable _chars
|
|
|
|
variable _rows
|
|
|
|
variable _cols
|
|
|
|
|
|
|
|
set old_rows [expr {min ($_rows, $rows)}]
|
|
|
|
set old_cols [expr {min ($_cols, $cols)}]
|
|
|
|
|
|
|
|
# Copy locally.
|
|
|
|
array set local_chars [array get _chars]
|
|
|
|
unset _chars
|
|
|
|
|
|
|
|
set _rows $rows
|
|
|
|
set _cols $cols
|
|
|
|
_clear_lines 0 $_rows
|
|
|
|
|
|
|
|
for {set x 0} {$x < $old_cols} {incr x} {
|
|
|
|
for {set y 0} {$y < $old_rows} {incr y} {
|
|
|
|
set _chars($x,$y) $local_chars($x,$y)
|
|
|
|
}
|
|
|
|
}
|
Make TUI resizing tests more robust
As Sergio pointed out, the TUI resizing tests are flaky. Debugging
this showed three main problems.
1. expect's "stty" command processes its arguments one-by-one. So,
rather than requesting a single resize, it sends two separate resize
requests (one for rows and one for columns). This means gdb sees two
SIGWINCH signals and resizes the terminal twice.
I consider this a bug in expect, but I couldn't readily see how to
report a bug; and anyway the fix wouldn't propagate very quickly.
This patch works around this problem by explicitly doing two separate
resizes (so it will be robust if expect ever does change); and then by
waiting for each resize to complete before continuing.
2. gdb uses curses to drive the console rendering. Currently the test
suite looks for terminal text insertion sequences to decide when a
command has completed. However, it turns out that, sometimes, curses
can output things in non-obvious ways. I didn't debug into curses but
I guess this can happen due to output optimizations. No matter the
reason, sometimes the current approach of only tracking text
insertions is not enough to detect that gdb has finished rendering.
This patch fixes this problem by arranging to detect the termination
output after any curses command, not just insertion.
3. Detecting when a resize has completed is tricky. In fact, I could
not find a way to reliably do this.
This patch fixes this problem by adding a special maint
"tui-resize-message" setting to gdb. When this is enabled, gdb will
print a message after each SIGWINCH has been fully processed. The
test suite enables this mode and then waits for the message in order
to know when control can be returned to the calling test.
This patch also adds a timeout, to avoid the situation where the
terminal code fails to notice a change for some reason. This lets the
test at least try to continue.
gdb/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* tui/tui-win.c (resize_message): New global.
(show_tui_resize_message): New function.
(tui_async_resize_screen): Print message if requested.
(_initialize_tui_win): Add tui-resize-message setting.
* NEWS: Add entry for new commands.
gdb/doc/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* gdb.texinfo (Maintenance Commands): Document new command.
gdb/testsuite/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* lib/tuiterm.exp (_accept): Add wait_for parameter. Check output
after any command. Expect prompt after WAIT_FOR is seen.
(enter_tui): Enable resize messages.
(command): Expect command in output.
(get_line): Avoid error when cursor appears to be off-screen.
(dump_screen): Include screen size in title.
(_do_resize): New proc, from "resize".
(resize): Rewrite. Do resize in two steps.
* gdb.tui/empty.exp (layouts): Fix entries.
(check_boxes): Remove xfail.
(check_text): Dump screen on failure.
Change-Id: I420e0259cb99b21adcd28f671b99161eefa7a51d
2019-08-17 05:16:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
proc resize {rows cols} {
|
|
|
|
variable _rows
|
|
|
|
variable _cols
|
|
|
|
variable _resize_count
|
2019-07-20 06:15:58 +08:00
|
|
|
|
|
|
|
global gdb_spawn_name
|
Make TUI resizing tests more robust
As Sergio pointed out, the TUI resizing tests are flaky. Debugging
this showed three main problems.
1. expect's "stty" command processes its arguments one-by-one. So,
rather than requesting a single resize, it sends two separate resize
requests (one for rows and one for columns). This means gdb sees two
SIGWINCH signals and resizes the terminal twice.
I consider this a bug in expect, but I couldn't readily see how to
report a bug; and anyway the fix wouldn't propagate very quickly.
This patch works around this problem by explicitly doing two separate
resizes (so it will be robust if expect ever does change); and then by
waiting for each resize to complete before continuing.
2. gdb uses curses to drive the console rendering. Currently the test
suite looks for terminal text insertion sequences to decide when a
command has completed. However, it turns out that, sometimes, curses
can output things in non-obvious ways. I didn't debug into curses but
I guess this can happen due to output optimizations. No matter the
reason, sometimes the current approach of only tracking text
insertions is not enough to detect that gdb has finished rendering.
This patch fixes this problem by arranging to detect the termination
output after any curses command, not just insertion.
3. Detecting when a resize has completed is tricky. In fact, I could
not find a way to reliably do this.
This patch fixes this problem by adding a special maint
"tui-resize-message" setting to gdb. When this is enabled, gdb will
print a message after each SIGWINCH has been fully processed. The
test suite enables this mode and then waits for the message in order
to know when control can be returned to the calling test.
This patch also adds a timeout, to avoid the situation where the
terminal code fails to notice a change for some reason. This lets the
test at least try to continue.
gdb/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* tui/tui-win.c (resize_message): New global.
(show_tui_resize_message): New function.
(tui_async_resize_screen): Print message if requested.
(_initialize_tui_win): Add tui-resize-message setting.
* NEWS: Add entry for new commands.
gdb/doc/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* gdb.texinfo (Maintenance Commands): Document new command.
gdb/testsuite/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* lib/tuiterm.exp (_accept): Add wait_for parameter. Check output
after any command. Expect prompt after WAIT_FOR is seen.
(enter_tui): Enable resize messages.
(command): Expect command in output.
(get_line): Avoid error when cursor appears to be off-screen.
(dump_screen): Include screen size in title.
(_do_resize): New proc, from "resize".
(resize): Rewrite. Do resize in two steps.
* gdb.tui/empty.exp (layouts): Fix entries.
(check_boxes): Remove xfail.
(check_text): Dump screen on failure.
Change-Id: I420e0259cb99b21adcd28f671b99161eefa7a51d
2019-08-17 05:16:12 +08:00
|
|
|
# expect handles each argument to stty separately. This means
|
|
|
|
# that gdb will see SIGWINCH twice. Rather than rely on this
|
|
|
|
# behavior (which, after all, could be changed), we make it
|
|
|
|
# explicit here. This also simplifies waiting for the redraw.
|
|
|
|
_do_resize $rows $_cols
|
|
|
|
stty rows $_rows < $gdb_spawn_name
|
|
|
|
# Due to the strange column resizing behavior, and because we
|
|
|
|
# don't care about this intermediate resize, we don't check
|
|
|
|
# the size here.
|
2019-12-23 07:52:56 +08:00
|
|
|
wait_for "@@ resize done $_resize_count"
|
Make TUI resizing tests more robust
As Sergio pointed out, the TUI resizing tests are flaky. Debugging
this showed three main problems.
1. expect's "stty" command processes its arguments one-by-one. So,
rather than requesting a single resize, it sends two separate resize
requests (one for rows and one for columns). This means gdb sees two
SIGWINCH signals and resizes the terminal twice.
I consider this a bug in expect, but I couldn't readily see how to
report a bug; and anyway the fix wouldn't propagate very quickly.
This patch works around this problem by explicitly doing two separate
resizes (so it will be robust if expect ever does change); and then by
waiting for each resize to complete before continuing.
2. gdb uses curses to drive the console rendering. Currently the test
suite looks for terminal text insertion sequences to decide when a
command has completed. However, it turns out that, sometimes, curses
can output things in non-obvious ways. I didn't debug into curses but
I guess this can happen due to output optimizations. No matter the
reason, sometimes the current approach of only tracking text
insertions is not enough to detect that gdb has finished rendering.
This patch fixes this problem by arranging to detect the termination
output after any curses command, not just insertion.
3. Detecting when a resize has completed is tricky. In fact, I could
not find a way to reliably do this.
This patch fixes this problem by adding a special maint
"tui-resize-message" setting to gdb. When this is enabled, gdb will
print a message after each SIGWINCH has been fully processed. The
test suite enables this mode and then waits for the message in order
to know when control can be returned to the calling test.
This patch also adds a timeout, to avoid the situation where the
terminal code fails to notice a change for some reason. This lets the
test at least try to continue.
gdb/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* tui/tui-win.c (resize_message): New global.
(show_tui_resize_message): New function.
(tui_async_resize_screen): Print message if requested.
(_initialize_tui_win): Add tui-resize-message setting.
* NEWS: Add entry for new commands.
gdb/doc/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* gdb.texinfo (Maintenance Commands): Document new command.
gdb/testsuite/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* lib/tuiterm.exp (_accept): Add wait_for parameter. Check output
after any command. Expect prompt after WAIT_FOR is seen.
(enter_tui): Enable resize messages.
(command): Expect command in output.
(get_line): Avoid error when cursor appears to be off-screen.
(dump_screen): Include screen size in title.
(_do_resize): New proc, from "resize".
(resize): Rewrite. Do resize in two steps.
* gdb.tui/empty.exp (layouts): Fix entries.
(check_boxes): Remove xfail.
(check_text): Dump screen on failure.
Change-Id: I420e0259cb99b21adcd28f671b99161eefa7a51d
2019-08-17 05:16:12 +08:00
|
|
|
incr _resize_count
|
2019-07-20 06:15:58 +08:00
|
|
|
# Somehow the number of columns transmitted to gdb is one less
|
|
|
|
# than what we request from expect. We hide this weird
|
|
|
|
# details from the caller.
|
Make TUI resizing tests more robust
As Sergio pointed out, the TUI resizing tests are flaky. Debugging
this showed three main problems.
1. expect's "stty" command processes its arguments one-by-one. So,
rather than requesting a single resize, it sends two separate resize
requests (one for rows and one for columns). This means gdb sees two
SIGWINCH signals and resizes the terminal twice.
I consider this a bug in expect, but I couldn't readily see how to
report a bug; and anyway the fix wouldn't propagate very quickly.
This patch works around this problem by explicitly doing two separate
resizes (so it will be robust if expect ever does change); and then by
waiting for each resize to complete before continuing.
2. gdb uses curses to drive the console rendering. Currently the test
suite looks for terminal text insertion sequences to decide when a
command has completed. However, it turns out that, sometimes, curses
can output things in non-obvious ways. I didn't debug into curses but
I guess this can happen due to output optimizations. No matter the
reason, sometimes the current approach of only tracking text
insertions is not enough to detect that gdb has finished rendering.
This patch fixes this problem by arranging to detect the termination
output after any curses command, not just insertion.
3. Detecting when a resize has completed is tricky. In fact, I could
not find a way to reliably do this.
This patch fixes this problem by adding a special maint
"tui-resize-message" setting to gdb. When this is enabled, gdb will
print a message after each SIGWINCH has been fully processed. The
test suite enables this mode and then waits for the message in order
to know when control can be returned to the calling test.
This patch also adds a timeout, to avoid the situation where the
terminal code fails to notice a change for some reason. This lets the
test at least try to continue.
gdb/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* tui/tui-win.c (resize_message): New global.
(show_tui_resize_message): New function.
(tui_async_resize_screen): Print message if requested.
(_initialize_tui_win): Add tui-resize-message setting.
* NEWS: Add entry for new commands.
gdb/doc/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* gdb.texinfo (Maintenance Commands): Document new command.
gdb/testsuite/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* lib/tuiterm.exp (_accept): Add wait_for parameter. Check output
after any command. Expect prompt after WAIT_FOR is seen.
(enter_tui): Enable resize messages.
(command): Expect command in output.
(get_line): Avoid error when cursor appears to be off-screen.
(dump_screen): Include screen size in title.
(_do_resize): New proc, from "resize".
(resize): Rewrite. Do resize in two steps.
* gdb.tui/empty.exp (layouts): Fix entries.
(check_boxes): Remove xfail.
(check_text): Dump screen on failure.
Change-Id: I420e0259cb99b21adcd28f671b99161eefa7a51d
2019-08-17 05:16:12 +08:00
|
|
|
_do_resize $_rows $cols
|
|
|
|
stty columns [expr {$_cols + 1}] < $gdb_spawn_name
|
2019-12-23 07:52:56 +08:00
|
|
|
wait_for "@@ resize done $_resize_count, size = ${_cols}x${rows}"
|
Make TUI resizing tests more robust
As Sergio pointed out, the TUI resizing tests are flaky. Debugging
this showed three main problems.
1. expect's "stty" command processes its arguments one-by-one. So,
rather than requesting a single resize, it sends two separate resize
requests (one for rows and one for columns). This means gdb sees two
SIGWINCH signals and resizes the terminal twice.
I consider this a bug in expect, but I couldn't readily see how to
report a bug; and anyway the fix wouldn't propagate very quickly.
This patch works around this problem by explicitly doing two separate
resizes (so it will be robust if expect ever does change); and then by
waiting for each resize to complete before continuing.
2. gdb uses curses to drive the console rendering. Currently the test
suite looks for terminal text insertion sequences to decide when a
command has completed. However, it turns out that, sometimes, curses
can output things in non-obvious ways. I didn't debug into curses but
I guess this can happen due to output optimizations. No matter the
reason, sometimes the current approach of only tracking text
insertions is not enough to detect that gdb has finished rendering.
This patch fixes this problem by arranging to detect the termination
output after any curses command, not just insertion.
3. Detecting when a resize has completed is tricky. In fact, I could
not find a way to reliably do this.
This patch fixes this problem by adding a special maint
"tui-resize-message" setting to gdb. When this is enabled, gdb will
print a message after each SIGWINCH has been fully processed. The
test suite enables this mode and then waits for the message in order
to know when control can be returned to the calling test.
This patch also adds a timeout, to avoid the situation where the
terminal code fails to notice a change for some reason. This lets the
test at least try to continue.
gdb/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* tui/tui-win.c (resize_message): New global.
(show_tui_resize_message): New function.
(tui_async_resize_screen): Print message if requested.
(_initialize_tui_win): Add tui-resize-message setting.
* NEWS: Add entry for new commands.
gdb/doc/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* gdb.texinfo (Maintenance Commands): Document new command.
gdb/testsuite/ChangeLog
2019-11-12 Tom Tromey <tom@tromey.com>
* lib/tuiterm.exp (_accept): Add wait_for parameter. Check output
after any command. Expect prompt after WAIT_FOR is seen.
(enter_tui): Enable resize messages.
(command): Expect command in output.
(get_line): Avoid error when cursor appears to be off-screen.
(dump_screen): Include screen size in title.
(_do_resize): New proc, from "resize".
(resize): Rewrite. Do resize in two steps.
* gdb.tui/empty.exp (layouts): Fix entries.
(check_boxes): Remove xfail.
(check_text): Dump screen on failure.
Change-Id: I420e0259cb99b21adcd28f671b99161eefa7a51d
2019-08-17 05:16:12 +08:00
|
|
|
incr _resize_count
|
2019-07-20 06:15:58 +08:00
|
|
|
}
|
2019-07-02 06:01:58 +08:00
|
|
|
}
|