aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite
AgeCommit message (Collapse)AuthorFilesLines
7 days[gdb/testsuite] Fix gdb.base/enum_cond.exp on arm-linuxTom de Vries3-1/+42
On arm-linux, I run into: ... gdb compile failed, ld: warning: enum_cond.o uses variable-size enums yet \ the output is to use 32-bit enums; use of enum values across objects may fail UNTESTED: gdb.base/enum_cond.exp: failed to compile ... Fix this by using -nostdlib. Tested on arm-linux and x86_64-linux. Approved-By: Simon Marchi <simon.marchi@efficios.com>
7 daysgdb: remove the !startup_with_shell path from construct_inferior_argumentsAndrew Burgess3-46/+50
In the commit: commit 0df62bf09ecf242e3a932255d24ee54407b3c593 Date: Fri Oct 22 07:19:33 2021 +0000 gdb: Support some escaping of args with startup-with-shell being off nat/fork-inferior.c was updated such that when we are starting an inferior without a shell we now remove escape characters. The benefits of this are explained in that commit, but having made this change we can now make an additional change. Currently, in construct_inferior_arguments, when startup_with_shell is false we construct the inferior argument string differently than when startup_with_shell is true; when true we apply some escaping to special shell character, when false we don't. This commit simplifies construct_inferior_arguments by removing the !startup_with_shell case, and instead we now apply escaping in all cases. This is fine because, thanks to the above commit the escaping will be correctly removed again when we call into nat/fork-inferior.c. We should think of construct_inferior_arguments and nat/fork-inferior.c as needing to cooperate in order for argument handling to work correctly. construct_inferior_arguments converts a list of separate arguments into a single string, and nat/fork-inferior.c splits that single string back into a list of arguments. It is critical that, if nat/fork-inferior.c is expecting to remove a "layer" of escapes, then construct_inferior_arguments must add that expected "layer", otherwise, we end up stripping more escapes than expected. The great thing (I think) about the new configuration, is that GDB no longer cares about startup_with_shell at the point the arguments are being setup. We only care about startup_with_shell at the point that the inferior is started. This means that a user can set the inferior arguments, and then change the startup-with-shell setting, and GDB will do what they expect. Under the previous system, where construct_inferior_arguments changed its behaviour based on startup_with_shell, the user had to change the setting, and then set the arguments, otherwise, GDB might not do what they expect. There is one slight issue with this commit though, which will be addressed by the next commit. For GDB's native targets construct_inferior_arguments is reached via two code paths; first when GDB starts and we combine arguments from the command line, and second when the Python API is used to set the arguments from a sequence. It's the command line argument handling which we are interested in. Consider this: $ gdb --args /tmp/exec '$FOO' (gdb) show args Argument list to give program being debugged when it is started is "\$FOO". Notice that the argument has become \$FOO, the '$' is now quoted. This is because, by quoting the argument in the shell command that started GDB, GDB was passed a literal $FOO with no quotes. In order to ensure that the inferior sees this same value, GDB added the extra escape character. When GDB starts with a shell we pass \$FOO, which results in the inferior seeing a literal $FOO. But what if the user _actually_ wanted to have the shell GDB uses to start the inferior expand $FOO? Well, it appears this can't be done from the command line, but from the GDB prompt we can just do: (gdb) set args $FOO (gdb) show args Argument list to give program being debugged when it is started is "$FOO". And now the inferior will see the shell expanded version of $FOO. It might seem like we cannot achieve the same result from the GDB command line, however, it is possible with this trick: $ gdb -eiex 'set startup-with-shell off' --args /tmp/exec '$FOO' (gdb) show args Argument list to give program being debugged when it is started is "$FOO". (gdb) show startup-with-shell Use of shell to start subprocesses is off. And now the $FOO is not escaped, but GDB is no longer using a shell to start the inferior, however, we can extend our command line like this: $ gdb -eiex 'set startup-with-shell off' \ -ex 'set startup-with-shell on' \ --args /tmp/exec '$FOO' (gdb) show args Argument list to give program being debugged when it is started is "$FOO". (gdb) show startup-with-shell Use of shell to start subprocesses is on. Use an early-initialisation option to disable startup-with-shell, this is done before command line argument processing, then a normal initialisation option turns startup-with-shell back on after GDB has processed the command line arguments! Is this useful? Yes, absolutely. Is this a good user experience? Absolutely not. And I plan to add a new command line option to GDB (and gdbserver) that will allow users to achieve the same result (this trick doesn't work in gdbserver as there's no early-initialisation there) without having to toggle the startup-with-shell option. The new option can be found in the series here: https://inbox.sourceware.org/gdb-patches/cover.1730731085.git.aburgess@redhat.com The problem is that, that series is pretty long, and getting it reviewed is just not possible. So instead I'm posting the individual patches in smaller blocks, to make reviews easier. So, what's the problem? Well, by removing the !startup_with_shell code path from GDB, there is no longer a construct_inferior_arguments code path that doesn't quote inferior arguments, and so there's no longer a way, from the command line, to set an unquoted '$FOO' as an inferior argument. Obviously, this can still be done from GDB's CLI prompt. The trick above is completely untested, so this regression isn't going to show up in the testsuite. And the breakage is only temporary. In the next commit I'll add a fix which restores the above trick. Of course, I hope that this fix will itself, only be temporary. Once the new command line options that I mentioned above are added, then the fix I add in the next commit can be removed, and user should start using the new command line option. After this commit a whole set of tests that were added as xfail in the above commit are now passing. A change similar to this one can be found in this series: https://inbox.sourceware.org/gdb-patches/20211022071933.3478427-1-m.weghorn@posteo.de/ which I reviewed before writing this patch. I don't think there's any one patch in that series that exactly corresponds with this patch though, so I've listed the author of the original series as co-author on this patch. Co-Authored-By: Michael Weghorn <m.weghorn@posteo.de> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28392 Tested-By: Guinevere Larsen <guinevere@redhat.com>
7 daysPreserve a local variable in a gdb testTom Tromey3-0/+28
I found another Ada test where LLVM optimizes away an unused local variable. This patch fixes this problem -- but note the test now fails for a different (currently expected) reason.
10 daysgdb/python: handle non-utf-8 character from gdb.execute()Andrew Burgess1-14/+55
I noticed that it was not possible to return a string containing non utf-8 characters using gdb.execute(). For example, using the binary from the gdb.python/py-source-styling.exp test: (gdb) file ./gdb/testsuite/outputs/gdb.python/py-source-styling/py-source-styling Reading symbols from ./gdb/testsuite/outputs/gdb.python/py-source-styling/py-source-styling... (gdb) set style enabled off (gdb) list 26 21 int some_variable = 1234; 22 23 /* The following line contains a character that is non-utf-8. This is a 24 critical part of the test as Python 3 can't convert this into a string 25 using its default mechanism. */ 26 char c[] = "�"; /* List this line. */ 27 28 return 0; 29 } (gdb) python print(gdb.execute('list 26', to_string=True)) Python Exception <class 'UnicodeDecodeError'>: 'utf-8' codec can't decode byte 0xc0 in position 250: invalid start byte Error occurred in Python: 'utf-8' codec can't decode byte 0xc0 in position 250: invalid start byte It is necessary to disable styling before the initial 'list 26', otherwise the source will be passed through GNU source highlight, and GNU source highlight seems to be smart enough to figure out the character encoding, and convert it to UTF-8. This conversion is then cached in the source cache, and the later Python gdb.execute call will get back a pure UTF-8 string. If source styling is disabled, then GDB caches the string without the conversion to UTF-8, now the gdb.execute call gets back the string with a non-UTF-8 character within it, and Python throws an error during its attempt to create a string object. I'm not, at this point, proposing a solution that tries to guess the source file encoding, though I guess such a thing could be done. Instead, I think we should make use of the host_charset(), as set by the user with 'set host-charset ....' during the creation of the Python string. To do this, in execute_gdb_command, we should switch from PyUnicode_FromString, which requires the input be a UTF-8 string, to using PyUnicode_Decode, which allows GDB to specify the string encoding. We will use host_charset(). With this done, it is now possible to list the file contents using gdb.execute(), with the contents passing through a string: (gdb) set host-charset ISO-8859-1 (gdb) python print(gdb.execute('list 26', to_string=True), end='') 21 int some_variable = 1234; 22 23 /* The following line contains a character that is non-utf-8. This is a 24 critical part of the test as Python 3 can't convert this into a string 25 using its default mechanism. */ 26 char c[] = "À"; /* List this line. */ 27 28 return 0; 29 } (gdb) There are already plenty of other places in GDB's Python code where we use PyUnicode_Decode to create a string from something that might contain user generated content, so I believe this is the correct approach.
12 daysgdb/testsuite: fix undefined variable in gdb.ada/scalar_storage.expAndrew Burgess1-1/+1
Commit: commit be382ece165eefa3e65f61bfb6b2aa2ee95dd6b4 Date: Wed Feb 12 09:35:26 2025 -0700 Check for compiler support in scalar_storage.exp Introduced an undefined variable use in gdb.ada/scalar_storage.exp, fixed by this commit.
12 daysgdb/testsuite: fail less catastrophically in gdb.base/style.expSimon Marchi1-3/+15
On Debian 12, with gcc 12 and ld 2.40, I get some failures when running: $ make check TESTS="gdb.base/style.exp" RUNTESTFLAGS="--target_board=fission" I think I stumble on this bug [1], preventing to do the disassembling that the test needs: $ ./gdb -nx -q --data-directory=data-directory testsuite/outputs/gdb.base/style/style Reading symbols from testsuite/outputs/gdb.base/style/style... (gdb) x/1i *main DW_FORM_strp pointing outside of .debug_str section [in module /home/smarchi/build/binutils-gdb/gdb/testsuite/outputs/gdb.base/style/style] (gdb) The regexp in get_single_disassembled_insn fails to match, the insn variable doesn't get set, and we get one of those unreadable TCL stack traces: ERROR: tcl error sourcing /home/smarchi/src/binutils-gdb/gdb/testsuite/gdb.base/style.exp. ERROR: tcl error code TCL READ VARNAME ERROR: can't read "insn": no such variable while executing "return $insn" (procedure "get_single_disassembled_insn" line 4) invoked from within "get_single_disassembled_insn" ("uplevel" body line 18) invoked from within "uplevel 1 $body" invoked from within ... Check the return value of the regexp call, return an empty string on failure. Log a failure, so that we have a trace that something went wrong, in case the tests done by the caller happen to pass by change. [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111409 Change-Id: I5123d4cc0034da85a093a8531a22e972c10d94ca Approved-By: Tom Tromey <tom@tromey.com>
14 days[gdb/testsuite] Fix gdb.base/step-over-syscall.exp with glibc 2.41Tom de Vries1-7/+17
On openSUSE Tumbleweed, with glibc 2.41, when running test-case gdb.base/step-over-syscall.exp I run into: ... (gdb) stepi^M 0x00007ffff7cfd09b in __abort_lock_rdlock () from /lib64/libc.so.6^M 1: x/i $pc^M => 0x7ffff7cfd09b <__abort_lock_rdlock+29>: syscall^M (gdb) p $eax^M $1 = 14^M (gdb) FAIL: $exp: fork: displaced=off: syscall number matches FAIL: $exp: fork: displaced=off: find syscall insn in fork (timeout) ... We're stepi-ing through fork trying to find the fork syscall, but encounter another syscall. The test-case attempts to handle this: ... gdb_test_multiple "stepi" "find syscall insn in $syscall" { -re ".*$syscall_insn.*$gdb_prompt $" { # Is the syscall number the correct one? if {[syscall_number_matches $syscall]} { pass $gdb_test_name } else { exp_continue } } -re "x/i .*=>.*\r\n$gdb_prompt $" { incr steps if {$steps == $max_steps} { fail $gdb_test_name } else { send_gdb "stepi\n" exp_continue } } } ... but fails to do so because it issues an exp_continue without issuing a new stepi command, and consequently the "find syscall insn in fork" test times out. Also, the call to syscall_number_matches produces a PASS or FAIL, so skipping one syscall would produce: ... FAIL: $exp: fork: displaced=off: syscall number matches PASS: $exp: fork: displaced=off: syscall number matches DUPLICATE: $exp: fork: displaced=off: syscall number matches ... Fix this by: - not producing PASS or FAIL in syscall_number_matches, and - issuing stepi when encountering another syscall. While we're at it, fix indentation in syscall_number_matches. Tested on x86_64-linux, specifically: - openSUSE Tumbleweed (glibc 2.41), and - openSUSE Leap 15.6 (glibc 2.38). PR testsuite/32780 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32780
2025-03-10Remove pid from test name in gcore-memory-usage.expTom Tromey1-1/+1
The new gcore-memory-usage.exp test puts a PID into a test case name, causing spurious comparison failures. This patch changes the test name to avoid this.
2025-03-10Revert past commitsSimon Marchi3-111/+3
I accidentally pushed my work-in-progress branch... revert that. Sorry for the noise :(. The list of commits reverted are: ae2a50a9ae15 attempt to revamp to the CU/TU list e9386435c94f gdb/dwarf: print DWARF CUs/TUs in "maint print objfiles" 6cbd64aa3eb0 gdb/dwarf: add dwarf_source_language_name 32a187da7622 libiberty: move DW_LANG_* definitions to dwarf2.def b3fa38aef59d gdb/dwarf: move index unit vectors to debug names reader and use them 30ba74418982 gdb/dwarf: track comp and type units count bedb4e09f292 gdb/dwarf: remove unnecessary braces b4f18de12c77 gdb/dwarf: use ranged for loop in some pots Change-Id: I80aed2847025f5b15c16c997680783b39858a703
2025-03-10attempt to revamp to the CU/TU listSimon Marchi3-3/+111
Change-Id: I1c8214413583d540c10c9a2322ef2a21f8bb54e7
2025-03-08[gdb/testsuite] Fix gdb.base/step-over-syscall.exp with -m32 for AMDTom de Vries1-1/+1
When running test-case gdb.base/step-over-syscall.exp with target board unix/-m32 on an AMD processor, I run into: ... (gdb) x/2i $pc^M => 0xf7fc9575 <__kernel_vsyscall+5>: syscall^M 0xf7fc9577 <__kernel_vsyscall+7>: int $0x80^M (gdb) PASS: $exp: fork: displaced=off: pc before/after syscall instruction stepi^M [Detaching after fork from child process 65650]^M 0xf7fc9579 in __kernel_vsyscall ()^M 1: x/i $pc^M => 0xf7fc9579 <__kernel_vsyscall+9>: pop %ebp^M (gdb) $exp: fork: displaced=off: stepi fork insn print /x $pc^M $2 = 0xf7fc9579^M (gdb) PASS: gdb.base/step-over-syscall.exp: fork: displaced=off: pc after stepi FAIL: $exp: fork: displaced=off: pc after stepi matches insn addr after syscall ... The problem is that the syscall returns at the "pop %ebp" insn, while the test-case expects it to return at the "int $0x80" insn. This is similar to the problem I fixed in commit 14852123287 ("[gdb/testsuite] Fix gdb.base/step-over-syscall.exp with -m32"), just that the syscall sequence used there used the "sysenter" insn instead of the "syscall" insn. Fix this by extending the fix for commit 14852123287 to also handle the "syscall" insn. Tested on x86_64-linux, both using an AMD and Intel processor. PR testsuite/32439 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32439
2025-03-07Avoid excessive CU expansion on failed matchesTom Tromey1-0/+42
PR symtab/31010 points out that something like "ptype INT" will expand all CUs in a typical program. The OP further points out that the original patch for PR symtab/30520: https://sourceware.org/pipermail/gdb-patches/2024-January/205924.html ... did solve the problem, but the patch changed after (my) review and reintroduced the bug. In cooked_index_functions::expand_symtabs_matching, the final component of a split name is compared with the entry's name using the usual method of calling get_symbol_name_matcher. This code iterates over languages and tries to split the original name according to each style. But, the Ada splitter uses the decoded name -- "int". This causes every C or C++ CU to be expanded. Clearly this is wrong. And, it seems to me that looping over languages and trying to guess the splitting style for the input text is probably bad. However, fixing the problem is not so easy (again due to Ada). I've filed a follow-up bug, PR symtab/32733, for this. Meanwhile, this patch changes the code to be closer to the originally-submitted patch. This works because the comparison is now done between the full name and the "lookup_name_without_params" object, which is a less adulterated variant of the original input. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31010 Tested-By: Simon Marchi <simon.marchi@efficios.com>
2025-03-06Fixes to gdb.ada/fun_overload_menu.expTom Tromey2-19/+28
This patch applies a few fixes to gdb.ada/fun_overload_menu.exp. It adds some comments to the source and uses this to extract line numbers. This is used to ensure that two otherwise-equivalent results are in fact different, so that the test really checks that the result is correct. It also changes the test_menu proc to accept a list of possible results. This lets the test work regardless of the order in which the menu items are presented by gdb. Finally, like an earlier patch, it changes the test to optionally accept unqualified names from gdb.
2025-03-06Allow multiple locations in homonym.expTom Tromey1-1/+1
With some forthcoming changes to GNAT, the two Get_Value functions in this test case will end up with the same name (with the current GNAT, one ends up with a "__2" suffix). This change will cause one test to set multiple breakpoints; this patch changes the test to work with either version of the compiler.
2025-03-06Fix type name in ptype-o.expTom Tromey3-10/+28
The "Rec" type in ptype-o.exp is currently named "prog__rec" by the compiler. However, with my changes to GNAT, the type will no longer have a prefix, as it is local to a procedure. Changing this to just use "rec" works fine with the new compiler, but then fails with older compilers. To allow correct operation with both compilers, this patch simply moves the type into a new package. This doesn't affect the meaning of the test, which is just ensuring that ptype/o works in a certain case. Note that the more obvious fix of just using "ptype/o rec" does not work with the current GNAT. I haven't investigated this but I did file a bug to track it: https://sourceware.org/bugzilla/show_bug.cgi?id=32169
2025-03-06Allow unqualified names in Ada testsTom Tromey14-28/+47
Currently, when a type is declared in a subprogram that isn't part of a package, gdb will give this type a qualified name. E.g., in the program for gdb.ada/arr_arr.exp: procedure Foo is type Array2_First is array (24 .. 26) of Integer; gdb will name this type 'foo.array2_first'. However, with some coming changes to GNAT (and with the remainder of this series applied as well), this will no longer happen. Instead, such types will be given their local name. IMO this makes more sense anyway. This patch updates most of the Ada tests to allow either form in the spots where it matters. Both are accepted so that the tests continue to work with older versions of GNAT. (A few tests are handled in separate patches; this patch only contains the straightforward changes.)
2025-03-05gdb/testsuite: add test for memory requirements of gcoreGuinevere Larsen2-0/+149
For a long time, Fedora has been carrying an out-of-tree patch with a similar test to the one proposed in this patch, that ensures that the memory requirements don't grow with the inferior's memory. It's been so long that the context for why this test exists has been lost, but it looked like it could be interesting for upstream. The test runs twice, once with the inferior allocating 4Mb of memory, and the other allocating 64Mb. My plan was to find the rate at which things increase based on inferior size, and have that tested to ensure we're not growing that requirement accidentally, but my testing actually showed memory requirements going down as the inferior increases, so instead I just hardcoded that we need less than 2Mb for the command, and it can be tweaked later if necessary. Approved-By: Tom Tromey <tom@tromey.com>
2025-03-05Inconsistent treatment of template parameters in DWARF readerTom Tromey1-10/+5
I noticed that if you hack some clean_restart calls into paramless.exp, the test will fail. That is, the test currently relies on the desired CUs already being expanded when trying to set a breakpoint -- which is clearly a bug, the CU expansion state should not affect "break". I tracked this down to incorrect construction of a lookup_name_info in cooked_index_functions::expand_symtabs_matching. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32510 Approved-By: Simon Marchi <simon.marchi@efficios.com>
2025-03-04Check whether gnatmake can link with -sharedTom Tromey2-0/+10
Currently, gnat-llvm does not ship a shared libgnat. This patch changes the relevant test to check whether linking with -shared actually works.
2025-03-04Check whether gnatmake supports -OgTom Tromey2-0/+9
gnat-llvm does not support the -Og flag. This arranges to check for this flag before using it.
2025-03-04Look for -fgnat-encodings optionTom Tromey2-4/+24
gnat-llvm does not support the -fgnat-encodings option, and does not emit GNAT encodings at all -- it only supports the equivalent of GCC's "minimal" encodings; which is to say, ordinary DWARF. This patch changes gdb to test whether gnatmake supports this flag and adapt accordingly. foreach_gnat_encoding is changed to pretend that the "minimal" mode is in effect, as some test examine the mode.
2025-03-04Check -fvar-tracking via ada_simple_compileTom Tromey3-2/+7
A couple of Ada tests check whether the C compiler supports -fvar-tracking. However, this doesn't really work when using gnat-llvm, because that will invoke clang under the hood. This patch arranges to check gnatmake instead, which is more robust even when toolchains are mix-and-matched.
2025-03-04Introduce ada_simple_compileTom Tromey2-11/+56
This introduces ada_simple_compile, an Ada-specific analog of gdb_simple_compile. gdb_compile_test is split into two procs to make this possible. ada_simple_compile isn't used in this patch but will be by later patches in this series.
2025-03-04Check for compiler support in scalar_storage.expTom Tromey1-2/+14
gnat-llvm does not currently handle Scalar_Storage_Order. This patch changes the scalar_storage.exp test to check the compiler error messages and report "unsupported" in this case. This way, the test ought to start working automatically if this feature is added to gnat-llvm.
2025-03-03Add language to type unit in debug-names-tu.exp.tclTom Tromey2-26/+35
I think debug-names-tu.exp.tcl only passes by accident -- the type unit does not have a language, which gdb essentially requires. This isn't noticeable right now because the type unit in question is expanded in one phase and then the symbol found in another. However, I'm working on a series that would regress this. This patch partially fixes the problem by correcting the test case, adding the language to the TU. Hoewver, it then goes a bit further and arranges for this information not to be written to .debug_names. Whether or not a type should be considered "static" seems like something that is purely internal to gdb, so this patch has the entry-creation function apply the appropriate transform. It also may make sense to change the "debug_names" proc in the test suite to process attributes more like the ordinary "cu" proc does.
2025-02-28[gdb/testsuite] Fix gdb.base/nostdlib.exp on aarch64Tom de Vries1-2/+22
On aarch64-linux, in test-case gdb.base/nostdlib.exp I run into: ... (gdb) continue^M Continuing.^M warning: Temporarily disabling breakpoints for unloaded shared library \ "/lib/ld-linux-aarch64.so.1"^M ^M Breakpoint 2, _start () at nostdlib.c:20^M 20 {^M (gdb) FAIL: $exp: pie=pie: continue to marker ... This happens as follows: - the test-case sets a breakpoint on *_start, - the breakpoint resolves to *_start in the executable, - the executable is started, and the breakpoint resolves to *_start in the dynamic linker, - execution stops at *_start in the dynamic linker, - the test-case issues a continue, expecting to continue to the breakpoint on marker, - while continuing, the dynamic linker is reported as unloaded, - the breakpoint again resolves to *_start in the executable, - execution stops at *_start in the executable, and - the test-case concludes that it failed to "continue to marker". This doesn't happen on x86_64-linux. There, after the executable is started, the breakpoint again resolves to *_start in the exec. This is similar to what happens when printing _start. On aarch64-linux, we print the _start in the dynamic linker: ... $ gdb -q -batch outputs/gdb.base/nostdlib/nostdlib-pie \ -ex "b _start" \ -ex run \ -ex "print _start" \ -ex "info break" Breakpoint 1 at 0x2bc: file nostdlib.c, line 23. Breakpoint 1.2, _start () at ../sysdeps/aarch64/dl-start.S:22 22 ENTRY (_start) $1 = {void (void)} 0xfffff7fd6ac0 <_start> Num Type Disp Enb Address What 1 breakpoint keep y <MULTIPLE> breakpoint already hit 1 time 1.1 y 0x0000aaaaaaaa02bc in _start at nostdlib.c:23 1.2 y 0x0000fffff7fd6ac0 in _start at dl-start.S:22 ... On x86_64-linux, we print the _start in the exec: ... Breakpoint 1 at 0x2c5: file nostdlib.c, line 23. Breakpoint 1.2, 0x00007ffff7fe4f00 in _start () from \ /lib64/ld-linux-x86-64.so.2 $1 = {void (void)} 0x5555555542c1 <_start> Num Type Disp Enb Address What 1 breakpoint keep y <MULTIPLE> breakpoint already hit 1 time 1.1 y 0x00005555555542c5 in _start at nostdlib.c:23 1.2 y 0x00007ffff7fe4f00 <_start> ... The difference may be down to the availability of debug info for the _start in the dynamic linker. Finally, the described scenario on aarch64-linux is not deterministic. The behavior depends on the dynamic linker being reported as unloaded, which has been classified as a GLIBC bug, so that might get fixed. Ideally this test-case would stop at both *_start in the executable and the dynamic linker, but in absense of a way to specify this reliably (see PR32748), fix this by making this a temporary breakpoint, ensuring that the breakpoint will only trigger once. Approved-by: Kevin Buettner <kevinb@redhat.com> PR testsuite/32743 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32743
2025-02-27gdb, gdbserver, gdbsupport: fix some namespace comment formattingSimon Marchi2-3/+3
I noticed a // namespace selftests comment, which doesn't follow our comment formatting convention. I did a find & replace to fix all the offenders. Change-Id: Idf8fe9833caf1c3d99e15330db000e4bab4ec66c
2025-02-25gdb/amd-dbgapi: add displaced stepping supportSimon Marchi2-0/+101
Implement the target_ops displaced stepping methods to add displaced stepping support when debugging AMD GPU programs. The knowledge of how to prepare and finish displaced steps is provided by the amd-dbgapi library, so the code here is relatively straightforward. No need to parse instructions or handle fixups, that is done by the lib We just need to remember, for each thread doing a displaced step, the displaced stepping id given by the library. Add a test to exercise the new functionality. The compiler generates DWARF that GDB doesn't understand yet [1], so trying to step over a breakpoint with DWARF present gives: (gdb) si Unhandled dwarf expression opcode 0xe9 The test purposefully builds the binary without DWARF info to circumvent this. [1] https://llvm.org/docs/AMDGPUDwarfExtensionsForHeterogeneousDebugging.html Change-Id: I53f459221a42d4b02a6041eadb8cf554500e2162 Approved-By: Lancelot Six <lancelot.six@amd.com> (amdgpu)
2025-02-25gdb: don't show incorrect source file in source windowTom de Vries3-0/+121
Consider the test-case sources main.c and foo.c: $ cat main.c extern int foo (void); int main (void) { return foo (); } $ cat foo.c extern int foo (void); int foo (void) { return 0; } and main.c compiled with debug info, and foo.c without: $ gcc -g main.c -c $ gcc foo.c -c $ gcc -g main.o foo.o In TUI mode, if we run to foo: $ gdb -q a.out -tui -ex "b foo" -ex run it gets us "[ No Source Available ]": ┌─main.c─────────────────────────────────────────┐ │ │ │ │ │ │ │ [ No Source Available ] │ │ │ │ │ └────────────────────────────────────────────────┘ (src) In: foo L?? PC: 0x400566 ... Breakpoint 1, 0x0000000000400566 in foo () (gdb) But after resizing (pressing ctrl-<minus> in the gnome-terminal), we get instead the source for main.c: ┌─main.c─────────────────────────────────────────┐ │ 3 int │ │ 4 main (void) │ │ 5 { │ │ 6 return foo (); │ │ 7 } │ │ │ │ │ └────────────────────────────────────────────────┘ (src) In: foo L?? PC: 0x400566 ... Breakpoint 1, 0x0000000000400566 in foo () (gdb) which is inappropriate because we're stopped in function foo, which is not in main.c. The problem is that, when the window is resized, GDB ends up calling tui_source_window_base::rerender. The rerender function has three cases, one for when the window already has some source code content (which is not the case here), a case for when the inferior is active, and we have a selected frame (which is the case that applies here), and a final case for when the inferior is not running. For the case which we end up in, the source code window has no content, but the inferior is running, so we have a selected frame, GDB calls the get_current_source_symtab_and_line() function to get the symtab_and_line for the current location. The get_current_source_symtab_and_line() will actually return the last recorded symtab and line location, not the current symtab and line location. What this means, is that, if the current location has no debug information, get_current_source_symtab_and_line() will return any previously recorded location, or failing that, the default (main) location. This behaviour of get_current_source_symtab_and_line() also causes problems for the 'list' command. Consider this pure CLI session: (gdb) break foo Breakpoint 1 at 0x40110a (gdb) run Starting program: /tmp/a.out Breakpoint 1, 0x000000000040110a in foo () (gdb) list 1 extern int foo (void); 2 3 int 4 main (void) 5 { 6 return foo (); 7 } (gdb) list . Insufficient debug info for showing source lines at current PC (0x40110a). (gdb) However, if we look at how GDB's TUI updates the source window during a normal stop, we see that GDB does a better job of displaying the expected contents. Going back to our original example, when we start GDB with: $ gdb -q a.out -tui -ex "b foo" -ex run we do get the "[ No Source Available ]" message as expected. Why is that? The answer is that, in this case GDB uses tui_show_frame_info to update the source window, tui_show_frame_info is called each time a prompt is displayed, like this: #0 tui_show_frame_info (fi=...) at ../../src/gdb/tui/tui-status.c:269 #1 0x0000000000f55975 in tui_refresh_frame_and_register_information () at ../../src/gdb/tui/tui-hooks.c:118 #2 0x0000000000f55ae8 in tui_before_prompt (current_gdb_prompt=0x31ef930 <top_prompt+16> "(gdb) ") at ../../src/gdb/tui/tui-hooks.c:165 #3 0x000000000090ea45 in std::_Function_handler<void(char const*), void (*)(char const*)>::_M_invoke (__functor=..., __args#0=@0x7ffc955106b0: 0x31ef930 <top_prompt+16> "(gdb) ") at /usr/include/c++/9/bits/std_function.h:300 #4 0x00000000009020df in std::function<void(char const*)>::operator() (this=0x5281260, __args#0=0x31ef930 <top_prompt+16> "(gdb) ") at /usr/include/c++/9/bits/std_function.h:688 #5 0x0000000000901c35 in gdb::observers::observable<char const*>::notify (this=0x31dda00 <gdb::observers::before_prompt>, args#0=0x31ef930 <top_prompt+16> "(gdb) ") at ../../src/gdb/../gdbsupport/observable.h:166 #6 0x00000000008ffed8 in notify_before_prompt (prompt=0x31ef930 <top_prompt+16> "(gdb) ") at ../../src/gdb/event-top.c:518 #7 0x00000000008fff08 in top_level_prompt () at ../../src/gdb/event-top.c:534 #8 0x00000000008ffdeb in display_gdb_prompt (new_prompt=0x0) at ../../src/gdb/event-top.c:487 If we look at how tui_show_frame_info figures out what source to display, it doesn't use get_current_source_symtab_and_line(), instead, it finds a symtab_and_line directly from a frame_info_pt. This means we are not dependent on get_current_source_symtab_and_line() returning the current location (which it does not). I propose that we change tui_source_window_base::rerender() so that, for the case we are discussing here (the inferior has a selected frame, but the source window has no contents), we move away from using get_current_source_symtab_and_line(), and instead use find_frame_sal instead, like tui_show_frame_info does. This means that we will always use the inferior's current location. Tested on x86_64-linux. Reviewed-By: Tom de Vries <tdevries@suse.de> Reported-By: Andrew Burgess <aburgess@redhat.com> Co-Authored-By: Andrew Burgess <aburgess@redhat.com> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32614
2025-02-24[gdb/testsuite] Exit left-over gdb in gdb.mi/mi-break.expTom de Vries9-38/+92
After test-case gdb.mi/mi-break.exp, a gdb instance is left running. The test-case starts two instances using mi_clean_restart, one using separate-mi-tty. For each instance, gdb_exit is called once, from two different locations: - mi_clean_restart, and - gdb_finish. But this doesn't seem to be effective for the separate-mi-tty case. Fix this by calling gdb_mi_exit at the end of proc test_break. Likewise in a few more more test-case. Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com> PR testsuite/32709 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32709
2025-02-24gdb/styling: only check TERM environment once, during initialisationAndrew Burgess1-0/+51
We currently check the TERM environment variable any time we call one of the ui_file::can_emit_style_escape() functions. This seems excessive. During GDB's startup we also check for the NO_COLOR environment variable and disable styling if this is set. I propose that we combine these two checks, and perform them just once during startup (as the current NO_COLOR check is currently done). As with the NO_COLOR check, if the TERM variable is set to "dumb" indicating that styling is not supported then we should just set cli_styling to false. This does mean that the user can then 'set style enabled on', even for a dumb terminal, which was not possible previously. Before this commit the "dumb" terminal check was separate and would prevent styling even if 'set style enabled on' was in effect. Of course, trying to turn on styling in a dumb terminal might not give the results that a user hope for. And so, I have implemented a check in `set_style_enabled`, so in a dumb terminal a user will see this: (gdb) set style enabled on warning: The current terminal doesn't support styling. Styled output might not appear as expected. After which GDB will try to emit styling. We could, potentially, prevent styling being enabled instead of emitting a warning, but I'm inclined to let the user turn on styling if they really want to. Approved-By: Kevin Buettner <kevinb@redhat.com> Acked-By: Tom Tromey <tom@tromey.com>
2025-02-24gdb/tui: use correct setting to control asm window stylingAndrew Burgess2-4/+84
Currently the TUI's asm window uses `source_styling` to control styling. This setting is supposed to be for styling of source files though, and the asm window displays disassembler output. We have a different setting for this `disassemble_styling`, which is controlled with 'set style disassembler enabled on|off'. Switch to use the correct control variable. I've written a new test for this, but this required some additions to the tuiterm library in order to grab character attributes for a screen region. Approved-By: Tom Tromey <tom@tromey.com>
2025-02-24gdb, testsuite, rust: fix for empty arrayRudnicki, Piotr1-0/+4
For the Rust language, to avoid segmentation fault in case of an empty array, do not try to copy any elements, but allocate and return the empty array immediately. With the command before the change, gdb crashes with message: (gdb) set lang rust (gdb) p [1;0] Fatal signal: Segmentation fault After the fix in this commit, gdb shows following message: (gdb) set lang rust (gdb) p [1;0] $1 = [] Update the existing test case gdb.rust/expr.exp to verify the change. Approved-By: Tom Tromey <tom@tromey.com>
2025-02-24gdb/testsuite/lib/rocm.exp: Fix a typo in a commentShahab Vahedi1-1/+1
"Check we have ..." --> "Check if we have ..." This is for consistency with the previous comment and the code downstream.
2025-02-24gdb: handle empty locspec when printing breakpointsAndrew Burgess1-24/+45
For background reading, please see the previous patch, and the patch before that! After the last two patches, internal breakpoints can now be marked as shlib_disabled if the library in which they are placed is unloaded. The patch before last discusses a situation related to the gdb.base/nostdlib.exp test, when run on a GNU/Linux glibc based system where executables are compiled as PIE by default. In this case it is observed that the dynamic linker will actually report itself as unloaded (i.e. remove itself from the list of currently loaded shared libraries). This behaviour is likely a bug in the dynamic linker, but this behaviour exists in released versions of the dynamic linker, so GDB should (if the cost is not too great) be changed to handle this situation. This commit handles a problem with the 'maint info breakpoints' command. When the dynamic linker is unloaded the 'shlib event' breakpoint is marked as shlib_disabled (i.e. placed into the pending state). When displaying the breakpoint in the 'maint info breakpoints' output, GDB will try to print the locspec (location_spec *) as a string Unfortunately, the locspec will be nullptr as the internal breakpoints are not created via a location_spec, this means that GDB ends up trying to call location_sepc::to_string() on a nullptr, resulting in undefined behaviour (and a crash). For most internal breakpoint types this is not a problem. If we consider bp_longjmp_master for example, if the shared library containing a breakpoint of this type is unloaded then first GDB marks the breakpoint as shlib_disabled, then after unloading the shared library breakpoint_re_set is called, which will delete the internal breakpoint, and then try to re-create it (if needed). As a result, the user never gets a change to run 'maint info breakpoints' on a bp_longjmp_master breakpoint in the shlib_disabled state. But bp_shlib_event and bp_thread_event breakpoints are not deleted and recreated like this (see internal_breakpoint::re_set), so it is possible, in rare cases, that we could end up trying to view one of these breakpoint in a shlib_disabled state, and it would be nice if GDB didn't crash as a result. I've updated the printing code to check for and handle this case, and I've updated the docs to mention this (rare) case. For testing, I've extended gdb.base/nostdlib.exp to compile as pie and nopie, and then run 'maint info breakpoints'. If we're running on a buggy glibc then this will trigger the crash. I don't know how I can trigger this problem without a buggy glibc as this would require forcing the dynamic linker to be unloaded. Reviewed-By: Eli Zaretskii <eliz@gnu.org> Approved-By: Tom Tromey <tom@tromey.com>
2025-02-24gdb: disable internal b/p when a solib is unloadedAndrew Burgess1-0/+48
Bug PR gdb/32079 highlights an issue where GDB will try to remove a breakpoint for a shared library that has been unloaded. This will trigger an error from GDB like: (gdb) next 61 dlclose (handle[dl]); (gdb) next warning: error removing breakpoint 0 at 0x7ffff78169b9 warning: error removing breakpoint 0 at 0x7ffff7730b57 warning: error removing breakpoint 0 at 0x7ffff7730ad3 54 for (dl = 0; dl < 4; ++dl) (gdb) What happens is that as the inferior steps over the dlclose() call, GDB notices that the library has been unloaded and calls disable_breakpoints_in_unloaded_shlib. However, this function only operates on user breakpoints and tracepoints. In the example above what is happening is that the test loads multiple copies of libc into different linker namespsaces. When we 'next' over the dlclose call one of the copies of libc is unloaded. As GDB placed longjmp master breakpoints within the copy of libc that was just unloaded, the warnings we see are GDB trying (and failing) to remove these breakpoints. I think the solution is for disable_breakpoints_in_unloaded_shlib to handle all breakpoints, even internal ones like the longjmp master breakpoints. If we do this then the breakpoint will be marked as shlib_disabled and also will be marked as not inserted. Later when we call breakpoint_re_set() and the longjmp breakpoints are deleted we will no longer try to remove them. This solution is inspired by a patch suggested in the bug report: https://sourceware.org/bugzilla/show_bug.cgi?id=32079#c3 There are some differences with my approach compared to the patch suggested in the bug. First I have no need to delete the breakpoint inside disable_breakpoints_in_unloaded_shlib as an earlier patch in this series arranged for breakpoint_re_set to be called when shared libraries are removed. Calling breakpoint_re_set will take care of deleting the breakpoint for us. For details see the earlier commit titled: gdb: fixes for code_breakpoint::disabled_by_cond logic Next, rather than only handling bp_longjmp and bp_longjmp_master, I allow all breakpoints to be handled. I also only give the warning about disabling breakpoints for user breakpoints, I don't see the point of warning the user about internal b/p changes. With this done the issues in PR gdb/32079 are resolved. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32079 Tested-By: Hannes Domani <ssbssa@yahoo.de> Approved-By: Tom Tromey <tom@tromey.com>
2025-02-24gdb: handle dprintf breakpoints when unloading a shared libraryAndrew Burgess1-0/+116
While working on the previous commit I realised that GDB would not handle dprintf breakpoints correctly when a shared library was unloaded. Consider this example using the test binary from shlib-unload.exp. In the function 'foo' we create a dprintf is in a shared library: (gdb) b 59 Breakpoint 1 at 0x401215: file /tmp/projects/binutils-gdb/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/shlib-unload.c, line 59. (gdb) r Starting program: /tmp/projects/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/shlib-unload/shlib-unload Breakpoint 1, main () at /tmp/projects/binutils-gdb/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/shlib-unload.c:59 59 res = dlclose (handle); /* Break here. */ (gdb) dprintf foo,"In foo" Dprintf 2 at 0x7ffff7fc50fd: file /tmp/projects/binutils-gdb/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/shlib-unload-lib.c, line 23. (gdb) n Error in re-setting breakpoint 2: Function "foo" not defined. warning: error removing breakpoint 2 at 0x7ffff7fc50fd warning: error removing breakpoint 2 at 0x7ffff7fc50fd warning: error removing breakpoint 2 at 0x7ffff7fc50fd warning: error removing breakpoint 2 at 0x7ffff7fc50fd warning: error removing breakpoint 2 at 0x7ffff7fc50fd warning: error removing breakpoint 2 at 0x7ffff7fc50fd warning: error removing breakpoint 2 at 0x7ffff7fc50fd warning: error removing breakpoint 2 at 0x7ffff7fc50fd Cannot remove breakpoints because program is no longer writable. Further execution is probably impossible. 60 assert (res == 0); (gdb) What happens here is that as the inferior steps over the dlclose call the shared library containing 'foo' is unloaded and disable_breakpoints_in_unloaded_shlib is called. However in disable_breakpoints_in_unloaded_shlib we have this check: if (b.type != bp_breakpoint && b.type != bp_jit_event && b.type != bp_hardware_breakpoint && !is_tracepoint (&b)) continue; As the dprintf has type bp_dprintf then this check triggers and we ignore the dprintf, meaning the dprintf is not disabled. When the inferior stops after the 'next' GDB tries to remove all breakpoints but the dprintf can no longer be removed, the memory in which it was placed has been unmapped from the inferior. The fix is to start using is_breakpoint() in disable_breakpoints_in_unloaded_shlib instead of the bp_breakpoint and bp_hardware_breakpoint checks. The is_breakpoint() function also checks for bp_dprintf. With this fix in place GDB now correctly disables the breakpoint and we no longer see the warning about removing the breakpoint. During review it was pointed out that PR gdb/23149 and PR gdb/20208 both describe something similar, though for these bugs, the inferior is restarted (which unloads all currently loaded shlib) rather than passing over the dlclose. But the consequences are pretty similar. I've included a test which covers this case. One additional thing that these two bugs did show though is that disable_breakpoints_in_shlibs also needs to start using is_breakpoint for the same reason. Without this change, when an inferior is restarted we get a warning like this for dprintf breakpoints: warning: Temporarily disabling breakpoints for unloaded shared library "..." but we don't get a similar warning for "normal" breakpoints. This is because disable_breakpoints_in_shlibs is called from clear_solib, which is called when an inferior is restarted. It is best not to think too hard about disable_breakpoints_in_shlibs, as this function is pretty broken, e.g. it doesn't call notify_breakpoint_modified, despite modifying the breakpoints. But for now I'm ignoring that, but fixing this is definitely on my list for my next set of breakpoint related fixes, it's just that a lot of these breakpoint fixes end up being depending on one another, but I want to avoid making this series too long. So for now, I'm ignoring the existing bug (missing breakpoint modified events), and fixing disable_breakpoints_in_shlibs to cover dprintf. With these fixes in place, the two bugs mentioned above should be fixed. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=23149 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=20208 Tested-By: Hannes Domani <ssbssa@yahoo.de> Approved-By: Tom Tromey <tom@tromey.com>
2025-02-24gdb: restructure disable_breakpoints_in_unloaded_shlibAndrew Burgess5-0/+266
This commit rewrites disable_breakpoints_in_unloaded_shlib to be more like disable_breakpoints_in_freed_objfile. Instead of looping over all b/p locations, we instead loop over all b/p and then over all locations for each b/p. The advantage of doing this is that we can fix the small bug that was documented in a comment in the code: /* This may cause duplicate notifications for the same breakpoint. */ notify_breakpoint_modified (b); By calling notify_breakpoint_modified() as we modify each location we can potentially send multiple notifications for a single b/p. Is this a bug? Maybe not. After all, at each notification one of the locations will have changed, so its probably fine. But it's not ideal, and we can easily do better, so lets do that. There's a new test which checks that we only get a single notification when the shared library is unloaded. Note that the test is written as if there are multiple related but different tests within the same test file ... but there aren't currently! The next commit will add another test proc to this test script at which point the comments will make sense. I've done this to avoid unnecessary churn in the next commit. Tested-By: Hannes Domani <ssbssa@yahoo.de> Approved-By: Tom Tromey <tom@tromey.com>
2025-02-24gdb: fixes for code_breakpoint::disabled_by_cond logicAndrew Burgess5-0/+319
I spotted that the code_breakpoint::disabled_by_cond flag doesn't work how I'd expect it too. The flag appears to be "sticky" in some situations; once a code_breakpoint::disabled_by_cond flag is marked true, then, in some cases the flag wont automatically become false again, even when you'd think it should. The problem is in update_breakpoint_locations. In this function, which is called as a worker of code_breakpoint::re_set, GDB computes a new set of locations for a breakpoint, the new locations are then installed into the breakpoint. However, before installing the new locations GDB attempts to copy the bp_location::enabled and bp_location::disabled_by_cond flag from the old locations into the new locations. The reason for copying the ::enabled flag makes sense. This flag is controlled by the user. When we create the new locations if GDB can see that a new location is equivalent to one of the old locations, and if the old location was disabled by the user, then the new location should also be disabled. However, I think the logic behind copying the ::disabled_by_cond flag is wrong. The disabled_by_cond flag is controlled by GDB and should toggle automatically. If the condition string can be parsed then the flag should be false (b/p enabled), if the condition string can't be parsed then the flag should be true (b/p disabled). As we always parse the condition string in update_breakpoint_locations before we try to copy the ::enabled flag value then the ::disabled_by_cond flag should already be correct, there's no need to copy over the ::disabled_by_cond value from the old location. As a concrete example, consider a b/p placed within the main executable, but with a condition that depends on a variable within a shared library. When the b/p is initially created the b/p will be disabled as the condition string will be invalid (the shared library variable isn't available yet). When the inferior starts the shared library is loaded and the condition variable becomes available to GDB. When the shared library is loaded breakpoint_re_set is called which (eventually) calls update_breakpoint_locations. A new location is computed for the breakpoint and the condition string is parsed. As the shared library variable is now know the expression parses correctly and ::disabled_by_cond is left false for the new location. But currently GDB spots that the new location is at the same address as the old location and copies disabled_by_cond over from the old location, which marks the b/p location as disabled. This is not what I would expect. The solution is simple, don't copy over disabled_by_cond. While writing a test I found another problem though. The disabled_by_cond flag doesn't get set true when it should! This is the exact opposite of the above. The problem here is in solib_add which is (despite the name) called whenever the shared library set changes, including when a shared library is unloaded. Imagine an executable that uses dlopen/dlclose to load a shared library. Given an example of a b/p in the main executable that has a condition that uses a variable from our shared library, a library which might be unloaded with dlclose. My expectation is that, when the library is unloaded, GDB will automatically mark the breakpoint as disabled_by_cond, however, this was not happening. The problem is that in solib_add we only call breakpoint_re_set when shared libraries are added, not when shared libraries are removed. The solution I think is to just call breakpoint_re_set in both cases, now the disabled_by_cond flag is updated as I'd expect. Unfortunately, making this change causes a regression when running: make check-gdb \ TESTS="gdb.trace/change-loc.exp" \ RUNTESTFLAGS="--target_board=native-gdbserver" This test unloads a shared library and expects breakpoints within the shared library to enter the PENDING state (because the bp_location's shlib_disabled flag will be set). However, the new call to breakpoint_re_set means that this is no longer the case. The breakpoint_re_set call means that update_breakpoint_locations is called, which then checks if all locations for a breakpoint are pending or not. In this test not all locations are pending, and so GDB recalculates the locations of each breakpoint, this means that pending locations are discarded. There is a but report PR gdb/32404 which mentions the problems with shlib_disabled pending breakpoints, and how they are prone to being randomly deleted if the user can cause GDB to trigger a call to breakpoint_re_set. This patch just adds another call to breakpoint_re_set, which triggers this bug in this one test case. For now I have marked this test as KFAIL. I do plan to try and address the pending (shlib_disabled) breakpoint problem in the future, but I'm not sure when that will be right now. There are, of course, tests to cover all these cases. During review I was pointed at bug PR gdb/32079 as something that this commit might fix, or help in fixing. And this commit is part of the fix for that bug, but is not the complete solution. However, the remaining parts of the fix for that bug are not really related to the content of this commit. The problem in PR gdb/32079 is that the inferior maps multiple copies of libc in different linker namespaces using dlmopen (actually libc is loaded as a consequence of loading some other library into a different namespace, but that's just a detail). The user then uses a 'next' command to move the inferior forward. GDB sets up internal breakpoints on the longjmp symbols, of which there are multiple copies (there is a copy in every loaded libc). However, the 'next' command is, in the problem case, stepping over a dlclose call which unloads one of the loaded libc libraries. In current HEAD GDB in solib_add we fail to call breakpoint_re_set() when the library is unloaded; breakpoint_re_set() would delete and then recreate the longjmp breakpoints. As breakpoint_re_set() is not called GDB thinks that the the longjmp breakpoint in the now unloaded libc still exists, and is still inserted. When the inferior stops after the 'next' GDB tries to delete and remove the longjmp breakpoint which fails as the libc in which the breakpoint was inserted is no longer mapped in. When the user tries to 'next' again GDB tries to re-insert the still existing longjmp breakpoint which again fails as the memory in which the b/p should be inserted is no longer part of the inferior memory space. This commit helps a little. Now when the libc library is unmapped GDB does call breakpoint_re_set(). This deletes the longjmp breakpoints including the one in the unmapped library, then, when we try to recreate the longjmp breakpoints (at the end of breakpoint_re_set) we don't create a b/p in the now unmapped copy of libc. However GDB does still think that the deleted breakpoint is inserted. The breakpoint location remains in GDB's data structures until the next time the inferior stops, at which point GDB tries to remove the breakpoint .... and fails. However, as the b/p is now deleted, when the user tries to 'next' GDB no longer tries to re-insert the b/p, and so one of the problems reported in PR gdb/32079 is resolved. I'll fix the remaining issues from PR gdb/32079 in a later commit in this series. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32079 Tested-By: Hannes Domani <ssbssa@yahoo.de> Approved-By: Tom Tromey <tom@tromey.com>
2025-02-21gdb/testsuite/rocm.exp: Use system GPU(s) to detect featuresShahab Vahedi1-36/+74
gdb/testsuite/rocm.exp: Use system GPU(s) to detect features Background ---------- This patch revisits the purpose of hcc_amdgpu_targets{} in order to address the separation of concerns between: - GPU targets passed to the compiler. This kind of target is passed as an argument to flags like "--offload-arch=...", "--targets=...", etc. - GPU targets as in available GPU devices on the system. This is crucial for finding which capabilities are available, and therefore which tests should be executed or skipped. Code change ----------- - A new "find_amdgpu_devices{}" procedure is added. It is responsible for listing the GPU devices that are available on the system. - "hcc_amdgpu_targets{}" is rewritten to use the newly added "find_amdgpu_devices{}" when there's no environment variable (HCC_AMDGPU_TARGET) set. - The output of "hcc_amdgpu_targets{}" is now only used in places that set the target for the building toolchains. - The output of "find_amdgpu_devices{}" is used anywhere that needs to evaluate the GPU features. Approved-By: Lancelot Six <lancelot.six@amd.com> (amdgpu) Change-Id: Ib11021dbe674aa40192737ede78284a1bc531513
2025-02-20Handle optional lines correctly in gdb.ada/complete.expTom Tromey1-20/+37
While working on another series, I discovered that the existing code in gdb.ada/complete.exp that conditionally accepts a completion does not work correctly. The code assumes that wrapping a line in "(...)?" will make the entire line optional, but really this will only match a blank line. Meanwhile, I needed this same patch for a second series I'm working on, so I've pulled this out. As it only affects Ada, I am going to check it in.
2025-02-20GDB: add stabs deprecation warningGuinevere Larsen1-1/+1
Now that stabs is deprecated, we should probably warn our users of it before removing support, so that they have time to react and either make themselves heard, or fix things on their end so that they can still debug their applications. This commit adds a new function that emits a warning whenever GDB does stabs reading. Since there are several places where stabs is re-invented, this warning had to be added to many places, but I think I managed to warn everywhere relevant without duplicating warnings. Also, the test gdb.stabs/weird.exp explicitly checks for GDB warnings when reading stabs, so it had to be updated to account for the deprecation warning. It is done generically, since it will be removed in the next release anyway. Approved-By: Tom Tromey <tom@tromey.com>
2025-02-19gdb/mi: Fix segfault when attaching a rocm process with MILancelot Six2-0/+70
When using the MI interpreter, if someone was to attach to a ROCm process which has active GPU waves, GDB would issue a segfault as follows: attach 1994813 &"attach 1994813\n" ~"Attaching to process 1994813\n" =thread-group-started,id="i1",pid="1994813" =thread-created,id="1",group-id="i1" =thread-created,id="2",group-id="i1" ~"[New LWP 1994828]\n" *running,thread-id="2" =thread-created,id="3",group-id="i1" ~"[New LWP 1994825]\n" *running,thread-id="3" =thread-created,id="4",group-id="i1" ~"[New LWP 1994823]\n" *running,thread-id="4" ^done =library-loaded,... [...] ~"[Thread debugging using libthread_db enabled]\n" ~"Using host libthread_db library \"/lib/x86_64-linux-gnu/libthread_db.so.1\".\n" =thread-created,id="5",group-id="i1" &"\n\n" &"Fatal signal: " &"Segmentation fault" &"\n" &"----- Backtrace -----\n" &"Backtrace unavailable\n" &"---------------------\n" &"A fatal error internal to GDB has been detected, further\ndebugging is not possible. GDB will now terminate.\n\n" &"This is a bug, please report it." &" For instructions, see:\n" &"<https://github.com/ROCm-Developer-Tools/ROCgdb/issues>" &"." &"\n\n" Segmentation fault The issue comes from using a non-initialized pointer in mi_on_resume_1: if (!mi->running_result_record_printed && mi->mi_proceeded) { gdb_printf (mi->raw_stdout, "%s^running\n", mi->current_token ? mi->current_token : ""); } In this instance, "mi->current_token" has an uninitialized value. This is a regression introduced by: commit def2803789208a617c429b5dcf2026decb25ce0c Date: Wed Sep 6 11:02:00 2023 -0400 gdb/mi: make current_token a field of mi_interp Before this patch, current_token was a global implicitly 0-initialized. Since it is now a class field, it is not 0-initialized by default anymore. This patch changes this. Change-Id: I3f00b080318a70405d881ff0abe02b2c5cb1f9d8 Approved-By: Simon Marchi <simon.marchi@efficios.com> Approved-By: Tom Tromey <tom@tromey.com>
2025-02-18testsuite, mi: prevent buffer overflow in get_mi_thread_listTankut Baris Aktemur1-25/+26
If there is a large number of threads in the input program, the expect buffer in `get_mi_thread_list` would become full. Prevent this by consuming the buffer in small pieces. Regression-tested using the gdb.mi tests. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2025-02-18[gdb/testsuite] Don't start gdb in gdb.base/gstack.expTom de Vries1-2/+2
In test-case gdb.base/gstack.exp we start a gdb implicitly using prepare_for_testing. The gdb is not really used, but its spawn_id (available in variable gdb_spawn_id) is used in a gdb_test_multiple, which is used to interact with the gstack process. Usually, a running gdb is cleaned up at test-case exit in gdb_finish, which calls gdb_exit, which by default calls gdb_default_exit, which does 'send_gdb "quit\n"'. However, this sends a quit to the host process expect is currently talking to, defined by board_info(host,fileid), and after spawning gstack that's gstack, not gdb. Fix this by: - using build_executable instead of prepare_for_testing to not spawn an unused gdb, and - changing the gdb_test_multiple into a gdb_expect, eliminating the implicit use of gdb_spawn_id. Tested on x86_64-linux. Reviewed-By: Keith Seitz <keiths@redhat.com> PR testsuite/32709 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32709
2025-02-18[gdb] Fix some typosTom de Vries4-6/+6
Fix typos: ... overriden -> overridden reate -> create ... Tested on x86_64-linux. I
2025-02-17testsuite, mi: fix indentation in get_mi_thread_listTankut Baris Aktemur1-29/+29
The `get_mi_thread_list` procedure's body is incorrectly indented. Fix it. There is one line that was already long. Consider it an exception and don't bother breaking it.
2025-02-15alpha, ld: remove -taso optionIvan Kokshaysky1-6/+0
The -taso switch was quite useful 25 years ago for porting 32-bit code with broken integer-pointer casting. Not anymore. The EF_ALPHA_32BIT Linux support is going to be dropped in kernel v6.14 [1], NetBSD and OpenBSD never had it, so there is no point in keeping the -taso option around. Also remove alpha special case that uses -taso from gdb.base/dump.exp in gdb testsuite. [1] https://lore.kernel.org/all/87jzb2tdb7.fsf_-_@email.froward.int.ebiederm.org Signed-off-by: Ivan Kokshaysky <ink@unseen.parts> Reviewed-By: Maciej W. Rozycki <macro@orcam.me.uk> Approved-By: Andrew Burgess <aburgess@redhat.com>
2025-02-14gdb/testsuite: clean ups in gdb.python/py-source-styling.expAndrew Burgess1-8/+8
The top comment in gdb.python/py-source-styling.exp was completely wrong, clearly a cut&paste job from elsewhere. Write a comment that actually reflects what the test does. I've also moved the allow_python_tests check earlier in the file. And I changed some 'return -1' into just 'return'. I'm not aware that the '-1' adds any value. I also folded a 'pass $gdb_test_name' into the preceding gdb_assert, which I think is neater. There is no change in what is actually being tested after this commit. Approved-By: Tom Tromey <tom@tromey.com>
2025-02-14gdb/tui: use maybe_update for source centring in an extra caseAndrew Burgess2-0/+88
I noticed that, with recent versions of GDB, when the TUI is enabled before the inferior is started, the source code display is not as helpful as it used to be. Here's a simple test program being displayed using GDB 15.2, at this point the inferior has not started, all I've done is 'tui enable': ┌─hello.c────────────────────────────────────────────────┐ │ 10 return 0; │ │ 11 } │ │ 12 │ │ 13 /* The main function. */ │ │ 14 │ │ 15 int │ │ 16 main () │ │ 17 { │ │ 18 printf ("Hello World\n"); │ │ 19 call_me ( 0, 1, 2, 3, 4, 5, 6, 7 ); │ │ 20 return 0; │ │ 21 } │ │ │ │ │ └────────────────────────────────────────────────────────┘ Compare this to GDB 16.2: ┌─hello.c────────────────────────────────────────────────┐ │ 17 { │ │ 18 printf ("Hello World\n"); │ │ 19 call_me ( 0, 1, 2, 3, 4, 5, 6, 7 ); │ │ 20 return 0; │ │ 21 } │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └────────────────────────────────────────────────────────┘ I think the new layout is not as good because it is missing the context of the function name. The new behaviour started with the commit: commit 49e607f511c1fab82a0116990a72d1915c74bb4a Author: Stephan Rohr <stephan.rohr@intel.com> Date: Sat Aug 3 02:07:42 2024 -0700 gdb: adjust the default place of 'list' to main's prologue I don't think the new behaviour is really a problem with that commit, rather, when using 'tui enable' before the inferior has started GDB ends up calling tui_source_window_base::rerender(), and then passes through the code path which calls update_source_window_with_addr(). When using 'tui enable' after the inferior has started, GDB again calls tui_source_window_base::rerender(), but this time has a frame, and so takes the second code path, which centres the selected source line, and then calls update_source_window. The point is that the update_source_window_with_addr() path doesn't include the logic to centre the source line. Before the above commit this was fine as GDB's default location would be prior to main, and so we got the "good" TUI output. After the above commit the default location is now main's prologue, and without the centring logic, the first line shown is main's prologue. I propose fixing this by having update_source_window_with_addr() call maybe_update(). This will first check if the requested line is already visible, and if not, show the requested line with centring applied. After this commit, the 'tui enable' state is now: ┌─hello.c─────────────────────────────────────────────────────┐ │ 11 } │ │ 12 │ │ 13 /* The main function. */ │ │ 14 │ │ 15 int │ │ 16 main () │ │ 17 { │ │ 18 printf ("Hello World\n"); │ │ 19 call_me ( 0, 1, 2, 3, 4, 5, 6, 7 ); │ │ 20 return 0; │ │ 21 } │ │ │ │ │ │ │ └─────────────────────────────────────────────────────────────┘ It's not identical to the old behaviour, but that was never the objective, we do however, see the context around main's prologue, which will usually be enough to see the function name and return type, which I think is useful. Approved-By: Tom Tromey <tom@tromey.com>