aboutsummaryrefslogtreecommitdiff
path: root/gdb/tui
AgeCommit message (Collapse)AuthorFilesLines
2023-10-05gdb: add all_objfiles_removed observerSimon Marchi1-2/+11
The new_objfile observer is currently used to indicate both when a new objfile is added to program space (when passed non-nullptr) and when all objfiles of a program space were just removed (when passed nullptr). I think this is confusing (and Andrew apparently thinks so too [1]). Add a new "all_objfiles_removed" observer to remove the second role from "new_objfile". Some existing users of new_objfile do nothing if the passed objfile is nullptr. For them, we can simply drop the nullptr check. For others, add a new all_objfiles_removed callback, and refactor things a bit to keep the existing behavior as much as possible. Some callbacks relied on current_program_space, and following the refactoring now use either objfile->pspace or the pspace passed to all_objfiles_removed. I think this should be relatively safe, and in general a step in the right direction. On the notify side, I found only one call site to change from new_objfile to all_objfiles_removed, in clear_symtab_users. It is not entirely clear to me that this is entirely correct. clear_symtab_users appears to be called in spots that don't remove all objfiles (functions finish_new_objfile, remove_symbol_file_command, reread_symbols, do_module_cleanups). But I think that this patch at least makes the current code clearer. [1] https://gitlab.com/gnutools/binutils-gdb/-/commit/a0a031bce0527b1521788b5dad640e7883b3a252 Change-Id: Icb648f72862e056267f30f44dd439bd4ec766f13 Approved-By: Tom Tromey <tom@tromey.com>
2023-09-28[gdb/tui] Fix segfault in tui_find_disassembly_addressTom de Vries1-0/+39
PR29040 describes a FAIL for test-case gdb.threads/next-fork-other-thread.exp and target board unix/-m32. The FAIL happens due to the test executable running into an assert, which is caused by a forked child segfaulting, like so: ... Program terminated with signal SIGSEGV, Segmentation fault. #0 0x00000000 in ?? () ... I tried to reproduce the segfault with exec next-fork-other-thread-fork, using TUI layout asm. I set a breakpoint at fork and ran to the breakpoint, and somewhere during the following session I ran into a gdb segfault here in tui_find_disassembly_address: ... /* Disassemble forward. */ next_addr = tui_disassemble (gdbarch, asm_lines, new_low, max_lines); last_addr = asm_lines.back ().addr; ... due to asm_lines being empty after the call to tui_disassemble, while asm_lines.back () assumes that it's not empty. I have not been able to reproduce that segfault in that original setting, I'm not sure of the exact scenario (though looking back it probably involved "set detach-on-fork off"). What likely happened is that I managed to reproduce PR29040, and TUI (attempted to) display the disassembly for address 0, which led to the gdb segfault. When gdb_print_insn encounters an insn it cannot print because it can't read the memory, it throws a MEMORY_ERROR that is caught by tui_disassemble. The specific bit that causes the gdb segfault is that if gdb_print_insn throws a MEMORY_ERROR for the first insn in tui_disassemble, it returns an empty asm_lines. FWIW, I did manage to reproduce the gdb segfault as follows: ... $ gdb -q \ -iex "set pagination off" \ /usr/bin/rustc \ -ex "set breakpoint pending on" \ -ex "b dl_main" \ -ex run \ -ex "up 4" \ -ex "layout asm" \ -ex "print \$pc" ... <TUI> ... $1 = (void (*)()) 0x1 (gdb) ... Now press <up>, and the segfault triggers. Fix the segfault by handling asm_lines.empty () results of tui_disassemble in tui_find_disassembly_address. I've written a unit test that exercises this scenario. Tested on x86_64-linux. Reviewed-by: Kevin Buettner <kevinb@redhat.com> PR tui/30823 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30823
2023-09-20Remove explanatory comments from includesTom Tromey2-2/+2
I noticed a comment by an include and remembered that I think these don't really provide much value -- sometimes they are just editorial, and sometimes they are obsolete. I think it's better to just remove them. Tested by rebuilding. Approved-By: Andrew Burgess <aburgess@redhat.com>
2023-09-20gdb/tui: add 'set tui mouse-events off' to restore mouse selectionMatthew "strager" Glazar3-1/+27
Rationale: I use the mouse with my terminal to select and copy text. In gdb, I use the mouse to select a function name to set a breakpoint, or a variable name to print, for example. When gdb is compiled with ncurses mouse support, gdb's TUI mode intercepts mouse events. Left-clicking and dragging, which would normally select text, seems to do nothing. This means I cannot select text using my mouse anymore. This makes it harder to set breakpoints, print variables, etc. Solution: I tried to fix this issue by editing the 'mousemask' call to only enable buttons 4 and 5. However, this still caused my terminal (gnome-terminal) to not allow text to be selected. The only way I could make it work is by calling 'mousemask (0, NULL);'. But doing so disables the mouse code entirely, which other people might want. I therefore decided to make a setting in gdb called 'tui mouse-events'. If enabled (the default), the behavior is as it is now: terminal mouse events are given to gdb, disabling the terminal's default behavior. If disabled (opt-in), the behavior is as it was before the year 2020: terminal mouse events are not given to gdb, therefore the mouse can be used to select and copy text. Notes: I am not attached to the setting name or its description. Feel free to suggest better wording. Testing: I tested this change in gnome-terminal by performing the following steps manually: 1. Run: gdb --args ./myprogram 2. Enable TUI: press ctrl-x ctrl-a 3. Click and drag text with the mouse. Observe no selection. 4. Input: set tui mouse-events off 5. Click and drag text with the mouse. Observe that selection works now. 6. Input: set tui mouse-events on. 7. Click and drag text with the mouse. Observe no selection.
2023-07-21[gdb/tui] Fix superfluous newline for long promptTom de Vries1-2/+0
In test-case gdb.tui/long-prompt.exp, with a prompt of 40 chars, the same size as the terminal width, we get a superfluous newline at line 19: ... 16 (gdb) set prompt 123456789A123456789B123 17 456789C123456789> 18 123456789A123456789B123456789C123456789> 19 20 123456789A123456789B123456789C123456789> 21 set prompt (gdb) 22 (gdb) ... as well as a superfluous repetition of the prompt at line 20 once we type the 's' starting "set prompt". I traced the superfluous newline back to readline's readline_internal_setup, that does: ... /* If we're not echoing, we still want to at least print a prompt, because rl_redisplay will not do it for us. If the calling application has a custom redisplay function, though, let that function handle it. */ if (_rl_echoing_p == 0 && rl_redisplay_function == rl_redisplay) ... else { if (rl_prompt && rl_already_prompted) rl_on_new_line_with_prompt (); else rl_on_new_line (); (*rl_redisplay_function) (); ... and then we hit the case that calls rl_on_new_line_with_prompt, which does: ... /* If the prompt length is a multiple of real_screenwidth, we don't know whether the cursor is at the end of the last line, or already at the beginning of the next line. Output a newline just to be safe. */ if (l > 0 && (l % real_screenwidth) == 0) _rl_output_some_chars ("\n", 1); ... This doesn't look like a readline bug, because the behaviour matches the comment. [ And the fact that the output of the newline doesn't happen in the scope of tui_redisplay_readline means it doesn't get the prompt wrap detection treatment, causing start_line to be incorrect, which causes the superfluous repetition of the prompt. ] I looked at ways to work around this, and managed by switching off rl_already_prompted, which we set to 1 in tui_rl_startup_hook: ... /* Readline hook to redisplay ourself the gdb prompt. In the SingleKey mode, the prompt is not printed so that the command window is cleaner. It will be displayed if we temporarily leave the SingleKey mode. */ static int tui_rl_startup_hook (void) { rl_already_prompted = 1; if (tui_current_key_mode != TUI_COMMAND_MODE && !gdb_in_secondary_prompt_p (current_ui)) tui_set_key_mode (TUI_SINGLE_KEY_MODE); tui_redisplay_readline (); return 0; } ... Then I started looking at why rl_already_prompted is set to 1. The use case for rl_already_prompted seems to be: - app (application, the readline user) outputs prompt, - app sets rl_already_prompted to 1, and - app calls readline, which calls rl_on_new_line_with_prompt, which figures out how long the prompt is, and sets a few readline variables accordingly, which can be used in the following call to rl_redisplay_function. AFAICT, TUI does not fit this pattern. It does not output an initial prompt, rather it writes the prompt in every rl_redisplay_function. It doesn't use the variables set by rl_on_new_line_with_prompt, instead it figures stuff out by itself. Fix this by removing the rl_already_prompted setting. Also remove the call to tui_redisplay_readline, it's not necessary, the function is called anyway. Tested on x86_64-linux, no regressions.
2023-07-15gdb/tui: make tui_win_info::title privateAndrew Burgess5-14/+19
This commit builds on this earlier work: commit 9fe01a376b2fb096e4836e985ba316ce9dc02399 Date: Thu Jun 29 11:26:55 2023 -0600 Update TUI window title when changed and makes tui_win_info::title private, renaming to m_title at the same time. There's a new tui_win_info::title() member function to provide read-only access to the title. There should be no user visible changes after this commit. Approved-By: Tom Tromey <tom@tromey.com>
2023-07-12[gdb/tui] Assume HAVE_WBORDERTom de Vries1-4/+0
The tui border-kind setting allows values acs, ascii and space. The values ascii and space however don't work well with !HAVE_WBORDER. Fix this by removing the !HAVE_WBORDER case, which was introduced for Ultrix support, which is now obsolete. Tested on x86_64-linux. PR tui/30580 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30580 Approved-By: Tom Tromey <tom@tromey.com>
2023-07-12[gdb/tui] Make translate return entry->value instead of entryTom de Vries1-13/+11
The only use of "entry = translate (...)" is entry->value. Simplify using the function by returning entry->value instead. Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com>
2023-07-12[gdb/tui] Merge tui border-kind corner translation tablesTom de Vries1-25/+7
The tables: - tui_border_kind_translate_ulcorner - tui_border_kind_translate_urcorner - tui_border_kind_translate_llcorner - tui_border_kind_translate_lrcorner are identical. Merge and rename to tui_border_kind_translate_corner. Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com>
2023-07-12[gdb/tui] Introduce translate_acsTom de Vries1-25/+34
In function tui_update_variables we have the somewhat inconvenient: ... entry = translate (tui_border_kind, tui_border_kind_translate_lrcorner); int val = (entry->value < 0) ? ACS_LRCORNER : entry->value; ... Add a new function translate_acs, that allows us to do the more straighforward: ... int val = translate_acs (tui_border_kind, tui_border_kind_translate_lrcorner, ACS_LRCORNER); ... By special-casing "acs" in translate_acs, we can now remove the acs entries from the translation tables. Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com>
2023-07-12[gdb/tui] Remove default entries in TUI translation tablesTom de Vries1-21/+10
The TUI translation tables contain default entries at the end: ... static struct tui_translate tui_border_kind_translate_hline[] = { { "space", ' ' }, { "ascii", '-' }, { "acs", -1 }, { 0, 0 }, { "ascii", '-' } }; ... A simpler way of implementing this would be to to declare the first (or last) entry the default, but in fact these default entries are not used. Make this explicit by removing the default entries, and asserting in translate that an entry will always be found. Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com>
2023-07-10Update TUI window title when changedTom Tromey2-0/+15
I wrote a TUI window in Python, and I noticed that setting its title did not result in a refresh, so the new title did not appear. This patch corrects this problem.
2023-06-19[gdb/tui] Simplify tui_update_variablesTom de Vries1-15/+7
Simplify tui_update_variables by using template function assign_return_if_changed. Tested on x86_64-linux.
2023-06-12[gdb/tui] Replace macro HELP_ATTRIBUTE_MODE with std::stringTom de Vries1-10/+14
Replace macro HELP_ATTRIBUTE_MODE with a std::string. Tested on x86_64-linux. Reviewed-By: Bruno Larsen <blarsen@redhat.com> Reviewed-By: Tom Tromey <tom@tromey.com>
2023-06-09[gdb/tui] Simplify tui_puts_internalTom de Vries1-19/+20
Simplify tui_puts_internal by using continue, as per this [1] coding standard rule, making the function more readable and easier to understand. No functional changes. Tested on x86_64-linux. [1] https://llvm.org/docs/CodingStandards.html#use-early-exits-and-continue-to-simplify-code Reviewed-By: Tom Tromey <tom@tromey.com>
2023-06-09[gdb/tui] Delete line buffer when switching to singlekeyTom de Vries1-0/+7
Say we're in TUI mode, and type "sun": ... (gdb) sun ... After switching to SingleKey mode using C-x s, we have just: ... sun ... After typing "d", we get: ... sun Undefined command: "sundown". Try "help". ... The SingleKey "d" is supposed run the "down" command. Fix this by clearing the readline line buffer when switching to SingleKey mode. Tested on x86_64-linux. PR tui/30522 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30522 Reviewed-By: Tom Tromey <tom@tromey.com>
2023-06-07[gdb/tui] Factor out border-mode help textTom de Vries1-15/+16
I noticed that the help texts for tui border-mode and tui active-border-mode are similar. Factor out the common part into macro HELP_ATTRIBUTE_MODE. Tested on x86_64-linux.
2023-06-05[gdb] Fix more typosTom de Vries2-2/+2
Fix some more typos: - distinquish -> distinguish - actualy -> actually - singe -> single - frash -> frame - chid -> child - dissassembler -> disassembler - uninitalized -> uninitialized - precontidion -> precondition - regsiters -> registers - marge -> merge - sate -> state - garanteed -> guaranteed - explictly -> explicitly - prefices (nonstandard plural) -> prefixes - bondary -> boundary - formated -> formatted - ithe -> the - arrav -> array - coresponding -> corresponding - owend -> owned - fials -> fails - diasm -> disasm - ture -> true - tpye -> type There's one code change, the name of macro SIG_CODE_BONDARY_FAULT changed to SIG_CODE_BOUNDARY_FAULT. Tested on x86_64-linux.
2023-06-03[gdb] Fix typosTom de Vries4-4/+4
Fix a few typos: - implemention -> implementation - convertion(s) -> conversion(s) - backlashes -> backslashes - signoring -> ignoring - (un)ambigious -> (un)ambiguous - occured -> occurred - hidding -> hiding - temporarilly -> temporarily - immediatelly -> immediately - sillyness -> silliness - similiar -> similar - porkuser -> pokeuser - thats -> that - alway -> always - supercede -> supersede - accomodate -> accommodate - aquire -> acquire - priveleged -> privileged - priviliged -> privileged - priviledges -> privileges - privilige -> privilege - recieve -> receive - (p)refered -> (p)referred - succesfully -> successfully - successfuly -> successfully - responsability -> responsibility - wether -> whether - wich -> which - disasbleable -> disableable - descriminant -> discriminant - construcstor -> constructor - underlaying -> underlying - underyling -> underlying - structureal -> structural - appearences -> appearances - terciarily -> tertiarily - resgisters -> registers - reacheable -> reachable - likelyhood -> likelihood - intepreter -> interpreter - disassemly -> disassembly - covnersion -> conversion - conviently -> conveniently - atttribute -> attribute - struction -> struct - resonable -> reasonable - popupated -> populated - namespaxe -> namespace - intialize -> initialize - identifer(s) -> identifier(s) - expection -> exception - exectuted -> executed - dungerous -> dangerous - dissapear -> disappear - completly -> completely - (inter)changable -> (inter)changeable - beakpoint -> breakpoint - automativ -> automatic - alocating -> allocating - agressive -> aggressive - writting -> writing - reguires -> requires - registed -> registered - recuding -> reducing - opeartor -> operator - ommitted -> omitted - modifing -> modifying - intances -> instances - imbedded -> embedded - gdbaarch -> gdbarch - exection -> execution - direcive -> directive - demanged -> demangled - decidely -> decidedly - argments -> arguments - agrument -> argument - amespace -> namespace - targtet -> target - supress(ed) -> suppress(ed) - startum -> stratum - squence -> sequence - prompty -> prompt - overlow -> overflow - memember -> member - languge -> language - geneate -> generate - funcion -> function - exising -> existing - dinking -> syncing - destroh -> destroy - clenaed -> cleaned - changep -> changedp (name of variable) - arround -> around - aproach -> approach - whould -> would - symobl -> symbol - recuse -> recurse - outter -> outer - freeds -> frees - contex -> context Tested on x86_64-linux. Reviewed-By: Tom Tromey <tom@tromey.com>
2023-06-03[gdb/tui] Fix help text of show tui tab-widthTom de Vries1-1/+1
I noticed: ... (gdb) help show tui tab-width Show the tab witdh, in characters, for the TUI. This variable controls how many spaces are used to display a tab character. ... a typo: "witdh". Fix this by using "width" instead. Reviewed-By: Tom Tromey <tom@tromey.com>
2023-05-31[gdb/tui] Fix fingerprint for cmd-only layoutTom de Vries2-3/+4
I added a cmd-only layout: ... (gdb) tui new-layout cmd cmd 1 ... and set it: ... (gdb) layout cmd ... which gave me the expect result: only the cmd window in the screen. However, after going back to layout src: ... (gdb) layout src ... I got a source window with only one line in it, and the cmd window taking most of the screen. I traced this back to tui_set_layout, where for both the old and the new layout the fingerprint of the cmd window in the layout is taken. If the fingerprint is the same, an effort will be done to preserve the command window size. The fingerprint is "VC" for both the old (cmd) and new (src) layouts, which explains the behaviour. I think this is essentially a bug in the finger print calculation, and it should be "C" for the cmd layout. Fix this by not adding a V or H in the fingerprint if the list size is one. Tested on x86_64-linux. Reviewed-By: Tom Tromey <tom@tromey.com>
2023-05-25gdb: remove breakpoint_pointer_iteratorSimon Marchi1-7/+7
Remove the breakpoint_pointer_iterator layer. Adjust all users of all_breakpoints and all_tracepoints to use references instead of pointers. Change-Id: I376826f812117cee1e6b199c384a10376973af5d Reviewed-By: Andrew Burgess <aburgess@redhat.com>
2023-05-25gdb: remove bp_location_pointer_iteratorSimon Marchi1-2/+2
Remove the bp_location_pointer_iterator layer. Adjust all users of breakpoint::locations to use references instead of pointers. Change-Id: Iceed34f5e0f5790a9cf44736aa658be6d1ba1afa Reviewed-By: Andrew Burgess <aburgess@redhat.com>
2023-05-25gdb: add breakpoint::first_loc methodsSimon Marchi1-1/+1
Add convenience first_loc methods to struct breakpoint (const and non-const overloads). A subsequent patch changes the list of locations to be an intrusive_list and makes the actual list private, so these spots would need to change from: b->loc to something ugly like: *b->locations ().begin () That would make the code much heavier and not readable. There is a surprisingly big number of places that access the first location of breakpoints. Whether this is correct, or these spots fail to consider the possibility of multi-location breakpoints, I don't know. But anyhow, I think that using this instead: b->first_loc () conveys the intention better than the other two forms. Change-Id: Ibbefe3e4ca6cdfe570351fe7e2725f2ce11d1e95 Reviewed-By: Andrew Burgess <aburgess@redhat.com>
2023-05-22[gdb/tui] Fix buglet in tui_update_variablesTom de Vries1-2/+3
I noticed a buglet in tui_update_variables: ... entry = translate (tui_border_kind, tui_border_kind_translate_lrcorner); if (tui_border_lrcorner != (chtype) entry->value) { tui_border_lrcorner = (entry->value < 0) ? ACS_LRCORNER : entry->value; ... When assigning the new value to tui_border_lrcorner, an entry->value of -1 is taken into account, but not when comparing to the current value of tui_border_lrcorner. Fix this by introducing: ... int val = (entry->value < 0) ? ACS_LRCORNER : entry->value; ... and using this in both comparison and assignment. Tested on x86_64-linux.
2023-05-16[gdb/tui] Don't show line number for lines not in source fileTom de Vries1-5/+19
Currently, for a source file containing only 5 lines, we also show line numbers 6 and 7 if they're in scope of the source window: ... 0 +-compact-source.c----------------+ 1 |___3_{ | 2 |___4_ return 0; | 3 |___5_} | 4 |___6_ | 5 |___7_ | 6 +---------------------------------+ ... Fix this by not showing line numbers not in a source file, such that we have instead: ... 0 +-compact-source.c----------------+ 1 |___3_{ | 2 |___4_ return 0; | 3 |___5_} | 4 | | 5 | | 6 +---------------------------------+ ... Tested on x86_64-linux. Suggested-By: Simon Marchi <simon.marchi@efficios.com> Approved-By: Tom Tromey <tom@tromey.com>
2023-05-10[gdb/tui] Fix tui compact-source a bit moreTom de Vries1-2/+1
Andrew pointed out that the behaviour as tested in gdb.tui/compact-source.exp is incorrect: ... 0 +-compact-source.c--------------------------------------------------------+ 1 |___3_{ | 2 |___4_ return 0; | 3 |___5_} | 4 |___6_ | 5 |___7_ | 6 |___8_ | 7 |___9_ | 8 +-------------------------------------------------------------------------+ ... The last line number in the source file is 5, and there are 7 lines to display source lines, so if we'd scroll all the way down, the first line number in the source window would be 5, and the last one would be 11. To represent 11 we'd need 2 digits, so we expect to see ___04_ here instead of ___4_, even though all line numbers currently in the src window (3-9) can be represented with only 1 digit. Fix this in tui_source_window::set_contents, by updating the computation of max_line_nr: ... - int max_line_nr = std::max (lines_in_file, last_line_nr_in_window); + int max_line_nr = lines_in_file + nlines - 1; ... Tested on x86_64-linux. Co-Authored-By: Andrew Burgess <aburgess@redhat.com> Approved-By: Tom Tromey <tom@tromey.com>
2023-05-10[gdb/tui] Fix tui compact-sourceTom de Vries2-4/+7
Consider a hello.c, with less than 10 lines: ... $ wc -l hello.c 8 hello.c ... and compiled with -g into an a.out. With compact-source off: ... $ gdb -q a.out \ -ex "set tui border-kind ascii" \ -ex "maint set tui-left-margin-verbose on" \ -ex "set tui compact-source off" \ -ex "tui enable" ... we get: ... +-./data/hello.c-----------------------+ |___000005_{ | |___000006_ printf ("hello\n"); | |___000007_ return 0; | |___000008_} | |___000009_ | |___000010_ | |___000011_ | ... but with compact-source on: ... +-./data/hello.c-----------------------+ |___5{ | |___6 printf ("hello\n"); | |___7 return 0; | |___8} | |___9 | |___1 | |___1 | ... There are a couple of problems with compact-source. First of all the documentation mentions: ... The default display uses more space for line numbers and starts the source text at the next tab stop; the compact display uses only as much space as is needed for the line numbers in the current file, and only a single space to separate the line numbers from the source. ... The bit about the default display and the next tab stop looks incorrect. The source doesn't start at a tab stop, instead it uses a single space to separate the line numbers from the source. Then the documentation mentions that there's single space in the compact display, but evidently that's missing. Then there's the fact that the line numbers "10" and "11" are both abbreviated to "1" in the compact case. The abbreviation is due to allocating space for <lines in source>, which is 8 for this example, and takes a single digit. The line numbers though continue past the end of the file, so fix this by allocating space for max (<lines in source>, <last line in window>), which in this example takes 2 digits. The missing space is due to some confusion about what the "1" here in tui_source_window::set_contents represent: ... double l = log10 ((double) offsets->size ()); m_digits = 1 + (int) l; ... It could be the trailing space that's mentioned in tui-source.h: ... /* How many digits to use when formatting the line number. This includes the trailing space. */ int m_digits; ... Then again, it could be part of the calculation for the number of digits needed for printing. With this minimal example: ... int main () { for (int i = 8; i <= 11; ++i) { double l = log10 ((double) i); printf ("%d %d\n", i, (int)l); } return 0; } ... we get: ... $ ./a.out 8 0 9 0 10 1 11 1 ... which shows that the number of digits needed for printing i is "1 + (int)log10 ((double) i)". Fix this by introducing named variables needed_digits and trailing_space, each adding 1. With the fixes, we get for compact-source on: ... +-./data/hello.c-----------------------+ |___05_{ | |___06_ printf ("hello\n"); | |___07_ return 0; | |___08_} | |___09_ | |___10_ | |___11_ | |... Also fix the documentation and help text to actually match effect of compact-source. Tested on x86_64-linux.
2023-05-01gdb: move struct ui and related things to ui.{c,h}Simon Marchi3-1/+3
I'd like to move some things so they become methods on struct ui. But first, I think that struct ui and the related things are big enough to deserve their own file, instead of being scattered through top.{c,h} and event-top.c. Change-Id: I15594269ace61fd76ef80a7b58f51ff3ab6979bc
2023-04-30[gdb/tui] Fix TUI resizing for TERM=ansiTom de Vries1-0/+4
With TERM=ansi, when resizing a TUI window from LINES/COLUMNS 31/118 (maximized) to 20/78 (de-maximized), I get a garbled screen (that ^L doesn't fix) and a message: ... @@ resize done 0, size = 77x20 ... with the resulting width being 77 instead of the expected 78. [ The discrepancy also manifests in CLI, filed as PR30346. ] The discrepancy comes from tui_resize_all, where we ask readline for the screen size: ... rl_get_screen_size (&screenheight, &screenwidth); ... As it happens, when TERM is set to ansi, readline decides that the terminal cannot auto-wrap lines, and reserves one column to deal with that, and as a result reports back one less than the actual screen width: ... $ echo $COLUMNS 78 $ TERM=xterm gdb -ex "show width" -ex q Number of characters gdb thinks are in a line is 78. $ TERM=ansi gdb -ex "show width" -ex q Number of characters gdb thinks are in a line is 77. ... In tui_resize_all, we need the actual screen width, and using a screenwidth of one less than the actual value garbles the screen. This is currently not causing trouble in testing because we have a workaround in place in proc Term::resize. If we disable the workaround: ... - stty columns [expr {$_cols + 1}] < $::gdb_tty_name + stty columns $_cols < $::gdb_tty_name ... and dump the screen we get the same type of screen garbling: ... 0 +---------------------------------------+| 1 || 2 || 3 || ... Another way to reproduce the problem is using command "maint info screen". After starting gdb with TERM=ansi, entering TUI, and issuing the command, we get: ... Number of characters curses thinks are in a line is 78. ... and after maximizing and demaximizing the window we get: ... Number of characters curses thinks are in a line is 77. ... If we use TERM=xterm, we do get the expected 78. Fix this by: - detecting when readline will report back less than the actual screen width, - accordingly setting a new variable readline_hidden_cols, - using readline_hidden_cols in tui_resize_all to fix the resize problem, and - removing the workaround in Term::resize. The test-case gdb.tui/empty.exp serves as regression test. I've applied the same fix in tui_async_resize_screen, the new test-case gdb.tui/resize-2.exp serves as a regression test for that change. Without that fix, we have: ... FAIL: gdb.tui/resize-2.exp: again: gdb width 80 ... Tested on x86_64-linux. PR tui/30337 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30337
2023-04-29gdb: Fix building with latest libc++Manoj Gupta2-2/+2
Latest libc++[1] causes transitive include to <locale> when <mutex> or <thread> header is included. This causes gdb to not build[2] since <locale> defines isupper/islower etc. functions that are explicitly macroed-out in safe-ctype.h to prevent their use. Use the suggestion from libc++ to include <locale> internally when building in C++ mode to avoid build errors. Use safe-gdb-ctype.h as the include instead of "safe-ctype.h" to keep this isolated to gdb since rest of binutils does not seem to use much C++. [1]: https://reviews.llvm.org/D144331 [2]: https://issuetracker.google.com/issues/277967395
2023-04-26[gdb/tui] Fix length of status line stringTom de Vries1-4/+7
In commit 5d10a2041eb ("gdb: add string_file::release method") this was added: ... + std::string string_val = string.release (); ... without updating subsequent uses of string.size (), which returns 0 after the string.release () call. Fix this by: - using string_val.size () instead of string.size (), and - adding an assert that would have caught this regression. Tested on x86_64-linux. Reviewed-By: Simon Marchi <simon.marchi@efficios.com> PR tui/30389 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30389
2023-04-13[gdb/tui] Revert workaround in tui_source_window::show_line_numberTom de Vries1-4/+2
The m_digits member of tui_source_window is documented as having semantics: ... /* How many digits to use when formatting the line number. This includes the trailing space. */ ... The commit 1b6d4bb2232 ("Redraw both spaces between line numbers and source code") started printing two trailing spaces instead: ... - xsnprintf (text, sizeof (text), "%*d ", m_digits - 1, lineno); + xsnprintf (text, sizeof (text), "%*d ", m_digits - 1, lineno); ... Now that PR30325 is fixed, this no longer has any effect. Fix this by reverting to the original behaviour: print one trailing space char. Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com>
2023-04-13[gdb/tui] Fix left margin in disassembly windowTom de Vries2-4/+5
With a hello world a.out, and maint set tui-left-margin-verbose on, we have this disassembly window: ... ┌───────────────────────────────────────────────────────────┐ │___ 0x555555555149 <main> endbr64 │ │___ 0x55555555514d <main+4> push %rbp │ │___ 0x55555555514e <main+5> mov %rsp,%rbp │ │B+> 0x555555555151 <main+8> lea 0xeac(%rip),%rax│ │___ 0x555555555158 <main+15> mov %rax,%rdi │ ... Note the space between "B+>" and 0x555555555151. The space shows that a bit of the left margin is not written, which is a problem because that location is showing a character previously written, which happens to be a space, but also may be something else, for instance a '[' as reported in PR tui/30325. The problem is caused by confusion about the meaning of: ... #define TUI_EXECINFO_SIZE 4 ... There's the meaning of defining the size of this zero-terminated char array: ... char element[TUI_EXECINFO_SIZE]; ... which is used to print the "B+>" bit, which is 3 chars wide. And there's the meaning of defining part of the size of the left margin: ... int left_margin () const { return 1 + TUI_EXECINFO_SIZE + extra_margin (); } ... where it represents 4 chars. The discrepancy between the two causes the space between "B+>" and "0x555555555151". Fix this by redefining TUI_EXECINFO_SIZE to 3, and using: ... char element[TUI_EXECINFO_SIZE + 1]; ... such that we have: ... |B+>0x555555555151 <main+8> lea 0xeac(%rip),%rax │ ... This changes the layout of the disassembly window back to what it was before commit 9e820dec13e ("Use a curses pad for source and disassembly windows"), the commit that introduced the PR30325 regression. This also changes the source window from: ... │___000005__{ | ... to: ... │___000005_{ | ... Tested on x86_64-linux. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30325 Approved-By: Tom Tromey <tom@tromey.com>
2023-04-13[gdb/tui] Add maint set/show tui-left-margin-verboseTom de Vries4-2/+29
The TUI has two types of windows derived from tui_source_window_base: - tui_source_window (the source window), and - tui_disasm_window (the disassembly window). The two windows share a common concept: the left margin. With a hello world a.out, we can see the source window: ... ┌─/home/vries/hello.c───────────────────────────────────────┐ │ 5 { │ │B+> 6 printf ("hello\n"); │ │ 7 return 0; │ │ 8 } │ │ 9 │ │ ... where the left margin is the part holding "B+>" and the line number, and the disassembly window: ... ┌───────────────────────────────────────────────────────────┐ │ 0x555555555149 <main> endbr64 │ │ 0x55555555514d <main+4> push %rbp │ │ 0x55555555514e <main+5> mov %rsp,%rbp │ │B+> 0x555555555151 <main+8> lea 0xeac(%rip),%rax│ │ 0x555555555158 <main+15> mov %rax,%rdi │ ... where the left margin is just the bit holding "B+>". Because the left margin contains some spaces, it's not clear where it starts and ends, making it harder to observe problems related to it. Add a new maintenance command "maint set tui-left-margin-verbose", that when set to on replaces the spaces in the left margin with either '_' or '0', giving us this for the source window: ... ┌─/home/vries/hello.c───────────────────────────────────────┐ │___000005__{ │ │B+>000006__ printf ("hello\n"); │ │___000007__ return 0; │ │___000008__} │ ... and this for the disassembly window: ... ┌───────────────────────────────────────────────────────────┐ │___ 0x555555555149 <main> endbr64 │ │___ 0x55555555514d <main+4> push %rbp │ │___ 0x55555555514e <main+5> mov %rsp,%rbp │ │B+> 0x555555555151 <main+8> lea 0xeac(%rip),%rax│ │___ 0x555555555158 <main+15> mov %rax,%rdi │ ... Note the space between "B+>" and 0x555555555151. The space shows that a bit of the left margin is not written, a problem reported as PR tui/30325. Specifically, PR tui/30325 is about the fact that the '[' character from the string "[ No Assembly Available ]" ends up in that same spot: ... │B+>[0x555555555151 <main+8> lea 0xeac(%rip),%rax│ ... which only happens for certain window widths. The new command allows us to spot the problem with any window width. Likewise, when we revert the fix from commit 1b6d4bb2232 ("Redraw both spaces between line numbers and source code"), we have: ... ┌─/home/vries/hello.c───────────────────────────────────────┐ │___000005_ { │ │B+>000006_ printf ("hello\n"); │ │___000007_ return 0; │ │___000008_ } │ ... showing a similar problem at the space between '_' and '{'. Tested on x86_64-linux. Reviewed-By: Eli Zaretskii <eliz@gnu.org> Approved-By: Tom Tromey <tom@tromey.com>
2023-03-09gdb, gdbserver, gdbsupport: fix whitespace issuesSimon Marchi1-6/+6
Replace spaces with tabs in a bunch of places. Change-Id: If0f87180f1d13028dc178e5a8af7882a067868b0
2023-02-27Forced quit cases handled by resetting sync_quit_force_runKevin Buettner2-0/+15
During my audit of the use of gdb_exception with regard to QUIT processing, I found a try/catch in the scoped_switch_fork_info destructor. Static analysis found this call path from the destructor to maybe_quit(): scoped_switch_fork_info::~scoped_switch_fork_info() -> remove_breakpoints() -> remove_breakpoint(bp_location*) -> remove_breakpoint_1(bp_location*, remove_bp_reason) -> memory_validate_breakpoint(gdbarch*, bp_target_info*) -> target_read_memory(unsigned long, unsigned char*, long) -> target_read(target_ops*, target_object, char const*, unsigned char*, unsigned long, long) -> maybe_quit() Since it's not safe to do a 'throw' from a destructor, we simply call set_quit_flag and, for gdb_exception_forced_quit, also set sync_quit_force_run. This will cause the appropriate exception to be rethrown at the next QUIT check. Another case is the try / catch in tui_getc() in tui-io.c. The existing catch swallows the exception. I've added a catch for 'gdb_exception_forced_quit', which also swallows the exception, but also sets sync_quit_force_run and calls set_quit_flag in order to restart forced quit processing at the next QUIT check. This is required because it isn't safe to throw into/through readline. Thanks to Pedro Alves for suggesting this idea. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=26761 Tested-by: Tom de Vries <tdevries@suse.de> Approved-By: Pedro Alves <pedro@palves.net>
2023-02-14Remove a use of pagination_enabledTom Tromey1-6/+0
I noticed that the TUI temporarily sets pagination_enabled and gdb_stdout in one spot. However, I don't believe these settings are necessary here, as a ui_file is passed to gdbarch_print_registers_info. This patch removes these settings.
2023-02-13gdb/tui: don't leak the known_window_types mapAndrew Burgess1-24/+17
This commit finishes the task that was started in the previous commit. Now that all Python TUI window factories are correctly deleted when the Python interpreter is shut down, we no longer need to dynamically allocate the known_window_types map in tui-layout.c This commit changes known_window_types to a statically allocated data structure, removes the dynamic allocation from initialize_known_windows, and then replaces lots of '->' with '.' throughout this file. There should be no user visible changes after this commit. Reviewed-By: Tom Tromey <tom@tromey.com>
2023-02-13gdb/python: allow Python TUI windows to be replacedAndrew Burgess1-0/+8
The documentation for gdb.register_window_type says: "... It's an error to try to replace one of the built-in windows, but other window types can be replaced. ..." I take this to mean that if I imported a Python script like this: gdb.register_window_type('my_window', FactoryFunction) Then GDB would have a new TUI window 'my_window', which could be created by calling FactoryFunction(). If I then, in the same GDB session imported a script which included: gdb.register_window_type('my_window', UpdatedFactoryFunction) Then GDB would replace the old 'my_window' factory with my new one, GDB would now call UpdatedFactoryFunction(). This is pretty useful in practice, as it allows users to iterate on their window implementation within a single GDB session. However, right now, this is not how GDB operates. The second call to register_window_type is basically ignored and the old window factory is retained. This is because in tui_register_window (tui/tui-layout.c) we use std::unordered_map::emplace to insert the new factory function, and emplace doesn't replace an existing element in an unordered_map. In this commit, before the emplace call, I now search for an already existing element, and delete any matching element from the map, the emplace call will then add the new factory function. Reviewed-By: Tom Tromey <tom@tromey.com>
2023-02-08Simplify interp::exec / interp_exec - let exceptions propagatePedro Alves1-2/+2
This patch implements a simplication that I suggested here: https://sourceware.org/pipermail/gdb-patches/2022-March/186320.html Currently, the interp::exec virtual method interface is such that subclass implementations must catch exceptions and then return them via normal function return. However, higher up the in chain, for the CLI we get to interpreter_exec_cmd, which does: for (i = 1; i < nrules; i++) { struct gdb_exception e = interp_exec (interp_to_use, prules[i]); if (e.reason < 0) { interp_set (old_interp, 0); error (_("error in command: \"%s\"."), prules[i]); } } and for MI we get to mi_cmd_interpreter_exec, which has: void mi_cmd_interpreter_exec (const char *command, char **argv, int argc) { ... for (i = 1; i < argc; i++) { struct gdb_exception e = interp_exec (interp_to_use, argv[i]); if (e.reason < 0) error ("%s", e.what ()); } } Note that if those errors are reached, we lose the original exception's error code. I can't see why we'd want that. And, I can't see why we need to have interp_exec catch the exception and return it via the normal return path. That's normally needed when we need to handle propagating exceptions across C code, like across readline or ncurses, but that's not the case here. It seems to me that we can simplify things by removing some try/catch-ing and just letting exceptions propagate normally. Note, the "error in command" error shown above, which only exists in the CLI interpreter-exec command, is only ever printed AFAICS if you run "interpreter-exec console" when the top level interpreter is already the console/tui. Like: (gdb) interpreter-exec console "foobar" Undefined command: "foobar". Try "help". error in command: "foobar". You won't see it with MI's "-interpreter-exec console" from a top level MI interpreter: (gdb) -interpreter-exec console "foobar" &"Undefined command: \"foobar\". Try \"help\".\n" ^error,msg="Undefined command: \"foobar\". Try \"help\"." (gdb) nor with MI's "-interpreter-exec mi" from a top level MI interpreter: (gdb) -interpreter-exec mi "-foobar" ^error,msg="Undefined MI command: foobar",code="undefined-command" ^done (gdb) in both these cases because MI's -interpreter-exec just does: error ("%s", e.what ()); You won't see it either when running an MI command with the CLI's "interpreter-exec mi": (gdb) interpreter-exec mi "-foobar" ^error,msg="Undefined MI command: foobar",code="undefined-command" (gdb) This last case is because MI's interp::exec implementation never returns an error: gdb_exception mi_interp::exec (const char *command) { mi_execute_command_wrapper (command); return gdb_exception (); } Thus I think that "error in command" error is pretty pointless, and since it simplifies things to not have it, the patch just removes it. The patch also ends up addressing an old FIXME. Change-Id: I5a6432a80496934ac7127594c53bf5221622e393 Approved-By: Tom Tromey <tromey@adacore.com> Approved-By: Kevin Buettner <kevinb@redhat.com>
2023-01-27gdb/tui: more debug outputAndrew Burgess2-0/+24
Add some additional debug output that I've found really useful while working on the previous set of patches. Unless tui debug is turned on, then there should be no user visible changes with this commit.
2023-01-27gdb/tui: avoid extra refresh_window on vertical scrollAndrew Burgess2-7/+14
While working on the previous couple of patches I noticed that when I scroll the src and asm windows vertically, I get two refresh_window calls. The two calls can be traced back to tui_source_window_base::update_source_window_as_is, in here we call show_source_content, which calls refresh_window, and then update_exec_info, which also calls refresh_window. In this commit I propose making the refresh_window call in update_exec_info optional. In update_source_window_as_is I'll then call update_exec_info before calling show_source_content, and pass a flag to update_exec_info to defer the refresh. There are places where update_exec_info is used without any subsequent refresh_window call (e.g. when a breakpoint is updated), so update_exec_info does not to call refresh_window in some cases, which is why I'm using a flag to control the refresh. With this changes I'm now only seeing a single refresh_window call for each vertical scroll. There should be no user visible changes after this commit.
2023-01-27gdb/tui: avoid extra refresh_window on horizontal scrollAndrew Burgess1-3/+5
While working on the previous patches I noticed that in some cases I was seeing two calls to tui_source_window_base::refresh_window when scrolling the window horizontally. The two calls would trigger in for the tui-disasm-long-lines.exp test when the pad needed to be refilled. The two called both come from tui_source_window_base::show_source_content. The first call is nested within check_and_display_highlight_if_needed, while the second call is done directly at the end of show_source_content. The check_and_display_highlight_if_needed is being used to draw the window box to the window, this is needed here because show_source_content is what gets called when the window needs updating, e.g. after a resize. We could potentially do the boxing in refresh_window, but then we'd be doing it each time we scroll, even though the box doesn't need changing in this case. However, we can move the check_and_display_highlight_if_needed to be the last thing done in show_source_content, this means that we can rely on the refresh_window call within it to be our single refresh call. There should be no user visible changes after this commit.
2023-01-27gdb/tui: rewrite of tui_source_window_base to handle very long linesAndrew Burgess2-17/+214
This commit addresses an issue that is exposed by the test script gdb.tui/tui-disasm-long-lines.exp, that is, tui_source_window_base does not handle very long lines. The problem can be traced back to the newpad call in tui_source_window_base::show_source_content, this is where we allocate a backing pad to hold the window content. Unfortunately, there appears to be a limit to the size of pad that can be allocated, and the gdb.tui/tui-disasm-long-lines.exp test goes beyond this limit. As a consequence the newpad call fails and returns nullptr. It just so happens that the reset of the tui_source_window_base code can handle the pad being nullptr (this happens anyway when the window is first created, so we already depend on nullptr handling), so all that happens is the source window displays no content. ... well, sort of ... something weird does happen in the command window, we seem to see a whole bunch of blank lines. I've not bothered to track down exactly what's happening there, but it's some consequence of GDB attempting to write content to a WINDOW* that is nullptr. Before explaining my solution, I'll outline how things currently work: Consider we have the following window content to display: aaaaaaaaaa bbbbbbbbbbbbbbbbbbbb ccccccccccccccc the longest line here is 20 characters. If our display window is 10 characters wide, then we will create a pad that is 20 characters wide, and then copy the lines of content into the pad: .--------------------. |aaaaaaaaaa | |bbbbbbbbbbbbbbbbbbbb| |ccccccccccccccc | .--------------------. Now we will copy a 10 character wide view into this pad to the display, our display will then see: .----------. |aaaaaaaaaa| |bbbbbbbbbb| |cccccccccc| .----------. As the user scrolls left and right we adjust m_horizontal_offset and use this to select which part of the pad is copied onto the display. The benefit of this is that we only need to copy the content to the pad once, which includes processing the ansi escape sequences, and then the user can scroll left and right as much as they want relatively cheaply. The problem then, is that if the longest content line is very long, then we try to allocate a very large pad, which can fail. What I propose is that we allow both the pad and the display view to scroll. Once we allow this, then it becomes possible to allocate a pad that is smaller than the longest display line. We then copy part of the content into the pad. As the user scrolls the view left and right GDB will continue to copy content from the pad just as it does right now. But, when the user scrolls to the edge of the pad, GDB will copy a new block of content into the pad, and then update the view as normal. This all works fine so long as the maximum pad size is larger than the current window size - which seems a reasonable restriction, if ncurses can't support a pad of a given size it seems likely it will not support a display window of that size either. If we return to our example above, but this time we assume that the maximum pad size is 15 characters, then initially the pad would be loaded like this: .---------------. |aaaaaaaaaa | |bbbbbbbbbbbbbbb| |ccccccccccccccc| .---------------. Notice that the last 5 characters from the 'b' line are no longer included in the pad. There is still enough content though to fill the 10 character wide display, just as we did before. The pad contents remain unchanged until the user scrolls the display right to this point: .----------. |aaaaa | |bbbbbbbbbb| |cccccccccc| .----------. Now, when the user scrolls right once more GDB spots that the user has reached the end of the pad, and the pad contents are reloaded, like this: .---------------. |aaaaa | |bbbbbbbbbbbbbbb| |cccccccccc | .---------------. The display can now be updated from the pad again just like normal. With this change in place the gdb.tui/tui-disasm-long-lines.exp test now correctly loads the assembler code, and we can scroll around as expected. Most of the changes are pretty mundane, just updating to match the above. One interesting change though is the new member function tui_source_window_base::puts_to_pad_with_skip. This replaces direct calls to tui_puts when copying content to the pad. The content strings contain ansi escape sequences. When these strings are written to the pad these escape sequences are translated into ncurses attribute setting calls. Now however, we sometimes only write a partial string to the pad, skipping some of the leading content. Imagine then that we have a content line like this: "\033[31mABCDEFGHIJKLM\033[0m" Now the escape sequences in this content mean that the actual content (the 'ABCDEFGHIJKLM') will have a red foreground color. If we want to copy this to the pad, but skip the first 3 characters, then what we expect is to have the pad contain 'DEFGHIJKLM', but this text should still have a red foreground color. It is this problem that puts_to_pad_with_skip solves. This function skips some number of printable characters, but processes all the escape sequences. This means that when we do start printing the actual content the content will have the expected attributes. /
2023-01-27gdb/tui: make m_horizontal_offset privateAndrew Burgess1-2/+4
I noticed that tui_source_window_base::m_horizontal_offset was protected, but could be made private, so lets do that. This makes more sense in the context of a later commit where I plan to add another member variable that is similar to m_horizontal_offset. The new member variable could also be private. So I had to choose, place the new member variable next to m_horizontal_offset making it protected, but grouping similar variables together, or make m_horizontal_offset private, and then add the new variable as private too. I chose to make m_horizontal_offset private, which is this commit. There should be no user visible changes after this commit.
2023-01-27gdb/tui: improve errors from tui focus commandAndrew Burgess3-5/+99
This commit improves (I think) the errors from the tui focus command. There are a number of errors that can be triggered by the focus command, they include: (1) Window name "NAME" is ambiguous (2) Unrecognized window name "NAME" (3) Window "NAME" cannot be focused Error (1) is triggered when the user gives a partial window name, and the name matches multiple windows in the current layout. It is worth noting that the ambiguity must be within the current layout; if the partial name matches one window in the current layout, and one or more windows not in the current layout, then this is not ambiguous, and focus will shift to the matching window in the current layout. This error was not previous being tested, but in this commit I make use of the Python API to trigger and test this error. Error (3) is simple enough, and was already being tested. This is triggered by something like 'focus status'. The named window needs to be present in the current layout, and non-focusable in order to trigger the error. Error (2) is what I'd like to improve in this commit. This error triggers if the name the user gives doesn't match any window in the current layout. Even if GDB does know about the window, but the window isn't in the current layout, then GDB will say it doesn't recognize the window name. In this commit I propose to to split this error into three different errors. These will be: (a) Unrecognized window name "NAME" (b) No windows matching "NAME" in the current layout (c) Window "NAME" is not in the current layout Error (a) is the same as before, but will now only trigger if GDB doesn't know about window NAME at all. If the window is known, but not in the current layout then one of the other errors will trigger. Error (b) will trigger if NAME is ambiguous for multiple windows that are not in the current layout. If NAME identifies a single window in the current layout then that window will continue to be selected, just as it currently is. Only in the case where NAME doesn't identify a window in the current layout do we then check all the other known windows, if NAME matches multiple of these, then (b) is triggered. Finally, error (c) is used when NAME uniquely identifies a single window that is not in the current layout. The hope with these new errors is that the user will have a better understanding of what went wrong. Instead of GDB claiming to not know about a window, the mention of the current layout will hint to the user that they should first switch layouts. There are tests included for all the new errors.
2023-01-25gdb/tui: make use of a scoped_restoreAndrew Burgess1-7/+3
Make use of a scoped_restore object in tui_mld_read_key instead of doing a manual save/restore. I don't think the existing code can throw an exception, so this is just a cleanup rather than a bug fix. There should be no user visible changes after this commit.
2023-01-25gdb/tui: better filtering of tab completion results for focus commandAndrew Burgess1-7/+17
While working on the previous couple of commits, I noticed that the 'focus' command would happily suggest 'status' as a possible focus completion, even though the 'status' window is non-focusable, and, after the previous couple of commits, trying to focus the status window will result in an error. This commit improves the tab-completion results for the focus command so that the status window is not included.
2023-01-25gdb/tui: convert if/error to an assertAndrew Burgess1-2/+5
While working on the previous commit, I realised that there was an error in tui_set_focus_command that could never be triggered. Since the big tui rewrite (adding dynamic layouts) it is no longer true that there is a tui_win_info object for every window at all times. We now only create a tui_win_info object for a particular window, when the window is part of the current layout. As a result, if we have a tui_win_info pointer, then the window must be visible inside tui_set_focus_command (this function calls tui_enable as its first action, which makes the current layout visible). The gdb.tui/tui-focus.exp test script exercises this area of code, and doesn't trigger the assert, nor do any of our other existing tui tests.