aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite
AgeCommit message (Collapse)AuthorFilesLines
2025-06-09gdb.threads/thread-execl, don't re-exec foreverPedro Alves1-2/+8
I noticed on Cygwin, gdb.thread/thread-execl.exp would hang, (not that surprising since we can't follow-exec on Cygwin). Looking at the process list running on the machine, we end up with a thread-execl.exe process constantly respawning another process [1]. We see the same constant-reexec if we launch gdb.thread/thread-execl manually on the shell: $ ./testsuite/outputs/gdb.threads/thread-execl/thread-execl # * doesn't exit, constantly re-execing * ^C Prevent this leftover constantly-re-execing scenario by making the testcase program only exec once. We now get: $ ./testsuite/outputs/gdb.threads/thread-execl/thread-execl $ # exits immediately after one exec. On Cygwin, the testcase now fails reasonably quickly, and doesn't leave stale processes behind. Still passes cleanly on x86-64 GNU/Linux. [1] Cygwin's exec emulation spawns a new Windows process for the new image. Approved-By: Andrew Burgess <aburgess@redhat.com> Change-Id: I0de1136cf2ef7e89465189bc43489a2139a80efb
2025-06-09Support core dumping testcases with Cygwin's dumperPedro Alves1-1/+6
Cygwin supports dumping ELF cores via a dumper.exe utility, see https://www.cygwin.com/cygwin-ug-net/dumper.html. When I run a testcase that has the "kernel" generate a corefile, like gdb.base/corefile.exp, Cygwin invokes dumper.exe correctly and generates an ELF core file, however, the testsuite doesn't find the generated core: Running /home/alves/gdb/src/gdb/testsuite/gdb.base/corefile.exp ... WARNING: can't generate a core file - core tests suppressed - check ulimit -c The file is correctly put under $coredir, e.g., like so: outputs/gdb.base/corefile/coredir.8926/corefile.exe.core The problem is in this line in core_find: foreach i "${coredir}/core ${coredir}/core.coremaker.c ${binfile}.core" { Note that that isn't looking for "${binfile}.core" inside ${coredir}... That is fixed in this patch. However, that still isn't sufficient for Cygwin + dumper, as in that case the core is going to be called foo.exe.core, not foo.core. Fix that by looking for foo.exe.core in the core dir as well. With this, gdb.base/corefile.exp and other tests that use core_find now run. They don't pass cleanly, but at least now they're exercised. Approved-By: Tom Tromey <tom@tromey.com> Change-Id: Ic807dd2d7f22c5df291360a18c1d4fbbbb9b993e
2025-06-09Adjust gdb.base/sigall.exp for CygwinPedro Alves1-4/+5
The gdb.base/sigall.exp testcase has many FAILs on Cygwin currently. From: Thread 1 "sigall" received signal SIGPWR, Power fail/restart. 0x00007ffeac9ed134 in ntdll!ZwWaitForSingleObject () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll (gdb) FAIL: gdb.base/sigall.exp: get signal LOST we see two issues. The test is expecting "Program received ..." which only appears if the inferior is single-threaded. All Cygwin inferiors are multi-threaded, because both Windows and the Cygwin runtime spawn a few helper threads. And then, SIGLOST is the same as SIGPWR on Cygwin. The testcase already knows to treat them the same on SPARC64 GNU/Linux. We just need to extend the relevant code to treat Cygwin the same. With this, the test passes cleanly on Cygwin. Approved-By: Tom Tromey <tom@tromey.com> Change-Id: Ie3553d043f4aeafafc011347b6cb61ed58501667
2025-06-09Adjust gdb.arch/amd64-watchpoint-downgrade.exp for CygwinPedro Alves1-1/+1
The gdb.arch/amd64-watchpoint-downgrade.exp testcase is assuming the output of debugging a single-thread program, like so, on e.g., GNU/Linux: starti Starting program: .../gdb.arch/amd64-watchpoint-downgrade/amd64-watchpoint-downgrade warning: watchpoint 1 downgraded to software watchpoint Program stopped. 0x00007ffff7fe32b0 in _start () from /lib64/ld-linux-x86-64.so.2 However, on Cygwin, where all inferiors are multi-threaded (because both Windows and the Cygwin runtime spawn a few helper threads), we get: starti Starting program: .../gdb.arch/amd64-watchpoint-downgrade/amd64-watchpoint-downgrade [New Thread 4652.0x17e4] warning: watchpoint 1 downgraded to software watchpoint Thread 1 stopped. 0x00007ffbfc1c0911 in ntdll!LdrInitShimEngineDynamic () from C:/Windows/SYSTEM32/ntdll.dll This commit adjusts the testcase to work with either output. (Note GDB may print a thread name after the thread number.) Approved-by: Kevin Buettner <kevinb@redhat.com> Change-Id: I3aedfec04924ea3fb3bb87ba3251e2b720f8d59c
2025-06-09Adjust gdb.base/bp-permanent.exp for CygwinPedro Alves1-2/+2
On Cygwin, all inferiors are multi-threaded, because both Windows and the Cygwin runtime spawn a few helper threads. Adjust the gdb.base/bp-permanent.exp testcase to work with either single- or multi-threaded inferiors. Approved-by: Kevin Buettner <kevinb@redhat.com> Change-Id: I28935b34fc9f739c2a5490e83aa4995d29927be2
2025-06-09Adjust gdb.base/bp-cond-failure.exp for CygwinPedro Alves1-2/+2
Currently on Cygwin, I get: Running /home/alves/gdb/src/gdb/testsuite/gdb.base/bp-cond-failure.exp ... FAIL: gdb.base/bp-cond-failure.exp: access_type=char: cond_eval=auto: multi-loc: continue FAIL: gdb.base/bp-cond-failure.exp: access_type=char: cond_eval=auto: single-loc: continue FAIL: gdb.base/bp-cond-failure.exp: access_type=short: cond_eval=auto: multi-loc: continue FAIL: gdb.base/bp-cond-failure.exp: access_type=short: cond_eval=auto: single-loc: continue FAIL: gdb.base/bp-cond-failure.exp: access_type=int: cond_eval=auto: multi-loc: continue FAIL: gdb.base/bp-cond-failure.exp: access_type=int: cond_eval=auto: single-loc: continue FAIL: gdb.base/bp-cond-failure.exp: access_type=long long: cond_eval=auto: multi-loc: continue FAIL: gdb.base/bp-cond-failure.exp: access_type=long long: cond_eval=auto: single-loc: continue On GNU/Linux, we see: Breakpoint 2.1, foo () at .../src/gdb/testsuite/gdb.base/bp-cond-failure.c:21 21 return 0; /* Multi-location breakpoint here. */ (gdb) PASS: gdb.base/bp-cond-failure.exp: access_type=char: cond_eval=auto: multi-loc: continue While on Cygwin, we see: Thread 1 "bp-cond-failure" hit Breakpoint 2.1, foo () at .../src/gdb/testsuite/gdb.base/bp-cond-failure.c:21 21 return 0; /* Multi-location breakpoint here. */ (gdb) FAIL: gdb.base/bp-cond-failure.exp: access_type=char: cond_eval=auto: multi-loc: continue The difference is the "Thread 1" part in the beginning of the quoted output. It appears on Cygwin, but not on Linux. That's because on Cygwin, all inferiors are multi-threaded, because both Windows and the Cygwin runtime spawn a few helper threads. Fix this by adjusting the gdb.base/bp-cond-failure.exp testcase to work with either single- or multi-threaded inferiors. The testcase passes cleanly for me after this. Approved-by: Kevin Buettner <kevinb@redhat.com> Change-Id: I5ff11d06ac1748d044cef025f1e78b8f84ad3349
2025-06-07[gdb/testsuite] Fix gdb.ada/dyn-bit-offset.exp on s390xTom de Vries2-6/+39
On s390x-linux, with test-case gdb.ada/dyn-bit-offset.exp and gcc 7.5.0 I get: ... (gdb) print spr^M $1 = (discr => 3, array_field => (-5, -6, -7), field => -6, another_field => -6)^M (gdb) FAIL: $exp: print spr print spr.field^M $2 = -6^M (gdb) FAIL: $exp: print spr.field ... On x86_64-linux, with the same compiler version I get: ... (gdb) print spr^M $1 = (discr => 3, array_field => (-5, -6, -7), field => -4, another_field => -4)^M (gdb) XFAIL: $exp: print spr print spr.field^M $2 = -4^M (gdb) PASS: $exp: print spr.field ... In both cases, we're hitting the same compiler problem, but it manifests differently on little and big endian. Make sure the values seen for both little and big endian trigger xfails for both tests. Printing spr.field gives the expected value -4 for x86_64, but that's an accident. Change the actual spr.field value to -5, to make sure that we get the same number of xfails on x86_64 and s390x. Finally, make the xfails conditional on the compiler version. Tested using gcc 7.5.0 on both x86_64-linux and s390x-linux. Approved-By: Andrew Burgess <aburgess@redhat.com> PR testsuite/33042 https://sourceware.org/bugzilla/show_bug.cgi?id=33042
2025-06-06gdb/solib: make _linker_namespace use selected frameGuinevere Larsen1-0/+6
When the convenience variable $_linker_namespace was introduced, I meant for it to print the namespace of the frame that where the user was stopped. However, due to confusing what "current_frame" and "selected_frame" meant, it instead printed the namespace of the lowermost frame. This commit updates the code to follow my original intent. Since the variable was never in a GDB release, updating the behavior should not cause any disruption. It also adds a test to verify the functionality. Approved-By: Tom Tromey <tom@tromey.com>
2025-06-06Fix regression with DW_AT_bit_offset handlingTom Tromey2-0/+72
Internal AdaCore testing using -gdwarf-4 found a spot where GCC will emit a negative DW_AT_bit_offset. However, my recent signed/unsigned changes assumed that this value had to be positive. I feel this bug somewhat invalidates my previous thinking about how DWARF attributes should be handled. In particular, both GCC and LLVM at understand that a negative bit offset can be generated -- but for positive offsets they might use a smaller "data" form, which is expected not to be sign-extended. LLVM has similar code but GCC does: if (bit_offset < 0) add_AT_int (die, DW_AT_bit_offset, bit_offset); else add_AT_unsigned (die, DW_AT_bit_offset, (unsigned HOST_WIDE_INT) bit_offset); What this means is that this attribute is "signed but default unsigned". To fix this, I've added a new attribute::confused_constant method. This should be used when a constant value might be signed, but where narrow forms (e.g., DW_FORM_data1) should *not* cause sign extension. I examined the GCC and LLVM DWARF writers to come up with the list of attributes where this applies, namely DW_AT_bit_offset, DW_AT_const_value and DW_AT_data_member_location (GCC only, but LLVM always emits it as unsigned, so we're safe here). This patch corrects the bug and imports the relevant test case. Regression tested on x86-64 Fedora 41. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32680 Bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118837 Approved-By: Simon Marchi <simon.marchi@efficios.com>
2025-06-06gdb: prevent assertion after 'set debug breakpoint on'Andrew Burgess2-0/+101
Turns out that using 'set debug breakpoint on' will trigger an assertion for 'catch' style breakpoints, e.g.: (gdb) file /tmp/hello.x Reading symbols from /tmp/hello.x... (gdb) catch exec Catchpoint 1 (exec) (gdb) set debug breakpoint on (gdb) start [breakpoint] dump_condition_tokens: Tokens: { INFERIOR: "1" } Temporary breakpoint 2 at 0x401198: file /tmp/hello.c, line 18. [breakpoint] update_global_location_list: insert_mode = UGLL_MAY_INSERT Starting program: /tmp/hello.x [breakpoint] update_global_location_list: insert_mode = UGLL_MAY_INSERT ../../gdb-16.1/gdb/gdbarch-gen.c:1764: internal-error: gdbarch_addr_bit: Assertion `gdbarch != NULL' failed. .... etc ... The problem is that catch breakpoints don't set the bp_location::gdbarch member variable, they a "dummy" location added with a call to add_dummy_location (breakpoint.c). The breakpoint_location_address_str function (which is only used for breakpoint debug output) relies on bp_location::gdbarch being set in order to call the paddress function. I considered trying to ensure that the bp_location::gdbarch variable is always set to sane value. For example, in add_dummy_location I tried copying the gdbarch from the breakpoint object, and this does work for the catchpoint case, but for some of the watchpoint cases, even the breakpoint object has no gdbarch value set. Now this seemed a little suspect, but, the more I thought about it, I wondered if "fixing" the gdbarch was allowing me to solve the wrong problem. If the gdbarch was set, then this would allow us to print the address field of the bp_location, which is going to be 0, after all, as this is a dummy location, which has no address. But does it really make sense to print the address 0? For some targets, 0 is a valid address. But that wasn't an address we actually selected, it's just the default value for dummy locations. And we already have a helper function bl_address_is_meaningful, which returns false for dummy locations. So, I propose that in breakpoint_location_address_str, we use bl_address_is_meaningful to detect dummy locations, and skip the address printing code in that case. For testing, I temporarily changed insert_bp_location so that breakpoint_location_address_str was always called, even when breakpoint debugging was off. I then ran the whole testsuite. Without the fixes included in this commit I saw lots of assertion failures, but with the fixes from this commit in place, I now see no assertion failures. I've added a new test which reveals the original assertion failure. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2025-06-06Make default_gdb_exit resilient to failed closesPedro Alves1-1/+3
For some reason, when testing GDB on Cygwin, I get: child process exited abnormally while executing "exec sh -c "exec > /dev/null 2>&1 && (kill -2 -$spid || kill -2 $spid)"" (procedure "close_wait_program" line 20) invoked from within "close_wait_program $shell_id $pid" (procedure "standard_close" line 23) invoked from within "standard_close "Windows-ROCm"" ("eval" body line 1) invoked from within "eval ${try}_${proc} \"$dest\" $args" (procedure "call_remote" line 42) invoked from within "call_remote "" close $host" (procedure "remote_close" line 3) invoked from within "remote_close host" (procedure "log_and_exit" line 30) invoked from within "log_and_exit" When that happens from within clean_restart, clean_restart doesn't clear the gdb_spawn_id variable, and then when clean_restart starts up a new GDB, that sees that gdb_spawn_id is already set, so it doesn't actually spawn a new GDB, and so clean_restart happens to reuse the same GDB (!). Many tests happen to actually work OK with this, but some don't, and the failure modes can be head-scratching. Of course, the failure to close GDB should be fixed, but when it happens, I think it's good to not end up with the current weird state. Connecting the "child process exit abnormally" errors at the end of a testcase run with weird FAILs in other testcases took me a while (as in, weeks!), it wasn't obvious to me immediately. Thus, this patch makes default_gdb_exit more resilient to failed closes, so that gdb_spawn_id is unset even is closing GDB fails, and we move on to start a new GDB. Approved-By: Andrew Burgess <aburgess@redhat.com> Change-Id: I9ec95aa61872a40095775534743525e0ad2097d2
2025-06-06gdb_test_multiple: Anchor prompt match if -lblPedro Alves3-1/+112
The testcase added by this patch has a gdb_test_multiple call that wants to match different lines of output that all have a common prefix, and do different actions on each. Instead of a single regular expression with alternatives, it's clearer code if the different expressions are handled with different "-re", like so: gdb_test_multiple "command" "" -lbl { -re "^command(?=\r\n)" { exp_continue } -re "^\r\nprefix foo(?=\r\n)" { # Some action for "foo". exp_continue } -re "^\r\nprefix bar(?=\r\n)" { # Some action for "bar". exp_continue } -re "^\r\nprefix \[^\r\n\]*(?=\r\n)" { # Some action for all others. exp_continue } -re "^\r\n$::gdb_prompt $" { gdb_assert {$all_prefixes_were_seen} $gdb_test_name } } Above, the leading anchors in the "^\r\nprefix..." matches are needed to avoid too-eager matching due to the common prefix. Without the anchors, if the expect output buffer happens to contain at least: "\r\nprefix xxx\r\nprefix foo\r\n" ... then the "prefix foo" pattern match inadvertently consumes the first "prefix xxx" line. Without the anchor in the prompt match, like: -re "\r\n$::gdb_prompt $" { gdb_assert {$all_prefixes_were_seen} $gdb_test_name } Or the equivalent: -re -wrap "" { gdb_assert {$all_prefixes_were_seen} $gdb_test_name } ... then if the expect buffer contains: "\r\nmeant-to-be-matched-by-lbl\r\nprefix foo\r\n$gdb_prompt " ... then the prompt regexp matches this, consuming the "prefix" line inadvertently, and we get a FAIL. The built-in regexp matcher for -lbl doesn't get a chance to match the "\r\nmeant-to-be-matched-by-lbl\r\n" part, because the built-in prompt match appears first within gdb_test_multiple. By adding the anchor to the prompt regexp, we avoid that problem. However, the same expect output buffer contents will still match the built-in prompt regexp. That is what is fixed by this patch. It makes it so that if -lbl is specified, the built-in prompt regexp has a leading anchor. Original idea for turning this into a gdb.testsuite/ testcase by Tom de Vries <tdevries@suse.de>. Approved-By: Tom de Vries <tdevries@suse.de> Change-Id: Ic2571ec793d856a89ee0d533ec363e2ac6036ea2
2025-06-06[gdb/testsuite] Fix timeout in gdb.multi/attach-while-running.expTom de Vries1-1/+1
With test-case gdb.multi/attach-while-running.exp usually I get: ... (gdb) run &^M Starting program: attach-while-running ^M (gdb) PASS: $exp: run & [Thread debugging using libthread_db enabled]^M Using host libthread_db library "/lib64/libthread_db.so.1".^M add-inferior^M [New inferior 2]^M Added inferior 2 on connection 1 (native)^M (gdb) PASS: $exp: add-inferior ... or: ... (gdb) run & Starting program: attach-while-running (gdb) PASS: $exp: run & add-inferior [New inferior 2] Added inferior 2 on connection 1 (native) (gdb) PASS: $exp: add-inferior [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". ... but sometimes I run into: ... (gdb) run & Starting program: attach-while-running (gdb) PASS: $exp: run & add-inferior [New inferior 2] Added inferior 2 on connection 1 (native) (gdb) [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". FAIL: $exp: add-inferior (timeout) ... Fix this by using -no-prompt-anchor. Tested on x86_64-linux.
2025-06-05gdb/solib: rename convenience variable to _linker_namespaceGuinevere Larsen2-5/+5
Based on feedback from IRC and PR solib/32959, this commit renames the recently introduced convenience variable $_current_linker_namespace to the shorter name $_linker_namespace. This makes it more in line with existing convenience variables such as $_thread and $_inferior, and faster to type. It should be ok to simply change the name because the variable was never released to the public, so there should be no existing scripts depending on the name. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32959 Reviewed-By: Eli Zaretskii <eliz@gnu.org> Approved-By: Andrew Burgess <aburgess@redhat.com> Approved-By: Tom Tromey <tom@tromey.com>
2025-06-05gdb/solib: Change type of convenience variable _current_linker_namespaceGuinevere Larsen1-3/+3
Based on IRC feedback since commit 6a0da68c036a85a46415aa0dada2421eee7c2269 gdb: add convenience variables around linker namespace debugging This commit changes the type of the _current_linker_namespace variable to be a simple integer. This makes it easier to use for expressions, like breakpoint conditions or printing from a specific namespace once that is supported, at the cost of making namespace IDs slightly less consistent. This is based on PR solib/32960, where no negative feedback was given for the suggestion. The commit also changes the usage of "linkage namespaces" to "linker namespaces" in the NEWS file, to reduce chance of confusion from an end user. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32960 Reviewed-By: Eli Zaretskii <eliz@gnu.org> Approved-By: Tom Tromey <tom@tromey.com>
2025-06-05[gdb/testsuite] Fix gdb.base/bp-permanent.exp with gcc 15Tom de Vries1-1/+1
With test-case gdb.base/bp-permanent.exp and gcc 15 I run into: ... gdb compile failed, bp-permanent.c: In function 'test_signal_nested': bp-permanent.c:118:20: error: passing argument 2 of 'signal' from \ incompatible pointer type [-Wincompatible-pointer-types] 118 | signal (SIGALRM, test_signal_nested_handler); | ^~~~~~~~~~~~~~~~~~~~~~~~~~ | | | void (*)(void) In file included from bp-permanent.c:20: /usr/include/signal.h:88:57: note: expected '__sighandler_t' \ {aka 'void (*)(int)'} but argument is of type 'void (*)(void)' ... Fix this by adding an int parameter to test_signal_nested_handler. Tested on x86_64-linux. PR testsuite/32756 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32756
2025-06-04gdb/python/guile: fix segfault from nested prefix command creationAndrew Burgess2-0/+56
A commit I recently pushed: commit 0b5023cc71d3af8b18e10e6599a3f9381bc15265 Date: Sat Apr 12 09:15:53 2025 +0100 gdb/python/guile: user created prefix commands get help list can trigger a segfault if a user tries to create nested prefix commands. For example, this will trigger a crash: (gdb) python gdb.ParameterPrefix("prefix-1", gdb.COMMAND_NONE) (gdb) python gdb.ParameterPrefix("prefix-1 prefix-2", gdb.COMMAND_NONE) Fatal signal: Segmentation fault ... etc ... If the user adds an actual parameter under 'prefix-1' before creating 'prefix-2', then everything is fine: (gdb) python gdb.ParameterPrefix("prefix-1", gdb.COMMAND_NONE) (gdb) python gdb.Parameter('prefix-1 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN) (gdb) python gdb.ParameterPrefix("prefix-1 prefix-2", gdb.COMMAND_NONE) The mistake in the above patch is in how gdbpy_parse_command_name is used. The BASE_LIST output argument from this function points to the list of commands for the prefix, not to the prefix command itself. So when gdbpy_parse_command_name is called for 'prefix-1 prefix-2', BASE_LIST points to the list of commands associated with 'prefix-1', not to the actual 'prefix-1' cmd_list_element. Back in cmdpy_init, from where gdbpy_parse_command_name was called, I was walking back from the first entry in BASE_LIST to figure out if this was a "show" prefix command or not. However, if BASE_LIST is empty then there is no first item, and this would trigger the segfault. The solution it to extend gdbpy_parse_command_name to also return the prefix cmd_list_element in addition to the existing values. With this done, and cmdpy_init updated, the segfault is now avoided. There's a new test that would trigger the crash without the patch. And, of course, the above commit also broke guile in the exact same way. And the fix is exactly the same. And there's a guile test too. NOTE: We should investigate possibly sharing some of this boiler plate helper code between Python and Guile. But not in this commit. Approved-By: Tom Tromey <tom@tromey.com>
2025-06-04[gdb/testsuite] Fix gdb.base/exec-invalid-sysroot.expTom de Vries1-0/+4
Since commit d462550c91c ("gdb/testsuite: also compile foll-exec.exp as C++"), we run into: ... Running gdb.base/exec-invalid-sysroot.exp ... gdb compile failed, foll-exec.c: In function 'main': foll-exec.c:35:52: error: 'EXECD_PROG' undeclared (first use in this function) printf ("foll-exec is about to execlp(%s)...\n", EXECD_PROG); ^~~~~~~~~~ foll-exec.c:35:52: note: each undeclared identifier is reported only once \ for each function it appears in ... Fix this by default-defining EXECD_PROG to "execd-prog". Tested on x86_64-linux.
2025-06-03gdb/testsuite: also compile foll-exec.exp as C++Andrew Burgess4-44/+122
For a long time, Fedora GDB has carried a test that performs some basic testing that GDB can handle 'catch exec' related commands for a C++ executable. The exact motivation for this test has been lost in the mists of time, but looking at the test script, the concern seems to be that GDB would have problems inserting C++ related internal breakpoints if a non C++ process is execd from a C++ one. There's no actual GDB fix associated with the Fedora test. This usually means that the issue was fixed upstream long ago. This patch does seem to date from around 2010ish (or maybe earlier). Having a look through the upstream tests, I cannot see anything that covers this sort of thing (C++ to C exec calls), and I figure it cannot hurt to have some additional testing in this area, and so I wrote this patch. I've taken the existing foll-exec.exp test, which compiles a C executable and then execs a different C executable, and split it into two copies. We now have foll-exec-c.exp and foll-exec-c++.exp. These tests compile a C and C++ executable respectively. Then within each of these scripts both a C and C++ helper application is built, which can then be execd from the main test executable. And so, we now cover 4 cases, the initial executable can be C or C++, and the execd process can be C or C++. As expected, everything passes. This is just increasing test coverage. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2025-06-03gdb/python/guile: user created prefix commands get help listAndrew Burgess4-11/+255
Consider GDB's builtin prefix set/show prefix sub-commands, if they are invoked with no sub-command name then they work like this: (gdb) show print print address: Printing of addresses is on. print array: Pretty formatting of arrays is off. print array-indexes: Printing of array indexes is off. print asm-demangle: Demangling of C++/ObjC names in disassembly listings is off. ... cut lots of lines ... (gdb) set print List of set print subcommands: set print address -- Set printing of addresses. set print array -- Set pretty formatting of arrays. set print array-indexes -- Set printing of array indexes. set print asm-demangle -- Set demangling of C++/ObjC names in disassembly listings. ... cut lots of lines ... Type "help set print" followed by set print subcommand name for full documentation. Type "apropos word" to search for commands related to "word". Type "apropos -v word" for full documentation of commands related to "word". Command name abbreviations are allowed if unambiguous. (gdb) That is 'show print' lists the values of all settings under the 'print' prefix, and 'set print' lists the help text for all settings under the 'set print' prefix. Now, if we try to create something similar using the Python API: (gdb) python gdb.ParameterPrefix("my-prefix", gdb.COMMAND_NONE) (gdb) python gdb.Parameter("my-prefix foo", gdb.COMMAND_OBSCURE, gdb.PARAM_BOOLEAN) (gdb) show my-prefix (gdb) set my-prefix Neither 'show my-prefix' or 'set my-prefix' gives us the same details relating to the sub-commands that we get with the builtin prefix commands. This commit aims to address this. Currently, in cmdpy_init, when a new command is created, we always set the commands callback function to cmdpy_function. It is within cmdpy_function that we spot that the command is a prefix command, and that there is no gdb.Command.invoke method, and so return early. This commit changes things so that the rules are now: 1. For NON prefix commands, we continue to use cmdpy_function. 2. For prefix commands that do have a gdb.Command.invoke method (i.e. can handle unknown sub-commands), continue to use cmdpy_function. 3. For all other prefix commands, don't use cmdpy_function, instead use GDB's normal callback function for set/show prefixes. This requires splitting the current call to add_prefix_cmd into either a call to add_prefix_cmd, add_show_prefix_cmd, or add_basic_prefix_cmd, as appropriate. After these changes, we now see this: (gdb) python gdb.ParameterPrefix("my-prefix", gdb.COMMAND_NONE) │ (gdb) python gdb.Parameter("my-prefix foo", gdb.COMMAND_OBSCURE, gdb.PARAM_BOOLEAN) (gdb) show my-prefix │ my-prefix foo: The current value of 'my-prefix foo' is "off". (gdb) set my-prefix List of "set my-prefix" subcommands: set my-prefix foo -- Set the current value of 'my-prefix foo'. Type "help set my-prefix" followed by subcommand name for full documentation. Type "apropos word" to search for commands related to "word". Type "apropos -v word" for full documentation of commands related to "word". Command name abbreviations are allowed if unambiguous. (gdb) Which matches how a prefix defined within GDB would act. I have made the same changes to the Guile API.
2025-06-03Clean up comment in dw2-ranges-psym-warning.expTom Tromey1-1/+1
This removes a trailing backslash from a comment in dw2-ranges-psym-warning.exp. This backslash causes Emacs to try to reindent the next line. This happens because comments are weird in Tcl -- they are not exactly syntactic and the backslash still acts as a line-continuation marker here.
2025-06-03Handle dynamic DW_AT_data_bit_offsetTom Tromey1-0/+95
In Ada, a field can have a dynamic bit offset in its enclosing record. In DWARF 3, this was handled using a dynamic DW_AT_data_member_location, combined with a DW_AT_bit_offset -- this combination worked out ok because in practice GNAT only needs a dynamic byte offset with a fixed offset within the byte. However, this approach was deprecated in DWARF 4 and then removed in DWARF 5. No replacement approach was given, meaning that in strict mode there is no way to express this. This is a DWARF bug, see https://dwarfstd.org/issues/250501.1.html In a discussion on the DWARF mailing list, a couple people mentioned that compilers could use the obvious extension of a dynamic DW_AT_data_bit_offset. I've implemented this for LLVM: https://github.com/llvm/llvm-project/pull/141106 In preparation for that landing, this patch implements support for this construct in gdb. New in v2: renamed some constants and added a helper method, per Simon's review. New in v3: more renamings. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2025-06-03gdb: support zero inode in generate-core-file commandAndrew Burgess3-0/+813
It is possible, when creating a shared memory segment (i.e. with shmget), that the id of the segment will be zero. When looking at the segment in /proc/PID/smaps, the inode field of the entry holds the shared memory segment id. And so, it can be the case that an entry (in the smaps file) will have an inode of zero. When GDB generates a core file, with the generate-core-file (or its gcore alias) command, the shared memory segment should be written into the core file. Fedora GDB has, since 2008, carried a patch that tests this case. There is no fix for GDB associated with the test, and unfortunately, the motivation for the test has been lost to the mists of time. This likely means that a fix was merged upstream without a suitable test, but I've not been able to find and relevant commit. The test seems to be checking that the shared memory segment with id zero, is being written to the core file. While looking at this test and trying to work out if it should be posted upstream, I saw that GDB does appear to write the shared memory segment into the core file (as expected), which is good. However, GDB still isn't getting this case exactly right, there appears to be no NT_FILE entry for the shared memory mapping if the mapping had an id of zero. In gcore_memory_sections (gcore.c) we call back into linux-tdep.c (via the gdbarch_find_memory_regions call) to correctly write the shared memory segment into the core file, however, in linux_make_mappings_corefile_notes, when we use linux_find_memory_regions_full to create the NT_FILE note, we call back in to dump_note_entry_p for each mapping, and in here we reject any mapping with a zero inode. The result of this, is that, for a shared memory segment with a non-zero id, after loading the core file, the shared memory segment will appear in the 'proc info mappings' output. But, for a shared memory segment with a zero id, the segment will not appear in the 'proc info mappings' output. I initially tried just dropping the inode check in this function (see previous commit 1e21c846c27, which I then reverted in commit 998165ba99a. The problem with dropping the inode check is that the special kernel mappings, e.g. '[vvar]' would now get a NT_FILE entry. In fact, any special entry except '[vdso]' and '[vsyscall]' which are specifically checked for in dump_note_entry_p would get a NT_FILE entry, which is not correct. So, instead, I propose that if the inode is zero, and the filename starts with '[' and finished with ']' then we should not create a NT_FILE entry. But otherwise a zero inode should not prevent a NT_FILE entry being created. The test for this change is a bit tricky. The original Fedora test (mentioned above) has a loop that tries to grab the shared memory mapping with id zero. This was, unfortunately, not very reliable. I tried to make this more reliable by going multi-threaded, and waiting for longer, see my proposal here: https://inbox.sourceware.org/gdb-patches/0d389b435cbb0924335adbc9eba6cf30b4a2c4ee.1741776651.git.aburgess@redhat.com But this was still not great. On further testing this was only passing (i.e. managing to find the shared memory mapping with id zero) about 60% of the time. However, I realised that GDB finds the shared memory id by reading the /proc/PID/smaps file. But we don't really _need_ the shared memory id for anything, we just use the value (as an inode) to decide if the segment should be included in the core file or not. The id isn't even written to the core file. So, if we could intercept the read of the smaps file, then maybe, we could lie to GDB, and tell it that the id was zero, and then see how GDB handles this. And luckily, we can do that using a preload library! We already have a test that uses a preload library to modify GDB, see gdb.threads/attach-slow-waitpid.exp. So, I have created a new preload library. This one intercepts open, open64, close, read, and pread. When GDB attempts to open /proc/PID/smaps, the library spots this and loads the file contents into a memory buffer. The buffer is then modified to change the id of any shared memory mapping to zero. Any reads from this file are served from the modified memory buffer. I tested on x86-64, AArch64, PPC, s390, and ARM, all running various versions of GNU/Linux. The requirement for open64() came from my ARM testing. The other targets used plain open(). And so, the test is now simple. Start GDB with the preload library in place, start the inferior and generate a core file. Then restart GDB, load the core file, and check the shared memory mapping was included. This test will fail with an unpatched GDB, and succeed with the patch applied. Tested-By: Guinevere Larsen <guinevere@redhat.com>
2025-06-03gdb: handle struct and union types in evaluate_subexp_for_address_basePiotr Rudnicki2-0/+20
Suppose a function returns a struct and a method of that struct is called. E.g.: struct S { int a; int get () { return a; } }; S f () { S s; s.a = 42; return s; } ... int z = f().get(); ... GDB is able to evaluate the expression: (gdb) print f().get() $1 = 42 However, type-checking the expression fails: (gdb) ptype f().get() Attempt to take address of value not located in memory. This happens because the `get` function takes an implicit `this` pointer, which in this case is the value returned by `f()`, and GDB wants to get an address for that value, as if passing the implicit this pointer. However, during type-checking, the struct value returned by `f()` is a `not_lval`. A similar issue exists for union types, where methods called on temporary union objects would fail type-checking in the same way. Address the problems by handling `TYPE_CODE_STRUCT` and `TYPE_CODE_UNION` in `evaluate_subexp_for_address_base`. With this change, for struct's method call, we get (gdb) ptype f().get() type = int Add new test cases to file gdb.cp/chained-calls.exp to test this change. Regression-tested in X86-64 Linux.
2025-06-02gdb: use quoted filename completion for the shell commandAndrew Burgess1-1/+26
With the quoted filename completion work that I did last year the deprecated_filename_completer function will now only complete a single word as a filename, for example: (gdb) save breakpoints /tm<TAB> The 'save breakpoints' command uses the deprecated_filename_completer completion function. In the above '/tm' will complete to '/tmp/' as expected. However, if you try this: (gdb) save breakpoints /tmp/ /tm<TAB> The second '/tm' will not complete for GDB 16.x, but will complete with GDB 15.x as GDB 15.x is before my changes were merged. What's actually happening here is that, before my changes, the filename completion was breaking words on white space, so in the above the first '/tmp/' and the second '/tm' are seen as separate words for completion, the second word is therefore seen as the start of a new filename. After my changes, deprecated_filename_completer allows spaces to be part of the filename, so in the above, GDB is actually trying to complete a filename '/tmp/ /tm' which likely doesn't exist, and so completion stops. This change for how deprecated_filename_completer works makes sense, commands like 'save breakpoints' take their complete command arguments and treat it as a single filename, so given this: (gdb) save breakpoints /tmp/ /tm<ENTER> GDB really will try to save breakpoints to a file called '/tmp/ /tm', weird as that may seem. How GDB interprets the command arguments didn't change with my completion patches, I simply brought completion into line with how GDB interprets the arguments. The patches I'm talking about here are this set: * 4076f962e8c gdb: split apart two different types of filename completion * dc22ab49e9b gdb: deprecated filename_completer and associated functions * 35036875913 gdb: improve escaping when completing filenames * 1d1df753977 gdb: move display of completion results into completion_result class * bbbfe4af4fb gdb: simplify completion_result::print_matches * 2bebc9ee270 gdb: add match formatter mechanism for 'complete' command output * f2f866c6ca8 gdb: apply escaping to filenames in 'complete' results * 8f87fcb1daf gdb: improve gdb_rl_find_completion_word for quoted words * 67b8e30af90 gdb: implement readline rl_directory_rewrite_hook callback * 1be3b2e82f7 gdb: extend completion of quoted filenames to work in brkchars phase * 9dedc2ac713 gdb: fix for completing a second filename for a command * 4339a3ffc39 gdb: fix filename completion in the middle of a line Bug PR gdb/32982 identifies a problem with the shell command; completion broke between 15.x and 16.x. The shell command also uses deprecated_filename_completer for completion. But consider a shell command line: (gdb) shell ls /tm<TAB> The arguments to the shell command are 'ls /tm' at the point <TAB> is pressed. Under the old 15.x completion GDB would split the words on white space and then try to complete '/tm' as a filename. Under the 16.x model, GDB completes all the arguments as a single filename, that is 'ls /tm', which is unlikely to match any filenames, and so completion fails. The fix is to write a custom completion function for the shell_command function (cli/cli-cmds.c), this custom completion function will skip forward to find the last word in the arguments, and then try to complete that, so in the above example, GDB will skip over 'ls ', and then tries to complete '/tm', which is exactly what we want. Given that the filenames passed to the shell command are forwarded to an actual shell, I have switched over the new quoted filename completion function for the shell command, this means that white space within a filename will be escaped with a backslash by the completion function, which is likely what the user wants, this means the filename will arrive in the (actual) shell as a single word, rather than splitting on white space and arriving as two words. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32982 Reviewed-By: Tom Tromey <tom@tromey.com>
2025-06-02Fix DAP defer_stop_events implementationTom Tromey1-2/+2
DAP requests have a "defer_stop_events" option that is intended to defer the emission of any "stopped" event until after the current request completes. This was needed to handle async continues like "finish &". However, I noticed that sometimes DAP tests can fail, because a stop event does arrive before the response to the "stepOut" request. I've only noticed this when the machine is fairly loaded -- for instance when I'm regression-testing a series, it may occur in some of the tests mid-series. I believe the problem is that the implementation in the "request" function is incorrect -- the flag is set when "request" is invoked, but instead it must be deferred until the request itself is run. That is, the setting must be captured in one of the wrapper functions. Following up on this, Simon pointed out that introducing a delay before sending a request's response will cause test case failures. That is, there's a race here that is normally hidden. Investigation showed that that deferred requests can't force event deferral. This patch implements this; but more testing showed many more race failures. Some of these are due to how the test suite is written. Anyway, in the end I took the radical approach of deferring all events by default. Most DAP requests are asynchronous by nature, so this seemed ok. The only case I found that really required this is pause.exp, where the test (rightly) expects to see a 'continued' event while performing an inferior function call. I went through all events and all requests and tried to convince myself that this patch will cause acceptable behavior in every case. However, it's hard to be completely sure about this approach. Maybe there are cases that do still need an event before the response, but we just don't have tests for them. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32685 Acked-By: Simon Marchi <simon.marchi@efficios.com>
2025-06-01[gdb/tdep] Fix gdb.ada/finish-var-size.exp on ppc64le-linuxTom de Vries1-1/+7
On openSUSE Tumbleweed ppc64le-linux using gcc 14.3.0, with a gdb 16.3 based package and test-case gdb.ada/finish-var-size.exp, I run into: ... (gdb) finish^M Run till exit from #0 pck.get (value=true) at pck.adb:19^M 0x0000000100004a20 in p () at finish-var-size/p.adb:18^M 18 V : Result_T := Get (True);^M Value returned is $1 = <error reading variable: \ Cannot access memory at address 0x0>^M (gdb) FAIL: gdb.ada/finish-var-size.exp: finish ... Function pck.get returns type Result_T: ... type Array_Type is array (1 .. 64) of Integer; type Maybe_Array (Defined : Boolean := False) is record Arr : Array_Type; Arr2 : Array_Type; end record; type Result_T (Defined : Boolean := False) is record case Defined is when False => Arr : Maybe_Array; when True => Payload : Boolean; end case; end record; ... and uses r3 as address of the return value, which means RETURN_VALUE_STRUCT_CONVENTION, but while executing finish_command we do: ... return_value = gdbarch_return_value_as_value (gdbarch, read_var_value (sm->function, nullptr, callee_frame), val_type, nullptr, nullptr, nullptr); ... and get: ... (gdb) p return_value $1 = RETURN_VALUE_REGISTER_CONVENTION ... This is caused by this check in ppc64_sysv_abi_return_value: ... /* In the ELFv2 ABI, aggregate types of up to 16 bytes are returned in registers r3:r4. */ if (tdep->elf_abi == POWERPC_ELF_V2 && valtype->length () <= 16 ... which succeeds because valtype->length () == 0. Fix this by also checking for !TYPE_HAS_DYNAMIC_LENGTH (valtype). [ I also tested a version of this patch using "!is_dynamic_type (valtype)" instead, but ran into a regression in test-case gdb.ada/variant-record.exp, because type T: ... Length : constant Positive := 8; subtype Name_T is String (1 .. Length); type A_Record_T is record X1 : Natural; X2 : Natural; end record; type Yes_No_T is (Yes, No); type T (Well : Yes_No_T := Yes) is record case Well is when Yes => Name : Name_T; when No => Unique_Name : A_Record_T; end case; end record; ... while being dynamic, also has a non-zero size, and is small enough to be returned in registers r3:r4. ] Fixing this causes the test-case to fail with the familiar: ... warning: Cannot determine the function return value. Try compiling with -fvar-tracking. ... and indeed using -fvar-tracking makes the test-case pass. Tested on ppc64le-linux. PR tdep/33000 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33000
2025-05-29Fix build when RUSAGE_THREAD is not available & add warningPedro Alves1-0/+34
Building current GDB on Cygwin, fails like so: /home/pedro/gdb/src/gdbsupport/run-time-clock.cc: In function ‘void get_run_time(user_cpu_time_clock::time_point&, system_cpu_time_clock::time_point&, run_time_scope ’: /home/pedro/gdb/src/gdbsupport/run-time-clock.cc:52:13: error: ‘RUSAGE_THREAD’ was not declared in this scope; did you mean ‘SIGEV_THREAD’? 52 | who = RUSAGE_THREAD; | ^~~~~~~~~~~~~ | SIGEV_THREAD Cygwin does not implement RUSAGE_THREAD. Googling around, I see Cygwin is not alone, other platforms don't support it either. For example, here is someone suggesting an alternative for darwin/macos: https://stackoverflow.com/questions/5652463/equivalent-to-rusage-thread-darwin Fix this by falling back to process scope if thread scope can't be supported. I chose this instead of returning zero usage or some other constant, because if gdb is built without threading support, then process-scope run time usage is the right info to return. But instead of falling back silently, print a warning (just once), like so: (gdb) maint set per-command time on ⚠️ warning: per-thread run time information not available on this platform ... so that developers on other platforms at least have a hint upfront. This new warning also shows on platforms that don't have getrusage in the first place, but does not show if the build doesn't support threading at all. New tests are added to gdb.base/maint.exp, to expect the warning, and also to ensure other "mt per-command" sub commands don't trigger the new warning. Change-Id: Ie01b916b62f87006f855e31594a5ac7cf09e4c02 Approved-By: Simon Marchi <simon.marchi@efficios.com> Approved-By: Tom Tromey <tom@tromey.com>
2025-05-26gdb/testsuite: Clarify -lbl option in gdb_test_multipleThiago Jung Bauermann1-1/+4
I was a bit confused about the -lbl option in gdb_test_multiple, and needed to read its implementation to determine that it would be useful for my needs. Explicitly mention what the option does and why it's useful to hopefully help other developers. Reviewed-By: Keith Seitz <keiths@redhat.com> Approved-By: Andrew Burgess <aburgess@redhat.com>
2025-05-26gdb/testsuite: Fix flakiness in gdb.base/default.expThiago Jung Bauermann1-60/+147
The Linaro CI runs the GDB testsuite using the read1 tool, which significantly increases the time it takes DejaGNU to read inferior output. On top of that sometimes the test machine has higher than normal load, which causes tests to run even slower. Because gdb.base/default.exp tests some verbose commands such as "info set", it sometimes times out while waiting for the complete command output when running in the Linaro CI environment. Fix this problem by consuming each line of output from the most verbose commands with gdb_test_multiple's -lbl (line-by-line) option — which causes DejaGNU to reset the timeout after each match — and also by breaking up regular expressions that try to match more than 2000 characters (the default Expect buffer size) in one go into multiple matches. Some tests use the same regular expression, so I created a procedure for them. This is the case for "i" / "info", "info set" / "show", and "set print" tests. The tests for "show print" don't actually test their output, so this patch improves them by checking some lines of the output. Reviewed-By: Keith Seitz <keiths@redhat.com> Approved-By: Andrew Burgess <aburgess@redhat.com>
2025-05-23[gdb/testsuite] Add gdb.dwarf2/fission-dw-form-strx.expTom de Vries3-8/+117
Add a dwarf assembly test-case using a DW_FORM_strx in a .dwo file. Tested on x86_64-linux. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2025-05-20[gdb/testsuite] Fix gdb.dwarf2/dw-form-strx-out-of-bounds.exp with ↵Tom de Vries3-1/+13
make-check-all.sh I forgot to run test-case gdb.dwarf2/dw-form-strx-out-of-bounds.exp with make-check-all.sh, and consequently failed to notice that it fails with for instance target board fission-dwp. The test-case does: ... source $srcdir/$subdir/dw-form-strx.exp.tcl ... and in that tcl file, prepare_for_testing fails, so a -1 is returned, but that is ignored by the source command. Fix this by using require, but rather that testing the result of the source command, communicate success by setting a global variable prepare_for_testing_done. Likewise in gdb.dwarf2/dw-form-strx.exp. Also, the test-case gdb.dwarf2/dw-form-strx-out-of-bounds.exp fails for target board readnow, because the DWARF error occurs during a different command than expected. Fix this by just skipping the test-case in that case. Tested on x86_64-linux. Reported-by: Simon Marchi <simark@simark.ca> Approved-By: Tom Tromey <tom@tromey.com>
2025-05-20[gdb/testsuite] Make gdb.debuginfod codespell-cleanTom de Vries3-4/+4
Make gdb.debuginfod codespell-clean and add the dir to the pre-commit configuration. Approved-By: Tom Tromey <tom@tromey.com>
2025-05-20[gdb/testsuite] Make gdb.guile codespell-cleanTom de Vries1-1/+1
Make gdb.guile codespell-clean and add the dir to the pre-commit configuration. Approved-By: Tom Tromey <tom@tromey.com>
2025-05-20[gdb/testsuite] Make gdb.mi codespell-cleanTom de Vries4-5/+5
Make gdb.mi codespell-clean and add the dir to the pre-commit configuration. Approved-By: Tom Tromey <tom@tromey.com>
2025-05-20[gdb/testsuite] Make gdb.opt codespell-cleanTom de Vries1-1/+1
Make gdb.opt codespell-clean and add the dir to the pre-commit configuration. Approved-By: Tom Tromey <tom@tromey.com>
2025-05-20[gdb/testsuite] Make gdb.pascal codespell-cleanTom de Vries1-1/+1
Make gdb.pascal codespell-clean and add the dir to the pre-commit configuration. Approved-By: Tom Tromey <tom@tromey.com>
2025-05-20[gdb/testsuite] Make gdb.reverse codespell-cleanTom de Vries3-3/+3
Make gdb.reverse codespell-clean and add the dir to the pre-commit configuration. Approved-By: Tom Tromey <tom@tromey.com>
2025-05-20[gdb/testsuite] Make gdb.rocm codespell-cleanTom de Vries1-1/+1
Make gdb.rocm codespell-clean and add the dir to the pre-commit configuration. Approved-By: Tom Tromey <tom@tromey.com>
2025-05-20[gdb/testsuite] Make gdb.stabs codespell-cleanTom de Vries1-1/+1
Make gdb.stabs codespell-clean and add the dir to the pre-commit configuration. Approved-By: Tom Tromey <tom@tromey.com>
2025-05-20[gdb/testsuite] Make gdb.xml codespell-cleanTom de Vries2-2/+2
Make gdb.xml codespell-clean and add the dir to the pre-commit configuration. Approved-By: Tom Tromey <tom@tromey.com>
2025-05-20[gdb/testsuite] Make gdb.tui codespell-cleanTom de Vries2-3/+3
Make gdb.tui codespell-clean and add the dir to the pre-commit configuration. Approved-By: Tom Tromey <tom@tromey.com>
2025-05-20[gdb/testsuite] Fix gdbsever typoTom de Vries2-2/+2
I noticed a typo in the testsuite, twice: gdbsever. Fix these. Codespell doesn't detect it, so add a new file gdb/contrib/codespell-dictionary.txt that contains a gdbsever->gdbserver entry, and update gdb/contrib/setup.cfg to use it. Approved-By: Tom Tromey <tom@tromey.com>
2025-05-15Fix regression with dynamic array boundsTom Tromey2-0/+118
Kévin discovered that commit ba005d32b0f ("Handle dynamic field properties") regressed a test in the internal AdaCore test suite. The problem here is that, when writing that patch, I did not consider the case where an array type's bounds might come from a member of a structure -- but where the array is not defined in the structure's scope. In this scenario the field-resolution logic would trip this condition: /* Defensive programming in case we see unusual DWARF. */ if (fi == nullptr) return nullptr; This patch reworks this area, partly backing out that commit, and fixes the problem. In the new code, I chose to simply duplicate the field's location information. This isn't totally ideal, in that it might result in multiple copies of a baton. However, this seemed nicer than tracking the DIE/field correspondence for every field in every CU -- my thinking here is that this particular dynamic scenario is relatively rare overall. Also, if the baton cost does prove onerous, we could intern the batons somewhere. Regression tested on x86-64 Fedora 41. I also tested this using the AdaCore internal test suite. Tested-By: Simon Marchi <simon.marchi@efficios.com>
2025-05-14testsuite: fix gdb_exit for MinGW targetRohr, Stephan1-1/+2
GDB is not properly exited via 'remote_close host' when running the testsuite in a MinGW environment. Use the 'quit' command to properly exit the GDB debugging session. Approved-By: Tom Tromey <tom@tromey.com>
2025-05-14testsuite: get windows PID on MinGW targetRohr, Stephan1-1/+1
Also translate the MinGW PID to the Windows PID when running on a MinGW target. Approved-By: Tom Tromey <tom@tromey.com>
2025-05-13gdb/python: new gdb.ParameterPrefix classAndrew Burgess1-0/+285
This commit adds a new gdb.ParameterPrefix class to GDB's Python API. When creating multiple gdb.Parameters, it is often desirable to group these together under a sub-command, for example, 'set print' has lots of parameters nested under it, like 'set print address', and 'set print symbol'. In the Python API the 'print' part of these commands are called prefix commands, and are created using gdb.Command objects. However, as parameters are set via the 'set ....' command list, and shown through the 'show ....' command list, creating a prefix for a parameter usually requires two prefix commands to be created, one for the 'set' command, and one for the 'show' command. This often leads to some duplication, or at the very least, each user will end up creating their own helper class to simplify creation of the two prefix commands. This commit adds a new gdb.ParameterPrefix class. Creating a single instance of this class will create both the 'set' and 'show' prefix commands, which can then be used while creating the gdb.Parameter. Here is an example of it in use: gdb.ParameterPrefix('my-prefix', gdb.COMMAND_NONE) This adds 'set my-prefix' and 'show my-prefix', both of which are prefix commands. The user can then add gdb.Parameter objects under these prefixes. The gdb.ParameterPrefix initialise method also supports documentation strings, so we can write: gdb.ParameterPrefix('my-prefix', gdb.COMMAND_NONE, "Configuration setting relating to my special extension.") which will set the documentation string for the prefix command. Also, it is possible to support prefix commands that use the `invoke` functionality to handle unknown sub-commands. This is done by sub-classing gdb.ParameterPrefix and overriding either 'invoke_set' or 'invoke_show' to handle the 'set' or 'show' prefix command respectively. Reviewed-By: Eli Zaretskii <eliz@gnu.org>
2025-05-13gdb/guile: generate general description string for parametersAndrew Burgess1-10/+45
This commit builds on the previous one, and auto-generates a general description string for parameters defined via the Guile API. This brings the Guile API closer inline with the Python API. It is worth reading the previous commit to see some motivating examples. This commit updates get_doc_string in guile/scm-param.c to allow for the generation of a general description string. Then in gdbscm_make_parameter, if '#:doc' was not given, get_doc_string is used to generate a suitable default. This does invalidate (and so the commit removes) this comment that was in gdbscm_make_parameter: /* If doc is NULL, leave it NULL. See add_setshow_cmd_full. */ First, Python already does exactly what I'm proposing here, and has done for a while, with no issues reported. And second, I've gone and read add_setshow_cmd_full, and some of the functions it calls, and can see no reasoning behind this comment... ... well, there is one reason that I can think of, but I'll discuss that more below. With this commit, if I define a parameter like this: (use-modules (gdb)) (register-parameter! (make-parameter "print test" #:command-class COMMAND_NONE #:parameter-type PARAM_BOOLEAN)) Then, in GDB, I now see this behaviour: (gdb) help show print test Show the current value of 'print test'. This command is not documented. (gdb) help set print test Set the current value of 'print test'. This command is not documented. (gdb) The two 'This command is not documented.' lines are new. This output is what we get from a similarly defined parameter using the Python API (see the previous commit for an example). I mentioned above that I can think of one reason for the (now deleted) comment in gdbscm_make_parameter about leaving the doc field as NULL, and that is this: consider the following GDB behaviour: (gdb) help show style filename foreground Show the foreground color for this property. (gdb) Notice there is only a single line of output. If I want to get the same behaviour from a parameter defined in Guile, I might try skipping the #:doc argument, but (after this commit), if I do that, GDB will auto-generate some text for me, giving two lines of output (see above). So, next, maybe I try setting #:doc to the empty string, but if I do that, then I get this: (use-modules (gdb)) (register-parameter! (make-parameter "print test" #:doc "" #:command-class COMMAND_NONE #:parameter-type PARAM_BOOLEAN)) (gdb) help show print test Show the current value of 'print test'. (gdb) Notice the blank line, that's not what I wanted. In fact, the only way to get rid of the second line is to leave the 'doc' variable as NULL in gdbscm_make_parameter, which, due to the new auto-generation, is no longer possible. This issue also existed in the Python API, and was addressed in commit: commit 4b68d4ac98aec7cb73a4b276ac7dd38d112786b4 Date: Fri Apr 11 23:45:51 2025 +0100 gdb/python: allow empty gdb.Parameter.__doc__ string After this commit, an empty __doc__ string for a gdb.Parameter is translated into a NULL pointer passed to the add_setshow_* command, which means the second line of output is completely skipped. And this commit includes the same solution for the Guile API. Now, with this commit, and the Guile parameter using an empty '#:doc' string, GDB has the following behaviour: (gdb) help show print test Show the current value of 'print test'. (gdb) This matches the output for a similarly defined parameter in Python.
2025-05-13gdb/guile: improve auto-generated strings for parametersAndrew Burgess1-8/+18
Consider this user defined parameter created in Python: class test_param(gdb.Parameter): def __init__(self, name): super ().__init__(name, gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN) self.value = True test_param('print test') If this is loaded into GDB, then we observe the following behaviour: (gdb) show print test The current value of 'print test' is "on". (gdb) help show print test Show the current value of 'print test'. This command is not documented. (gdb) help set print test Set the current value of 'print test'. This command is not documented. (gdb) If we now define the same parameter using Guile: (use-modules (gdb)) (register-parameter! (make-parameter "print test" #:command-class COMMAND_NONE #:parameter-type PARAM_BOOLEAN)) And load this into a fresh GDB session, we see the following: (gdb) show print test Command is not documented is off. (gdb) help show print test This command is not documented. (gdb) help set print test This command is not documented. (gdb) The output of 'show print test' doesn't make much sense, and is certainly worse than the Python equivalent. For both the 'help' commands it appears as if the first line is missing, but what is actually happening is that the first line has become 'This command is not documented.', and the second line is then missing. The problems can all be traced back to 'get_doc_string' in guile/scm-param.c. This is the guile version of this function. There is a similar function in python/py-param.c, however, the Python version returns one of three different strings depending on the use case. In contrast, the Guile version just returns 'This command is not documented.' in all cases. The three cases that the Python code handles are, the 'set' string, the 'show' string, and the general 'description' string. Right now the Guile get_doc_string only returns the general 'description' string, which is funny, because, in gdbscm_make_parameter, where get_doc_string is used, the one case that we currently don't need is the general 'description' string. Instead, right now, the general 'description' string is used for both the 'set' and 'show' cases. In this commit I plan to bring the Guile API a little more inline with the Python API. I will update get_doc_string (in scm-param.c) to return either a 'set' or 'show' string, and gdbscm_make_parameter will make use of these strings. The changes to the Guile get_doc_string are modelled on the Python version of this function. It is also worth checking out the next commit, which is related, and helps motivate how the changes have been implemented in this commit. After this commit, the same Guile parameter description shown above, now gives this behaviour: (gdb) show print test The current value of 'print test' is off. (gdb) help show print test Show the current value of 'print test'. (gdb) help set print test Set the current value of 'print test'. (gdb) The 'show print test' output now matches the Python behaviour, and is much more descriptive. The set and show 'help' output are now missing the second line when compared to the Python output, but the first line is now correct, and I think this is better than the previous Guile output. In the next commit I'll address the problem of the missing second line. Existing tests have been updated to expect the new output.
2025-05-13gdb/python: allow empty gdb.Parameter.__doc__ stringAndrew Burgess1-0/+87
I was recently attempting to create some parameters via the Python API. I wanted these parameters to appear similar to how GDB handles the existing 'style' parameters. Specifically, I was interested in this behaviour: (gdb) help show style filename foreground Show the foreground color for this property. (gdb) help set style filename foreground Set the foreground color for this property. (gdb) Notice how each 'help' command only gets a single line of output. I tried to reproduce this behaviour via the Python API and was unable. The problem is that, in order to get just a single line of output like this, the style parameters are registered with a call to add_setshow_color_cmd with the 'help_doc' being passed as nullptr. On the Python side, when parameters are created, the 'help_doc' is obtained with a call to get_doc_string (python/py-param.c). This function either returns the __doc__ string, or a default string: "This command is not documented.". To avoid returning the default we could try setting __doc__ to an empty string, but setting this field to any string means that GDB prints a line for that string, like this: class test_param(gdb.Parameter): __doc__ = "" def __init__(self, name): super ().__init__(name, gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN) self.value = True test_param('print test') Then in GDB: (gdb) help set print test Set the current value of 'print test'. (gdb) The blank line is the problem I'd like to solve. This commit makes a couple of changes to how parameter doc strings are handled. If the doc string is set to an empty string, then GDB now converts this to nullptr, which removes the blank line problem, the new behaviour in GDB (for the above `test_param`) is: (gdb) help set print test Set the current value of 'print test'. (gdb) Next, I noticed that if the set/show docs are set to empty strings, then the results are less than ideal: class test_param(gdb.Parameter): set_doc = "" def __init__(self, name): super ().__init__(name, gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN) self.value = True test_param('print test') And in GDB: (gdb) help set print test This command is not documented. (gdb) So, if the set/show docs are the empty string, GDB now forces these to be the default string instead, the new behaviour in GDB is: (gdb) help set print test Set the current value of 'print test'. This command is not documented. (gdb) I've added some additional asserts; the set/show docs should always be non-empty strings, which I believe is the case after this commit. And the 'doc' string returned from get_doc_string should never nullptr, but could be empty. There are new tests to cover all these changes.