aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite
AgeCommit message (Collapse)AuthorFilesLines
2022-04-12Add C++ "save gdb-index" testTom Tromey2-0/+64
I found a bug in the new DWARF reader series, related to the handling of enumerator names. This bug caused a crash, so this patch adds a regression test for this particular case. I'm checking this in.
2022-04-12Require GNAT debug info for some Ada testsTom Tromey5-0/+25
A few Ada tests require some debug info in the GNAT runtime. When run without this info, these tests can't pass. This patch changes these tests to detect this situation and stop with "untested".
2022-04-11gdb/fortran/testsuite: add complex from integers testNils-Christian Kempke2-1/+12
When working on the files I noted that there was no actual test for a COMPLEX built from two INTEGERS. I added that now for completion.
2022-04-11gdb/fortran: rewrite intrinsic handling and add some missing overloadsNils-Christian Kempke5-70/+351
The operators FLOOR, CEILING, CMPLX, LBOUND, UBOUND, and SIZE accept (some only with Fortran 2003) the optional parameter KIND. This parameter determines the kind of the associated return value. So far, implementation of this kind parameter has been missing in GDB. Additionally, the one argument overload for the CMPLX intrinsic function was not yet available. This patch adds overloads for all above mentioned functions to the Fortran intrinsics handling in GDB. It re-writes the intrinsic function handling section to use the helper methods wrap_unop_intrinsic/wrap_binop_intrinsic/wrap_triop_intrinsic. These methods define the action taken when a Fortran intrinsic function is called with a certain amount of arguments (1/2/3). The helper methods fortran_wrap2_kind and fortran_wrap3_kind have been added as equivalents to the existing wrap and wrap2 methods. After adding more overloads to the intrinsics handling, some of the operation names were no longer accurate. E.g. UNOP_FORTRAN_CEILING has been renamed to FORTRAN_CEILING as it is no longer a purely unary intrinsic function. This patch also introduces intrinsic functions with one, two, or three arguments to the Fortran parser and the UNOP_OR_BINOP_OR_TERNOP_INTRINSIC token has been added.
2022-04-11gdb/fortran: Change GDB print for fortran default typesNils-Christian Kempke2-14/+9
Currently, when asking GDB to print the type of a Fortran default type such as INTEGER or REAL, GDB will return the default name of that type, e.g. "integer"/"real": (gdb) ptype integer type = integer (gdb) ptype real type = real For LOGICAL and COMPLEX it would return the actual underlying types (gdb) ptype logical type = logical*4 (gdb) ptype complex type = complex*4 Similarly, GDB would print the default integer type for the underlying default type: (gdb) ptype integer*4 type = integer (gdb) ptype real*4 type = real (gdb) ptype logical type = logical*4 (gdb) ptype complex*4 type = complex*4 This is inconsistent and a bit confusing. Both options somehow indicate what the internal underlying type for the default type is - but I think the logical/complex version is a bit clearer. Consider again: (gdb) ptype integer type = integer This indicates to a user that the type of "integer" is Fortran's default integer type. Without examining "ptype integer*4" I would expect, that any variable declared integer in the actual code would also fit into a GDB integer. But, since we cannot adapt out internal types to the compiler flags used at compile time of a debugged binary, this might be wrong. Consider debugging Fortran code compiled with GNU and e.g. the "-fdefault-integer-8" flag. In this case the gfortran default integer would be integer*8 while GDB internally still would use a builtin_integer, so an integer of the size of an integer*4 type. On the other hand having GDB print (gdb) ptype integer type = integer*4 makes this clearer. I would still be tempted to fit a variable declared integer in the code into a GDB integer - but at least ptype would directly tell me what is going on. Note, that when debugging a binary compiled with "-fdefault-integer-8" a user will always see the actual underlying type of any variable declared "integer" in the Fortran code. So having the code program test integer :: a = 5 print *, a ! breakpt end program test will, when breaking at breakpt print (gdb) ptype var type = integer(kind=4) or (gdb) ptype var type = integer(kind=8) depending on the compiler flag. This patch changes the outputs for the REAL and INTEGER default types to actually print the internally used type over the default type name. The new behavior for the above examples is: (gdb) ptype integer type = integer*4 (gdb) ptype integer*4 type = integer*4 Existing testcases have been adapted to reflect the new behavior.
2022-04-11gdb/fortran: clean-up Fortran intrinsic typesNils-Christian Kempke1-4/+27
The currently implemented intrinsic type handling for Fortran missed some tokens and their parsing. While still not all Fortran type kinds are implemented this patch at least makes the currently handled types consistent. As an example for what this patch does, consider the intrinsic type INTEGER. GDB implemented the handling of the keywords "integer" and "integer_2" but missed "integer_4" and "integer_8" even though their corresponding internal types were already available as the Fortran builtin types builtin_integer and builtin_integer_s8. Similar problems applied to LOGICAL, REAL, and COMPLEX. This patch adds all missing tokens and their parsing. Whenever a section containing the type handling was touched, it also was reordered to be in a more easy to grasp order. All INTEGER/REAL/LOGICAL/COMPLEX types were grouped together and ordered ascending in their size making a missing one more easy to spot. Before this change GDB would print the following when tyring to use the INTEGER keywords: (gdb) set language fortran (gdb) ptype integer*1 unsupported kind 1 for type integer (gdb) ptype integer_1 No symbol table is loaded. Use the "file" command. (gdb) ptype integer*2 type = integer*2 (gdb) ptype integer_2 type = integer*2 (gdb) ptype integer*4 type = integer (gdb) ptype integer_4 No symbol table is loaded. Use the "file" command. (gdb) ptype integer*8 type = integer*8 (gdb) ptype integer_8 No symbol table is loaded. Use the "file" command. (gdb) ptype integer type = integer With this patch all keywords are available and the GDB prints: (gdb) set language fortran (gdb) ptype integer*1 type = integer*1 (gdb) ptype integer_1 type = integer*1 (gdb) ptype integer*2 type = integer*2 (gdb) ptype integer_2 type = integer*2 (gdb) ptype integer*4 type = integer*4 (gdb) ptype integer_4 type = integer*4 (gdb) ptype integer*8 type = integer*8 (gdb) ptype integer_8 type = integer*8 (gdb) ptype integer type = integer The described changes have been applied to INTEGER, REAL, COMPLEX, and LOGICAL. Existing testcases have been adapted to reflect the new behavior. Tests for formerly missing types have been added.
2022-04-11gdb/fortran: change default logical type to builtin_logicalNils-Christian Kempke1-4/+4
According to the Fortran standard, logical is of the size of a 'single numeric storage unit' (just like real and integer). For gfortran, flang and ifx/ifort this storage unit (or the default logical type) is of size kind 4, actually occupying 4 bytes of storage, and so the default type for logical expressions in Fortran should probably also be Logical*4 and not Logical*2. I adapted GDB's behavior to be in line with gfortran/ifort/ifx/flang.
2022-04-11gdb/fortran: fix complex type in Fortran builtin typesNils-Christian Kempke1-1/+1
Before this patch things like (gdb) ptype complex*8 complex*16 (gdb) ptype complex*4 complex*8 were possible in GDB, which seems confusing for a user. The reason is a mixup in the implementation of the Fortran COMPLEX type. In Fortran the "*X" after a type would normally (I don't think this is language required) specify the type's size in memory. For the COMPLEX type the kind parameters usually (at least for GNU, Intel, Flang) specify not the size of the whole type but the size of the individual two REALs used to form the COMPLEX. Thus, a COMPLEX*4 will usually consist of two REAL*4s. Internally this type was represented by a builtin_complex_s8 - but here I think the s8 actually meant the raw size of the type. This is confusing and I renamed the types (e.g. builting_complex_s8 became builtin_complex_s4 according to its most common useage) and their printed names to their language equivalent. Additionally, I added the default COMPLEX type "COMPLEX" being the same as a COMPLEX*4 (as is normally the case) and removed the latter. I added a few tests for this new behavior as well. The new behavior is (gdb) ptype complex*8 complex*8 (gdb) ptype complex*4 complex*4
2022-04-11gdb/f-lang: add Integer*1 to Fortran builtin typesNils-Christian Kempke2-1/+3
Add builtin_integer_s1 of size TARGET_CHAR_BIT to Fortran builtin types.
2022-04-11[gdb/testsuite] Fix gdb.base/annota1.exp with pieTom de Vries1-0/+2
Since commit 359efc2d894 ("[gdb/testsuite] Make gdb.base/annota1.exp more robust") we see this fail with target board unix/-fPIE/-pie: ... FAIL: gdb.base/annota1.exp: run until main breakpoint (timeout) ... The problem is that the commit makes the number and order of matched annotations fixed, while between target boards unix and unix/-fPIE/-pie there is a difference: ... \032\032post-prompt Starting program: outputs/gdb.base/annota1/annota1 +\032\032breakpoints-invalid + \032\032starting \032\032frames-invalid ... Fix this by optionally matching the additional annotation. Tested on x86_64-linux.
2022-04-11[gdb/testsuite] Fix gdb.dwarf2/dw2-lines.exp for m32 pieTom de Vries1-1/+1
As reported in PR29043, when running test-case gdb.dwarf2/dw2-lines.exp with target board unix/-m32/-fPIE/-pie, we run into: ... Breakpoint 2, 0x56555540 in bar ()^M (gdb) PASS: gdb.dwarf2/dw2-lines.exp: cv=2: cdw=32: lv=2: ldw=32: \ continue to breakpoint: foo \(1\) next^M Single stepping until exit from function bar,^M which has no line number information.^M 0x56555587 in main ()^M (gdb) FAIL: gdb.dwarf2/dw2-lines.exp: cv=2: cdw=32: lv=2: ldw=32: \ next to foo (2) ... The problem is that the bar breakpoint ends up at an unexpected location because: - the synthetic debug info is incomplete and doesn't provide line info for the prologue part of the function, so consequently gdb uses the i386 port prologue skipper to get past the prologue - the i386 port prologue skipper doesn't get past a get_pc_thunk call. Work around this in the test-case by breaking on bar_label instead. Tested on x86_64-linux with target boards unix, unix/-m32, unix/-fPIE/-pie and unix/-m32/-fPIE/-pie.
2022-04-08gdb: Avoid undefined shifts, fix Go shiftsPedro Alves1-0/+368
I noticed that a build of GDB with GCC + --enable-ubsan, testing against GDBserver showed this GDB crash: (gdb) PASS: gdb.trace/trace-condition.exp: trace: 0x00abababcdcdcdcd << 46 == 0x7373400000000000: advance to trace begin tstart ../../src/gdb/valarith.c:1365:15: runtime error: left shift of 48320975398096333 by 46 places cannot be represented in type 'long int' ERROR: GDB process no longer exists GDB process exited with wait status 269549 exp9 0 1 UNRESOLVED: gdb.trace/trace-condition.exp: trace: 0x00abababcdcdcdcd << 46 == 0x7373400000000000: start trace experiment The problem is that, "0x00abababcdcdcdcd << 46" is an undefined signed left shift, because the result is not representable in the type of the lhs, which is signed. This actually became defined in C++20, and if you compile with "g++ -std=c++20 -Wall", you'll see that GCC no longer warns about it, while it warns if you specify prior language versions. While at it, there are a couple other situations that are undefined (and are still undefined in C++20) and result in GDB dying: shifting by a negative ammount, or by >= than the bit size of the promoted lhs. For the latter, GDB shifts using (U)LONGEST internally, so you have to shift by >= 64 bits to see it: $ gdb --batch -q -ex "p 1 << -1" ../../src/gdb/valarith.c:1365:15: runtime error: shift exponent -1 is negative $ # gdb exited $ gdb --batch -q -ex "p 1 << 64" ../../src/gdb/valarith.c:1365:15: runtime error: shift exponent 64 is too large for 64-bit type 'long int' $ # gdb exited Also, right shifting a negative value is implementation-defined (before C++20, after which it is defined). For this, I chose to change nothing in GDB other than adding tests, as I don't really know whether we need to do anything. AFAIK, most implementations do an arithmetic right shift, and it may be we don't support any host or target that behaves differently. Plus, this becomes defined in C++20 exactly as arithmetic right shift. Compilers don't error out on such shifts, at best they warn, so I think GDB should just continue doing the shifts anyhow too. Thus: - Adjust scalar_binop to avoid the undefined paths, either by adding explicit result paths, or by casting the lhs of the left shift to unsigned, as appropriate. For the shifts by a too-large count, I made the result be what you'd get if you split the large count in a series of smaller shifts. Thus: Left shift, positive or negative lhs: V << 64 => V << 16 << 16 << 16 << 16 => 0 Right shift, positive lhs: Vpos >> 64 => Vpos >> 16 >> 16 >> 16 >> 16 => 0 Right shift, negative lhs: Vneg >> 64 => Vneg >> 16 >> 16 >> 16 >> 16 => -1 This is actually Go's semantics (the compiler really emits instructions to make it so that you get 0 or -1 if you have a too-large shift). So for that language GDB does the shift and nothing else. For other C-like languages where such a shift is undefined, GDB warns in addition to performing the shift. For shift by a negative count, for Go, this is a hard error. For other languages, since their compilers only warn, I made GDB warn too. The semantics I chose (we're free to pick them since this is undefined behavior) is as-if you had shifted by the count cast to unsigned, thus as if you had shifted by a too-large count, thus the same as the previous scenario illustrated above. Examples: (gdb) set language go (gdb) p 1 << 100 $1 = 0 (gdb) p -1 << 100 $2 = 0 (gdb) p 1 >> 100 $3 = 0 (gdb) p -1 >> 100 $4 = -1 (gdb) p -2 >> 100 $5 = -1 (gdb) p 1 << -1 left shift count is negative (gdb) set language c (gdb) p -2 >> 100 warning: right shift count >= width of type $6 = -1 (gdb) p -2 << 100 warning: left shift count >= width of type $7 = 0 (gdb) p 1 << -1 warning: left shift count is negative $8 = 0 (gdb) p -1 >> -1 warning: right shift count is negative $9 = -1 - The warnings' texts are the same as what GCC prints. - Add comprehensive tests in a new gdb.base/bitshift.exp testcase, so that we exercise all these scenarios. Change-Id: I8bcd5fa02de3114b7ababc03e65702d86ec8d45d
2022-04-08Fix undefined behavior in the Fortran, Go and Pascal number parsersPedro Alves3-26/+79
This commit ports these two fixes to the C parser: commit ebf13736b42af47c9907b5157c8e80c78dbe00e1 CommitDate: Thu Sep 4 21:46:28 2014 +0100 parse_number("0") reads uninitialized memory commit 20562150d8a894bc91657c843ee88c508188e32e CommitDate: Wed Oct 3 15:19:06 2018 -0600 Avoid undefined behavior in parse_number ... to the Fortran, Go, and Fortran number parsers, fixing the same problems there. Also add a new testcase that exercises printing 0xffffffffffffffff (max 64-bit) in all languages, which crashes a GDB built with UBsan without the fix. I moved get_set_option_choices out of all-architectures.exp.tcl to common code to be able to extract all the supported languages. I did a tweak to it to generalize it a bit -- you now have to pass down the "set" part of the command as well. This is so that the proc can be used with "maintenance set" commands as well in future. Change-Id: I8e8f2fdc1e8407f63d923c26fd55d98148b9e16a
2022-04-08gdb/testsuite: use nopie in gdb.dwarf2/dw2-inline-param.expSimon Marchi1-3/+5
I see this failure: (gdb) run ^M Starting program: /home/smarchi/build/binutils-gdb/gdb/testsuite/outputs/gdb.dwarf2/dw2-inline-param/dw2-inline-param ^M Warning:^M Cannot insert breakpoint 1.^M Cannot access memory at address 0x113b^M ^M (gdb) FAIL: gdb.dwarf2/dw2-inline-param.exp: runto: run to *0x113b The test loads the binary in GDB, grabs the address of a symbol, strips the binary, reloads it in GDB, runs the program, and then tries to place a breakpoint at that address. The problem is that the binary is built as position independent, so the address GDB grabs in the first place isn't where the code ends up after running. Fix this by linking the binary as non-position-independent. The alternative would be to compute the relocated address where to place the breakpoint, but that's not very straightforward, unfortunately. I was confused for a while, I was trying to load the binary in GDB manually to get the symbol address, but GDB was telling me the symbol could not be found. Meanwhile, it clearly worked in gdb.log. The thing is that GDB strips the binary in-place, so we don't have access to the intermediary binary with symbols. Change the test to output the stripped binary to a separate file instead. Change-Id: I66c56293df71b1ff49cf748d6784bd0e935211ba
2022-04-08gdb/fortran: print fortran extended types with ptypeBernhard Heckel1-17/+48
Add the print of the base-class of an extended type to the output of ptype. This requires the Fortran compiler to emit DW_AT_inheritance for the extended type. Co-authored-by: Nils-Christian Kempke <nils-christian.kempke@intel.com>
2022-04-08gdb/fortran: add support for accessing fields of extended typesBernhard Heckel2-0/+228
Fortran 2003 supports type extension. This patch allows access to inherited members by using their fully qualified name as described in the Fortran standard. In doing so the patch also fixes a bug in GDB when trying to access the members of a base class in a derived class via the derived class' base class member. This patch fixes PR22497 and PR26373 on GDB side. Using the example Fortran program from PR22497 program mvce implicit none type :: my_type integer :: my_int end type my_type type, extends(my_type) :: extended_type end type extended_type type(my_type) :: foo type(extended_type) :: bar foo%my_int = 0 bar%my_int = 1 print*, foo, bar end program mvce and running this with GDB and setting a BP at 17: Before: (gdb) p bar%my_type A syntax error in expression, near `my_type'. (gdb) p bar%my_int There is no member named my_int. (gdb) p bar%my_type%my_int A syntax error in expression, near `my_type%my_int'. (gdb) p bar $1 = ( my_type = ( my_int = 1 ) ) After: (gdb) p bar%my_type $1 = ( my_int = 1 ) (gdb) p bar%my_int $2 = 1 # this line requires DW_TAG_inheritance to work (gdb) p bar%my_type%my_int $3 = 1 (gdb) p bar $4 = ( my_type = ( my_int = 1 ) ) In the above example "p bar%my_int" requires the compiler to emit information about the inheritance relationship between extended_type and my_type which gfortran and flang currently do not de. The respective issue gcc/49475 has been put as kfail. Co-authored-by: Nils-Christian Kempke <nils-christian.kempke@intel.com> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=26373 https://sourceware.org/bugzilla/show_bug.cgi?id=22497
2022-04-07gdb/fortran: fix fetching assumed rank array contentAndrew Burgess2-11/+23
Commit: commit df7a7bdd9766adebc6b117c31bc617d81c1efd43 Date: Thu Mar 17 18:56:23 2022 +0000 gdb: add support for Fortran's ASSUMED RANK arrays Added support for Fortran assumed rank arrays. Unfortunately, this commit contained a bug that means though GDB can correctly calculate the rank of an assumed rank array, GDB can't fetch the contents of an assumed rank array. The history of this patch can be seen on the mailing list here: https://sourceware.org/pipermail/gdb-patches/2022-January/185306.html The patches that were finally committed can be found here: https://sourceware.org/pipermail/gdb-patches/2022-March/186906.html The original patches did support fetching the array contents, it was only the later series that introduced the regression. The problem is that when calculating the array rank the result is a count of the number of ranks, i.e. this is a 1 based result, 1, 2, 3, etc. In contrast, when computing the details of any particular rank the value passed to the DWARF expression evaluator should be a 0 based rank offset, i.e. a 0 based number, 0, 1, 2, etc. In the patches that were originally merged, this was not the case, and we were passing the 1 based rank number to the expression evaluator, e.g. passing 1 when we should pass 0, 2 when we should pass 1, etc. As a result the DWARF expression evaluator was reading the wrong (undefined) memory, and returning garbage results. In this commit I have extended the test case to cover checking the array contents, I've then ensured we make use of the correct rank value, and extended some comments, and added or adjusted some asserts as appropriate.
2022-04-07gdb/testsuite: add "macros" option to gdb_compileSimon Marchi5-48/+22
Make gdb_compile handle a new "macros" option, which makes it pass the appropriate flag to make the compiler include macro information in the debug info. This will help simplify tests using macros, reduce redundant code, and make it easier to add support for a new compiler. Right now it only handles clang specially (using -fdebug-macro) and falls back to -g3 otherwise (which works for gcc). Other compilers can be added as needed. There are some tests that are currently skipped if the compiler is nor gcc nor clang. After this patch, the tests will attempt to run (the -g3 fall back will be used). That gives a chance to people using other compilers to notice something is wrong and maybe add support for their compiler. If it is needed to support a compiler that doesn't have a way to include macro information, then we can always introduce a "skip_macro_tests" that can be used to skip over them. Change-Id: I50cd6ab1bfbb478c1005486408e214b551364c9b
2022-04-07[gdb/testsuite] Make gdb.base/annota1.exp more robustTom de Vries1-24/+47
On openSUSE Tumbleweed I run into: ... FAIL: gdb.base/annota1.exp: run until main breakpoint (timeout) ... The problem is that the libthread_db message occurs at a location where it's not expected: ... Starting program: outputs/gdb.base/annota1/annota1 ^M ^M ^Z^Zstarting^M ^M ^Z^Zframes-invalid^M [Thread debugging using libthread_db enabled]^M Using host libthread_db library "/lib64/libthread_db.so.1".^M ^M ^Z^Zbreakpoints-invalid^M ^M ... Fix this by making the matching more robust: - rewrite the regexp such that each annotation is on a single line, starting with \r\n\032\032 and ending with \r\n - add a regexp variable optional_re, that matches all possible optional output, and use it as a separator in the first part of the regexp Tested on x86_64-linux.
2022-04-07gdb/testsuite/dwarf: simplify line number program syntaxSimon Marchi26-683/+681
By calling `uplevel $body` in the program proc (a pattern we use at many places), we can get rid of curly braces around each line number program directive. That seems like a nice small improvement to me. Change-Id: Ib327edcbffbd4c23a08614adee56c12ea25ebc0b
2022-04-07gdb/testsuite/dwarf: remove two unused variablesSimon Marchi1-19/+0
These variables seem to be unused, remove them. Change-Id: I7d613d9d35735930ee78b2c348943c73a702afbb
2022-04-07gdb/testsuite: make gdb_breakpoint and runto take a linespecSimon Marchi1-11/+13
Change gdb_breakpoint to accept a linespec, not just a function. In fact, no behavior changes are necessary, this only changes the parameter name and documentation. Change runto as well, since the two are so close (runto forwards all its arguments to gdb_breakpoint). I wrote this for a downstrean GDB port, but thought it could be useful upstream, eventually, even though not callers take advantage of it yet. Change-Id: I08175fd444d5a60df90fd9985e1b5dfd87c027cc
2022-04-07gdb/tui: fix 'tui reg next/prev' command when data window is hiddenAndrew Burgess1-0/+26
Start GDB like: $ gdb -q executable (gdb) start (gdb) layout src ... tui windows are now displayed ... (gdb) tui reg next At this point the data (register) window should be displayed, but will contain the message 'Register Values Unavailable', and at the console you'll see the message "unknown register group 'next'". The same happens with 'tui reg prev' (but the error message is slightly different). At this point you can continue to use 'tui reg next' and/or 'tui reg prev' and you'll keep getting the error message. The problem is that when the data (register) window is first displayed, it's current register group is nullptr. As a consequence tui_reg_next and tui_reg_prev (tui/tui-regs.c) will always just return nullptr, which triggers an error in tui_reg_command. In this commit I change tui_reg_next and tui_reg_prev so that they instead return the first and last register group respectively if the current register group is nullptr. So, after this, using 'tui reg next' will (in the above case) show the first register group, while 'tui reg prev' will display the last register group.
2022-04-06gdb: don't copy entirely optimized out values in value_copySimon Marchi1-0/+3
Bug 28980 shows that trying to value_copy an entirely optimized out value causes an internal error. The original bug report involves MI and some Python pretty printer, and is quite difficult to reproduce, but another easy way to reproduce (that is believed to be equivalent) was proposed: $ ./gdb -q -nx --data-directory=data-directory -ex "py print(gdb.Value(gdb.Value(5).type.optimized_out()))" /home/smarchi/src/binutils-gdb/gdb/value.c:1731: internal-error: value_copy: Assertion `arg->contents != nullptr' failed. This is caused by 5f8ab46bc691 ("gdb: constify parameter of value_copy"). It added an assertion that the contents buffer is allocated if the value is not lazy: if (!value_lazy (val)) { gdb_assert (arg->contents != nullptr); This was based on the comment on value::contents, which suggest that this is the case: /* Actual contents of the value. Target byte-order. NULL or not valid if lazy is nonzero. */ gdb::unique_xmalloc_ptr<gdb_byte> contents; However, it turns out that it can also be nullptr also if the value is entirely optimized out, for example on exit of allocate_optimized_out_value. That function creates a lazy value, marks the entire value as optimized out, and then clears the lazy flag. But contents remains nullptr. This wasn't a problem for value_copy before, because it was calling value_contents_all_raw on the input value, which caused contents to be allocated before doing the copy. This means that the input value to value_copy did not have its contents allocated on entry, but had it allocated on exit. The result value had it allocated on exit. And that we copied bytes for an entirely optimized out value (i.e. meaningless bytes). From here I see two choices: 1. respect the documented invariant that contents is nullptr only and only if the value is lazy, which means making allocate_optimized_out_value allocate contents 2. extend the cases where contents can be nullptr to also include values that are entirely optimized out (note that you could still have some entirely optimized out values that do have contents allocated, it depends on how they were created) and adjust value_copy accordingly Choice #1 is safe, but less efficient: it's not very useful to allocate a buffer for an entirely optimized out value. It's even a bit less efficient than what we had initially, because values coming out of allocate_optimized_out_value would now always get their contents allocated. Choice #2 would be more efficient than what we had before: giving an optimized out value without allocated contents to value_copy would result in an optimized out value without allocated contents (and the input value would still be without allocated contents on exit). But it's more risky, since it's difficult to ensure that all users of the contents (through the various_contents* accessors) are all fine with that new invariant. In this patch, I opt for choice #2, since I think it is a better direction than choice #1. #1 would be a pessimization, and if we go this way, I doubt that it will ever be revisited, it will just stay that way forever. Add a selftest to test this. I initially started to write it as a Python test (since the reproducer is in Python), but a selftest is more straightforward. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28980 Change-Id: I6e2f5c0ea804fafa041fcc4345d47064b5900ed7
2022-04-05gdb/testsuite: fix intermittent failure in gdb.base/vfork-follow-parent.expSimon Marchi2-1/+15
Tom de Vries reported some failures in this test: continue Continuing. [New inferior 2 (process 14967)] Thread 1.1 "vfork-follow-pa" hit Breakpoint 2, break_parent () at /home/vries/gdb_versions/devel/src/gdb/testsuite/gdb.base/vfork-follow-parent.c:23 23 } (gdb) FAIL: gdb.base/vfork-follow-parent.exp: resolution_method=schedule-multiple: continue to end of inferior 2 inferior 1 [Switching to inferior 1 [process 14961] (/home/vries/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.base/vfork-follow-parent/vfork-follow-parent)] [Switching to thread 1.1 (process 14961)] #0 break_parent () at /home/vries/gdb_versions/devel/src/gdb/testsuite/gdb.base/vfork-follow-parent.c:23 23 } (gdb) PASS: gdb.base/vfork-follow-parent.exp: resolution_method=schedule-multiple: inferior 1 continue Continuing. [Inferior 2 (process 14967) exited normally] (gdb) FAIL: gdb.base/vfork-follow-parent.exp: resolution_method=schedule-multiple: continue to break_parent (the program exited) Here, we continue both the vfork parent and child, since schedule-multiple is on. The child exits, which un-freezes the parent and makes an exit event available to GDB. We expect GDB to consume this exit event and present it to the user. Here, we see that GDB shows the parent hitting a breakpoint before showing the child exit. Because of the vfork, we know that chronologically, the child exiting must have happend before the parent hitting a breakpoint. However, scheduling being what it is, it is possible for the parent to un-freeze and exit quickly, such that when GDB pulls events out of the kernel, exit events for both processes are available. And then, GDB may chose at random to return the one for the parent first. This is what I imagine what causes the failure shown above. We could change the test to expect both possible outcomes, but I wanted to avoid complicating the .exp file that way. Instead, add a variable that the parent loops on that we set only after we confirmed the exit of the child. That should ensure that the order is always the same. Note that I wasn't able to reproduce the failure, so I can't tell if this fix really fixes the problem. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29021 Change-Id: Ibc8e527e0e00dac54b22021fe4d9d8ab0f3b28ad
2022-04-05gdb/testsuite: fix intermittent failures in gdb.mi/mi-cmd-user-context.expSimon Marchi2-5/+78
I got failures like this once on a CI: frame^M &"frame\n"^M ~"#0 child_sub_function () at /home/jenkins/workspace/binutils-gdb_master_build/arch/amd64/target_board/unix/src/binutils-gdb/gdb/testsuite/gdb.mi/user-selected-context-sync.c:33\n"^M ~"33\t dummy = !dummy; /* thread loop line */\n"^M ^done^M (gdb) ^M FAIL: gdb.mi/mi-cmd-user-context.exp: frame 1 (unexpected output) The problem is that the test expects the following regexp: ".*#0 0x.*" And that typically works, when the output of the frame command looks like: #0 0x00005555555551bb in child_sub_function () at ... Note the lack of hexadecimal address in the failing case. Whether or not the hexadecimal address is printed (roughly) depends on whether the current PC is at the beginning of a line. So depending on where thread 2 was when GDB stopped it (after thread 1 hit its breakpoint), we can get either output. Adjust the regexps to not expect an hexadecimal prefix (0x) but a function name instead (either child_sub_function or child_function). That one is always printed, and is also a good check that we are in the frame we expect. Note that for test "frame 5", we are showing a pthread frame (on my system), so the function name is internal to pthread, not something we can rely on. In that case, it's almost certain that we are not at the beginning of a line, or that we don't have debug info, so I think it's fine to expect the hex prefix. And for test "frame 6", it's ok to _not_ expect a hex prefix (what the test currently does), since we are showing thread 1, which has hit a breakpoint placed at the beginning of a line. When testing this, Tom de Vries pointed out that the current test code doesn't ensure that the child threads are in child_sub_function when they are stopped. If the scheduler chooses so, it is possible for the child threads to be still in the pthread_barrier_wait or child_function functions when they get stopped. So that would be another racy failure waiting to happen. The only way I can think of to ensure the child threads are in the child_sub_function function when they get stopped is to synchronize the threads using some variables instead of pthread_barrier_wait. So, replace the barrier with an array of flags (one per child thread). Each child thread flips its flag in child_sub_function to allow the main thread to make progress and eventually hit the breakpoint. I copied user-selected-context-sync.c to a new mi-cmd-user-context.c and made modifications to that, to avoid interfering with user-selected-context-sync.exp. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29025 Change-Id: I919673bbf9927158beb0e8b7e9e980b8d65eca90
2022-04-04gdb: resume ongoing step after handling fork or vforkSimon Marchi2-0/+208
The test introduced by this patch would fail in this configuration, with the native-gdbserver or native-extended-gdbserver boards: FAIL: gdb.threads/next-fork-other-thread.exp: fork_func=fork: target-non-stop=auto: non-stop=off: displaced-stepping=auto: i=2: next to for loop The problem is that the step operation is forgotten when handling the fork/vfork. With "debug infrun" and "debug remote", it looks like this (some lines omitted for brevity). We do the next: [infrun] proceed: enter [infrun] proceed: addr=0xffffffffffffffff, signal=GDB_SIGNAL_DEFAULT [infrun] resume_1: step=1, signal=GDB_SIGNAL_0, trap_expected=0, current thread [4154304.4154304.0] at 0x5555555553bf [infrun] do_target_resume: resume_ptid=4154304.0.0, step=1, sig=GDB_SIGNAL_0 [remote] Sending packet: $vCont;r5555555553bf,5555555553c4:p3f63c0.3f63c0;c:p3f63c0.-1#cd [infrun] proceed: exit We then handle a fork event: [infrun] fetch_inferior_event: enter [remote] wait: enter [remote] Packet received: T05fork:p3f63ee.3f63ee;06:0100000000000000;07:b08e59f6ff7f0000;10:bf60e8f7ff7f0000;thread:p3f63c0.3f63c6;core:17; [remote] wait: exit [infrun] print_target_wait_results: target_wait (-1.0.0 [process -1], status) = [infrun] print_target_wait_results: 4154304.4154310.0 [Thread 4154304.4154310], [infrun] print_target_wait_results: status->kind = FORKED, child_ptid = 4154350.4154350.0 [infrun] handle_inferior_event: status->kind = FORKED, child_ptid = 4154350.4154350.0 [remote] Sending packet: $D;3f63ee#4b [infrun] resume_1: step=0, signal=GDB_SIGNAL_0, trap_expected=0, current thread [4154304.4154310.0] at 0x7ffff7e860bf [infrun] do_target_resume: resume_ptid=4154304.0.0, step=0, sig=GDB_SIGNAL_0 [remote] Sending packet: $vCont;c:p3f63c0.-1#73 [infrun] fetch_inferior_event: exit In the first snippet, we resume the stepping thread with the range-stepping (r) vCont command. But after handling the fork (detaching the fork child), we resumed the whole process freely. The stepping thread, which was paused by GDBserver while reporting the fork event, was therefore resumed freely, instead of confined to the addresses of the stepped line. Note that since this is a "next", it could be that we have entered a function, installed a step-resume breakpoint, and it's ok to continue freely the stepping thread, but that's not the case here. The two snippets shown above were next to each other in the logs. For the fork case, we can resume stepping right after handling the event. However, for the vfork case, where we are waiting for the external child process to exec or exit, we only resume the thread that called vfork, and keep the others stopped (see patch "gdb: fix handling of vfork by multi-threaded program" prior in this series). So we can't resume the stepping thread right now. Instead, do it after handling the vfork-done event. Change-Id: I92539c970397ce880110e039fe92b87480f816bd
2022-04-04gdb: fix handling of vfork by multi-threaded program ↵Simon Marchi2-0/+184
(follow-fork-mode=parent, detach-on-fork=on) There is a problem with how GDB handles a vfork happening in a multi-threaded program. This problem was reported to me by somebody not using vfork directly, but using system(3) in a multi-threaded program, which may be implemented using vfork. This patch only deals about the follow-fork-mode=parent, detach-on-fork=on case, because it would be too much to chew at once to fix the bugs in the other cases as well (I tried). The problem ----------- When a program vforks, the parent thread is suspended by the kernel until the child process exits or execs. Specifically, in a multi-threaded program, only the thread that called vfork is suspended, other threads keep running freely. This is documented in the vfork(2) man page ("Caveats" section). Let's suppose GDB is handling a vfork and the user's desire is to detach from the child. Before detaching the child, GDB must remove the software breakpoints inserted in the shared parent/child address space, in case there's a breakpoint in the path the child is going to take before exec'ing or exit'ing (unlikely, but possible). Otherwise the child could hit a breakpoint instruction while running outside the control of GDB, which would make it crash. GDB must also avoid re-inserting breakpoints in the parent as long as it didn't receive the "vfork done" event (that is, when the child has exited or execed): since the address space is shared with the child, that would re-insert breakpoints in the child process also. So what GDB does is: 1. Receive "vfork" event for the parent 2. Remove breakpoints from the (shared) address space and set program_space::breakpoints_not_allowed to avoid re-inserting them 3. Detach from the child thread 4. Resume the parent 5. Wait for and receive "vfork done" event for the parent 6. Clean program_space::breakpoints_not_allowed and re-insert breakpoints 7. Resume the parent Resuming the parent at step 4 is necessary in order for the kernel to report the "vfork done" event. The kernel won't report a ptrace event for a thread that is ptrace-stopped. But the theory behind this is that between steps 4 and 5, the parent won't actually do any progress even though it is ptrace-resumed, because the kernel keeps it suspended, waiting for the child to exec or exit. So it doesn't matter for that thread if breakpoints are not inserted. The problem is when the program is multi-threaded. In step 4, GDB resumes all threads of the parent. The thread that did the vfork stays suspended by the kernel, so that's fine. But other threads are running freely while breakpoints are removed, which is a problem because they could miss a breakpoint that they should have hit. The problem is present with all-stop and non-stop targets. The only difference is that with an all-stop targets, the other threads are stopped by the target when it reports the vfork event and are resumed by the target when GDB resumes the parent. With a non-stop target, the other threads are simply never stopped. The fix ------- There many combinations of settings to consider (all-stop/non-stop, target-non-stop on/off, follow-fork-mode parent/child, detach-on-fork on/off, schedule-multiple on/off), but for this patch I restrict the scope to follow-fork-mode=parent, detach-on-fork=on. That's the "default" case, where we detach the child and keep debugging the parent. I tried to fix them all, but it's just too much to do at once. The code paths and behaviors for when we don't detach the child are completely different. The guiding principle for this patch is that all threads of the vforking inferior should be stopped as long as breakpoints are removed. This is similar to handling in-line step-overs, in a way. For non-stop targets (the default on Linux native), this is what happens: - In follow_fork, we call stop_all_threads to stop all threads of the inferior - In follow_fork_inferior, we record the vfork parent thread in inferior::thread_waiting_for_vfork_done - Back in handle_inferior_event, we call keep_going, which resumes only the event thread (this is already the case, with a non-stop target). This is the thread that will be waiting for vfork-done. - When we get the vfork-done event, we go in the (new) handle_vfork_done function to restart the previously stopped threads. In the same scenario, but with an all-stop target: - In follow_fork, no need to stop all threads of the inferior, the target has stopped all threads of all its inferiors before returning the event. - In follow_fork_inferior, we record the vfork parent thread in inferior::thread_waiting_for_vfork_done. - Back in handle_inferior_event, we also call keep_going. However, we only want to resume the event thread here, not all inferior threads. In internal_resume_ptid (called by resume_1), we therefore now check whether one of the inferiors we are about to resume has thread_waiting_for_vfork_done set. If so, we only resume that thread. Note that when resuming multiple inferiors, one vforking and one not non-vforking, we could resume the vforking thread from the vforking inferior plus all threads from the non-vforking inferior. However, this is not implemented, it would require more work. - When we get the vfork-done event, the existing call to keep_going naturally resumes all threads. Testing-wise, add a test that tries to make the main thread hit a breakpoint while a secondary thread calls vfork. Without the fix, the main thread keeps going while breakpoints are removed, resulting in a missed breakpoint and the program exiting. Change-Id: I20eb78e17ca91f93c19c2b89a7e12c382ee814a1
2022-04-04gdb/testsuite: fix timeout in server-pipe.exp testAndrew Burgess1-3/+7
I noticed that the gdb.server/server-pipe.exp test would sometimes timeout when my machine was more heavily loaded. Turns out the test is reading all the shared libraries over GDB's remote protocol, which can be slow. We avoid this in other tests by setting the sysroot in GDBFLAGS, something which is missing from the gdb.server/server-pipe.exp test. Fix the timeouts by setting sysroot in GDBFLAGS, after this the shared libraries are no longer copied over the remote protocol, and I no longer see the test timeout.
2022-04-04gdb: Add maint set ignore-prologue-end-flagLancelot SIX1-0/+14
The previous patch added support for the DWARF prologue-end flag in line table. This flag can be used by DWARF producers to indicate where to place breakpoints past a function prologue. However, this takes precedence over prologue analyzers. So if we have to debug a program with erroneous debug information, the overall debugging experience will be degraded. This commit proposes to add a maintenance command to instruct GDB to ignore the prologue_end flag. Tested on x86_64-gnu-linux. Change-Id: Idda6d1b96ba887f4af555b43d9923261b9cc6f82
2022-04-04gdb: Add support for DW_LNS_set_prologue_end in line-tableLancelot SIX5-9/+132
Add support for DW_LNS_set_prologue_end when building line-tables. This attribute can be set by the compiler to indicate that an instruction is an adequate place to set a breakpoint just after the prologue of a function. The compiler might set multiple prologue_end, but considering how current skip_prologue_using_sal works, this commit modifies it to accept the first instruction with this marker (if any) to be the place where a breakpoint should be placed to be at the end of the prologue. The need for this support came from a problematic usecase generated by hipcc (i.e. clang). The problem is as follows: There's a function (lets call it foo) which covers PC from 0xa800 to 0xa950. The body of foo begins with a call to an inlined function, covering from 0xa800 to 0xa94c. The issue is that when placing a breakpoint at 'foo', GDB inserts the breakpoint at 0xa818. The 0x18 offset is what GDB thinks is foo's first address past the prologue. Later, when hitting the breakpoint, GDB reports the stop within the inlined function because the PC falls in its range while the user expects to stop in FOO. Looking at the line-table for this location, we have: INDEX LINE ADDRESS IS-STMT [...] 14 293 0x000000000000a66c Y 15 END 0x000000000000a6e0 Y 16 287 0x000000000000a800 Y 17 END 0x000000000000a818 Y 18 287 0x000000000000a824 Y [...] For comparison, let's look at llvm-dwarfdump's output for this CU: Address Line Column File ISA Discriminator Flags ------------------ ------ ------ ------ --- ------------- ------------- [...] 0x000000000000a66c 293 12 2 0 0 is_stmt 0x000000000000a6e0 96 43 82 0 0 is_stmt 0x000000000000a6f8 102 18 82 0 0 is_stmt 0x000000000000a70c 102 24 82 0 0 0x000000000000a710 102 18 82 0 0 0x000000000000a72c 101 16 82 0 0 is_stmt 0x000000000000a73c 2915 50 83 0 0 is_stmt 0x000000000000a74c 110 1 1 0 0 is_stmt 0x000000000000a750 110 1 1 0 0 is_stmt end_sequence 0x000000000000a800 107 0 1 0 0 is_stmt 0x000000000000a800 287 12 2 0 0 is_stmt prologue_end 0x000000000000a818 114 59 81 0 0 is_stmt 0x000000000000a824 287 12 2 0 0 is_stmt 0x000000000000a828 100 58 82 0 0 is_stmt [...] The main difference we are interested in here is that llvm-dwarfdump's output tells us that 0xa800 is an adequate place to place a breakpoint past a function prologue. Since we know that foo covers from 0xa800 to 0xa94c, 0xa800 is the address at which the breakpoint should be placed if the user wants to break in foo. This commit proposes to add support for the prologue_end flag in the line-program processing. The processing of this prologue_end flag is made in skip_prologue_sal, before it calls gdbarch_skip_prologue_noexcept. The intent is that if the compiler gave information on where the prologue ends, we should use this information and not try to rely on architecture dependent logic to guess it. The testsuite have been executed using this patch on GNU/Linux x86_64. Testcases have been compiled with both gcc/g++ (verison 9.4.0) and clang/clang++ (version 10.0.0) since at the time of writing GCC does not set the prologue_end marker. Tests done with GCC 11.2.0 (not over the entire testsuite) show that it does not emit this flag either. No regression have been observed with GCC or Clang. Note that when using Clang, this patch fixes a failure in gdb.opt/inline-small-func.exp. Change-Id: I720449a8a9b2e1fb45b54c6095d3b1e9da9152f8
2022-04-04Add context-sensitive field name completion to Ada parserTom Tromey1-0/+31
This updates the Ada expression parser to implement context-sensitive field name completion. This is PR ada/28727. This is somewhat complicated due to some choices in the Ada lexer -- it chooses to represent a sequence of "."-separated identifiers as a single token, so the parser must partially recreate the completer's logic to find the completion word boundaries. Despite the minor warts in this patch, though, it is a decent improvement. It's possible that the DWARF reader rewrite will help fix the package completion problem pointed out in this patch as well. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28727
2022-04-04Implement completion for Ada attributesTom Tromey1-0/+5
This adds a completer for Ada attributes. Some work in the lexer is required in order to match end-of-input correctly, as flex does not have a general-purpose way of doing this. (The approach taken here is recommended in the flex manual.)
2022-04-04Fix bug in Ada attributes lexingTom Tromey1-7/+9
The Ada lexer allows whitespace between the apostrophe and the attribute text, but processAttribute does not handle this. This patch fixes the problem and introduces a regression test.
2022-04-04Handle ghost entities in symbol lookupTom Tromey4-0/+96
Normally, SPARK ghost entities are removed from the executable. However, with -gnata, they will be preserved. In this situation, it's handy to be able to inspect them. This patch allows this by removing the "___ghost_" prefix in the appropriate places.
2022-04-04[gdb/testsuite] Fix KPASS in gdb.ada/arrayptr.expTom de Vries1-16/+45
On openSUSE Leap 15.3 I run into: ... KPASS: gdb.ada/arrayptr.exp: scenario=minimal: print pa_ptr.all \ (PRMS minimal encodings) KPASS: gdb.ada/arrayptr.exp: scenario=minimal: print pa_ptr(3) \ (PRMS minimal encodings) KPASS: gdb.ada/arrayptr.exp: scenario=minimal: print pa_ptr.all(3) \ (PRMS minimal encodings) ... The test-case KFAILs some tests. However, the analysis in the corresponding PR talks of a compiler problem, so it should use XFAILs instead. The KFAILs are setup for pre-gcc-12, but apparantly the fix has been backported to system compiler 7.5.0, hence the KPASS. Fix this by: - using an XFAIL instead of a KFAIL - matching the specific gdb output that corresponds to the XFAILs (reproduced on Fedora 34). Tested on x86_64-linux, specifically openSUSE Leap 15.3 and Fedora 34.
2022-04-03gdb: add support for Fortran's ASSUMED RANK arraysrupothar2-0/+127
This patch adds a new dynamic property DYN_PROP_RANK, this property is read from the DW_AT_rank attribute and stored within the type just like other dynamic properties. As arrays with dynamic ranks make use of a single DW_TAG_generic_subrange to represent all ranks of the array, support for this tag has been added to dwarf2/read.c. The final piece of this puzzle is to add support in gdbtypes.c so that we can resolve an array type with dynamic rank. To do this the existing resolve_dynamic_array_or_string function is split into two, there's a new resolve_dynamic_array_or_string_1 core that is responsible for resolving each rank of the array, while the now outer resolve_dynamic_array_or_string is responsible for figuring out the array rank (which might require resolving a dynamic property) and then calling the inner core. The resolve_dynamic_range function now takes a rank, which is passed on to the dwarf expression evaluator. This rank will only be used in the case where the array itself has dynamic rank, but we now pass the rank in all cases, this should be harmless if the rank is not needed. The only small nit is that resolve_dynamic_type_internal actually handles resolving dynamic ranges itself, which now obviously requires us to pass a rank value. But what rank value to use? In the end I just passed '1' through here as a sane default, my thinking is that if we are in resolve_dynamic_type_internal to resolve a range, then the range isn't part of an array with dynamic rank, and so the range should actually be using the rank value at all. An alternative approach would be to make the rank value a gdb::optional, however, this ends up adding a bunch of complexity to the code (e.g. having to conditionally build the array to pass to dwarf2_evaluate_property, and handling the 'rank - 1' in resolve_dynamic_array_or_string_1) so I haven't done that, but could, if people think that would be a better approach. Finally, support for assumed rank arrays was only fixed very recently in gcc, so you'll need the latest gcc in order to run the tests for this. Here's an example test program: PROGRAM arank REAL :: a1(10) CALL sub1(a1) CONTAINS SUBROUTINE sub1(a) REAL :: a(..) PRINT *, RANK(a) END SUBROUTINE sub1 END PROGRAM arank Compiler Version: gcc (GCC) 12.0.0 20211122 (experimental) Compilation command: gfortran assumedrank.f90 -gdwarf-5 -o assumedrank Without Patch: gdb -q assumedrank Reading symbols from assumedrank... (gdb) break sub1 Breakpoint 1 at 0x4006ff: file assumedrank.f90, line 10. (gdb) run Starting program: /home/rupesh/STAGING-BUILD-2787/bin/assumedrank Breakpoint 1, arank::sub1 (a=<unknown type in /home/rupesh/STAGING-BUILD-2787 /bin/assumedrank, CU 0x0, DIE 0xd5>) at assumedrank.f90:10 10 PRINT *, RANK(a) (gdb) print RANK(a) 'a' has unknown type; cast it to its declared type With patch: gdb -q assumedrank Reading symbols from assumedrank... (gdb) break sub1 Breakpoint 1 at 0x4006ff: file assumedrank.f90, line 10. (gdb) run Starting program: /home/rupesh/STAGING-BUILD-2787/bin/assumedrank Breakpoint 1, arank::sub1 (a=...) at assumedrank.f90:10 10 PRINT *, RANK(a) (gdb) print RANK(a) $1 = 1 (gdb) ptype a type = real(kind=4) (10) (gdb) Co-Authored-By: Andrew Burgess <aburgess@redhat.com>
2022-04-03gdb/testsuite: resolve some duplicate test names in gdb.baseAndrew Burgess1-4/+6
This commit resolves all the duplicate test names that I see in the script: gdb.base/attach-pie-misread.exp The duplicate names all come from a second call to build_executable_own_libs, so in this commit I've places the second call inside a with_test_prefix block. While I was making this change I've also modified the value being passed as the testname for the second build_executable_own_libs call. Previously we used ${test}, however, I think this was likely a mistake, the 'test' variable is setup for the previous test. I suspect that ${testfile} is a better choice - especially now we have a testname prefix. As the testname is only used (after various calls) from within build_executable_from_specs should the build fail, I don't think this change really makes much difference though. There should be no change in what is tested after this commit.
2022-04-03gdb/testsuite: resolve a duplicate test name in a gdb.mi testAndrew Burgess1-1/+1
Solve two duplicate test names in the test script: gdb.mi/mi-catch-cpp-exceptions.exp by moving the call to restart_for_test inside the with_test_prefix block. There should be no difference in what is tested after this commit.
2022-04-03gdb/tui: fair split of delta after a resizeAndrew Burgess1-0/+31
Currently, in master gdb, when a tui window is changed in size, the screen delta is mostly just added to the next available window. We do take care to respect the min/max size, but in most cases, these limits are just "the terminal size", and so, we end up placing the whole delta on the next window. Consider these steps in an 80 column, 24 line terminal: (gdb) tui enable (gdb) layout src (gdb) layout split (gdb) info win Name Lines Columns Focus src 8 80 (has focus) asm 8 80 status 1 80 cmd 8 80 (gdb) winheight cmd +2 (gdb) info win Name Lines Columns Focus src 6 80 (has focus) asm 8 80 status 1 80 cmd 10 80 Notice that initially, the windows were balanced, 8 lines each for the major windows. Then, when the cmd window was adjusted, the extra two lines were given to the asm window. I think it would be nicer if the delta was spread more evenly over the available windows. In the example above, after the adjustment the layout now looks like: (gdb) info win Name Lines Columns Focus src 7 80 (has focus) asm 7 80 status 1 80 cmd 10 80 This is achieved within tui_layout_split::set_size, by just handing out the delta in increments of 1 to each window (except for the window the user adjusted), until there's no more delta left. Of course, we continue to respect the min/max window sizes.
2022-04-03gdb/tui: relax restrictions on window max height and widthAndrew Burgess1-1/+3
This commit removes some arbitrary adjustments made in tui_cmd_window::max_height, tui_win_info::max_height, and tui_win_info::max_width. These member functions all subtract some constant from the theoretical maximum height or width. I've looked back through the history a little and can see no real reason why these adjustments should be needed, with these adjustments removed all the existing tui tests still pass. However, retaining these restrictions causes some bugs, consider: (gdb) tui new-layout hsrc {-horizontal src 1 cmd 1} 1 When this layout is selected with current master, gdb will leave a 4 line gap at the bottom of the terminal. The problem is that the maximum height is restricted, for the cmd window, to 4 less than the terminal height. By removing this restriction gdb is able to size the windows to the complete terminal height, and the layout is done correctly. This 4 line restriction is also what prevents this layout from working correctly: (gdb) tui new-layout conly cmd 1 Previously, this layout would present a cmd window only, but there would be a 4 line gap at the bottom of the terminal. This issue was mentioned in an earlier commit in this series (when a different bug was fixed), but with this commit, the above layout now correctly fills the terminal. The associated test is updated. After removing the adjustment in tui_cmd_window::max_height, the implementation is now the same as the implementation in the parent class tui_win_info, so I've completely removed the max_height call from tui_cmd_window.
2022-04-03gdb/testsuite: some additional tests in gdb.tui/scroll.expAndrew Burgess1-0/+4
This commit just adds an extra check of the src window size prior to sending all the commands to gdb. We also set the cmd window height to its existing height, this (obviously) shouldn't change the window layout, which we check. My main motivation was adding the initial window layout check, the winheight and recheck are just extras. All of these test pass both before and after this commit.
2022-04-03gdb/tui: support placing the cmd window into a horizontal layoutAndrew Burgess1-0/+5
This commit allows the user to place the cmd window within horizontal tui layouts. Consider this set of steps, carried out in an 80 columns by 24 lines terminal, using current master gdb: (gdb) tui new-layout hsrc { -horizontal src 1 cmd 1 } 1 status 1 (gdb) tui layout hsrc What you end up with is a full width cmd window with the status bar beneath. Where's the src window gone? We then try: (gdb) info win Name Lines Columns Focus src 23 3 (has focus) cmd 23 80 status 1 80 (gdb) Something weird has gone on, gdb has overlapped the cmd window with the src window. If we trigger the src window to redraw is content, for example, 'list main', then we see corruption in the cmd window as the src window overwrites it. So, what's going on? The problem is some code in tui_layout_split::apply, in tui-layout.c. Within 'Step 1', there is a loop that calculates the min/max window sizes for all windows within a tui_layout_split. However, there's a special case for the cmd window. This special case is trying to have the cmd window retain its current size when a layout is re-applied, or a new layout is applied. This makes sense, consider moving from the 'src' layout to the 'asm' layout, this looks something like this (status window removed): .-------. .-------. | src | | asm | |-------| ====> |-------| | cmd | | cmd | '-------' '-------' If the user has gone to the effort of adjusting the cmd window size, then, the thinking goes, we shouldn't reset the cmd window size when switching layouts like this. The problem though, is that when we do a switch more like this: .-----------. .-----------. | src | | | | |-----------| ====> | asm | cmd | | cmd | | | | '-----------' '-----------' Now retaining the cmd window width makes no sense; the new layout has a completely different placement for the cmd window, instead of sizing by height, we're now sizing by width. The existing code doesn't understand this though, and tried to retain the full width for the cmd window. To solve this problem, I propose we introduce the idea of a layout "fingerprint". The fingerprint tries to capture, in an abstract way, where the cmd window lives within the layout. Only when two layouts have the same fingerprint will we attempt to retain the cmd window size. The fingerprint for a layout is represented as a string, the string is a series of 'V' or 'H' characters, ending with a single 'C' character. The series of 'V' and 'H' characters represent the vertical or horizontal layouts that must be passed through to find the cmd window. Here are a few examples: # This layout is equivalent to the builtin 'src' layout. # Fingerprint: VC tui new-layout example1 src 2 status 0 cmd 1 # This layout is equivalent to the builtin 'split' layout. # Fingerprint: VC tui new-layout example2 src 1 asm 1 status 0 cmd 1 # This is the same layout that was given at the top. # Fingerprint: VHC tui new-layout hsrc { -horizontal src 1 cmd 1 } 1 status 1 And so, when switching between example1 and example2, gdb knows that the cmd window is, basically, in the same sort of position within the layout, and will retain the cmd window size. In contrast, when switching to the hsrc layout, gdb understands that the position of the cmd window is different, and does not try to retain the cmd window size.
2022-04-03gdb/tui: allow cmd window to change size in tui_layout_split::applyAndrew Burgess2-0/+55
When we switch layouts we call the tui_layout_split::apply member function to reapply the layout, and recalculate all the window sizes. One special case is the cmd window, which we try to keep at its existing size. However, in some cases it is not appropriate to keep the cmd window at its existing size. I will describe two such cases here, in one, we want the cmd window to reduce in size, and in the other, we want the cmd window to grow in size. Try these steps in a 80 columns, by 24 lines terminal: (gdb) tui enable (gdb) layout src (gdb) winheight cmd 20 (gdb) layout split You should see that the status window is missing from the new layout, and that the cmd window has been placed over the border of the asm window. The 'info win' output is: (gdb) info win Name Lines Columns Focus src 3 80 (has focus) asm 3 80 status 1 80 cmd 20 80 Notice that gdb has assigned 27 lines of screen space, even with the border overlap between the src and asm windows, this is still 2 lines too many. The problem here is that after switching layouts, gdb has forced the cmd window to retain its 20 line height. Really, we want the cmd window to reduce in height so that the src and asm windows can occupy their minimum required space. This commit allows this (details on how are below). After this commit, in the above situation, we now see the status window displayed correctly, and the 'info win' output is: (gdb) info win Name Lines Columns Focus src 3 80 (has focus) asm 3 80 status 1 80 cmd 18 80 The cmd window has been reduced in size by 2 lines so that everything can fit on the screen. The second example is one which was discussed in a recent commit, consider this case (still in the 80 column, 24 line terminal): (gdb) tui enable (gdb) tui new-layout conly cmd 1 (gdb) layout conly (gdb) info win Name Lines Columns Focus cmd 8 80 (has focus) (gdb) This layout only contains a cmd window, which we would expect to occupy the entire terminal. But instead, the cmd window only occupies the first 8 lines, and the rest of the terminal is unused! The reason is, again, that the cmd window is keeping its previous size (8 lines). After this commit things are slightly different, the 'info win' output is now: (gdb) info win Name Lines Columns Focus cmd 20 80 (has focus) Which is a little better, but why only 20 lines? Turns out there's yet another bug hitting this case. That bug will be addressed in a later commit, so, for now, we're accepting the 20 lines. What this commit does is modify the phase of tui_layout_split::apply that handles any left over space. Usually, in "Step 2", each sub-layout has a size calculated. As the size is an integer, then, when all sizes are calculated we may have some space left over. This extra space is then distributed between all the windows fairly until all the space is used up. When we consider windows minimum size, or fixed size windows, then it is possible that we might try to use more space than is available, this was our first example above. The same code that added extra space to the windows, can also be used to reclaim space (in the over allocation case) to allow all windows to fit. The problem then is the cmd window, which we often force to a fixed size. Inside the loop that handles the allocation of excess space, if we find that we have tried every window, and still have space either left to give, or we need to claim back more space, then, if the cmd window was changed to a fixed size, we can change the cmd window back to a non-fixed-size window, and proceed to either give, or take space from the cmd window as needed.
2022-04-03gdb/tui: fairer distribution of excess space during applyAndrew Burgess4-17/+22
When applying layouts gdb computes the size of each window (or rather, each sub-layout within a layout) using integer arithmetic. As this rounds down the results, then, when all sub-layouts are sized, there is the possibility that we have some space left over. Currently, this space is just assigned to an arbitrary sub-layout. This can result in some unbalanced results. Consider this set of steps with current master: (gdb) tui enable (gdb) layout regs (gdb) info win Name Lines Columns Focus regs 7 80 src 9 80 (has focus) status 1 80 cmd 8 80 Notice the weird split between the src and regs windows, the original layout specification has these windows given equal weight. The problem is that, with rounding, both the regs and src windows are initially sized to 7, the extra 2 lines are then arbitrarily added to the src window. In this commit, rather than add all the extra space to one single window, I instead hand out the extra space 1 line at a time, looping over all the sub-layouts. We take care to respect the min/max sizes, and so, we now get this result: (gdb) tui enable (gdb) layout regs (gdb) info win Name Lines Columns Focus regs 8 80 src 8 80 (has focus) status 1 80 cmd 8 80 This looks more natural to me. This is obviously a change in behaviour, and so, lots of the existing tests need to be updated to take this into account. None of the changes are huge, it's just a line or two (or column for width) moved between windows.
2022-04-03gdb/tui: avoid fp exception when applying layoutsAndrew Burgess1-1/+2
Consider: (gdb) tui enable (gdb) layout src (gdb) tui new-layout conly cmd 1 (gdb) layout conly After this, with current master, gdb crashes with a floating-point exception. The problem is that in tui_layout_split::apply, when we switch from 'src' to 'conly', we will try to retain the cmd window height. As such, the cmd window will become a fixed size window, which decreases the available_size, but doesn't count towards the total_weight. As the cmd window is the only window, the total_weight stays at zero, and, when we move into step 2, where we attempt to size the windows, we perform a divide by zero, and crash. After this commit we avoid the divide by zero, and just directly set the window size based on the fixed size. There is still a problem after this commit, when the conly layout is selected the cmd window retains its original height, which will only be part of the terminal. The rest of the terminal is left unused. This issue will be addressed in a later commit, this commit is just about the floating-point exception.
2022-04-03gdb/tui/testsuite: refactor new-layout.exp testAndrew Burgess1-27/+56
This commit changes the gdb.tui/new-layout.exp test to make use of a list of test descriptions, and a loop to check each description in turn. There's no change to what is actually tested after this commit. In future commits I plan to add additional tests to this file, and this will be easier now that all I have to do is add a new test description to the list.
2022-04-03gdb/tui: add new 'tui window width' command and 'winwidth' aliasAndrew Burgess1-0/+62
This commit adds a new command 'tui window width', and an alias 'winwidth'. This command is equivalent to the old 'winheight' command (which was recently renamed 'tui window height'). Even though I recently moved the old tui commands under the tui namespace, and I would strongly encourage all new tui commands to be added as 'tui ....' only (users can create their own top-level aliases if they want), I'm breaking that suggestion here, and adding a 'winwidth' alias. Given that we already have 'winheight' and have done for years, it just didn't seem right to no have the matching 'winwidth'. You might notice in the test that the window resizing doesn't quite work right. I setup a horizontal layout, then grow and shrink the windows. At the end of the test the windows should be back to their original size... ... they are not. This isn't my fault, honest! GDB's window resizing is a little ... temperamental, and is prone to getting things slightly wrong during resizes, off by 1 type things. This is true for height resizing, as well as the new width resizing. Later patches in this series will rework the resizing algorithm, which should improve things in this area. For now, I'm happy that the width resizing is as good as the height resizing, given the existing quirks. For the docs side I include a paragraph that explains how multiple windows are required before the width can be adjusted. For completeness, I've added the same paragraph to the winheight description. With the predefined layouts this extra paragraph is not really needed for winheight, as there are always multiple windows on the screen. However, with custom layouts, this might not be true, so adding the paragraph seems like a good idea. As for the changes in gdb itself, I've mostly just taken the existing height adjustment code, changed the name to make it generic 'size' adjustment, and added a boolean flag to indicate if we are adjusting the width or the height.
2022-04-01gdb/testing/tui: add new _csi_{L,S,T}Andrew Burgess2-0/+180
This patch was original part of this series: https://sourceware.org/pipermail/gdb-patches/2022-March/186429.html https://sourceware.org/pipermail/gdb-patches/2022-March/186433.html I've pulled this out as it might be useful ahead of the bigger series being merged. This commit adds: _csi_L - insert line _csi_S - pan down _csi_T - pan up
2022-03-31Style URLs in GDB outputTom Tromey1-2/+3
I noticed that GDB will display URLs in a few spots. This changes them to be styled. Originally I thought I'd introduce a new "url" style, but there aren't many places to use this, so I just reused filename styling instead. This patch also changes the debuginfod URL list to be printed one URL per line. I think this is probably a bit easier to read.