aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite
AgeCommit message (Collapse)AuthorFilesLines
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>
2025-02-14gdb: only update m_last_subfile after writing a line table entryAndrew Burgess2-0/+261
While working on another patch which changes how we parse the line DWARF line tables I noticed what I think is a minor bug in how we process the line tables. What I noticed is that my new line table parser was adding more END markers into the parsed table than GDB's current approach. This difference was observed when processing the debug information for libstdc++. Here is the line table from the new test, this is a reasonable reproduction of the problem case that I observed in the actual debug line table: Contents of the .debug_line section: dw2-skipped-line-entries-1.c: File name Line number Starting address View Stmt dw2-skipped-line-entries-1.c 101 0x40110a x /tmp/dw2-skipped-line-entries-2.c: dw2-skipped-line-entries-2.c 201 0x401114 x /tmp/dw2-skipped-line-entries-3.c: dw2-skipped-line-entries-3.c 301 0x40111e x /tmp/dw2-skipped-line-entries-1.c: dw2-skipped-line-entries-1.c 102 0x401128 x dw2-skipped-line-entries-1.c 103 0x401128 x dw2-skipped-line-entries-1.c 104 0x401128 x /tmp/dw2-skipped-line-entries-2.c: dw2-skipped-line-entries-2.c 211 0x401128 /tmp/dw2-skipped-line-entries-3.c: dw2-skipped-line-entries-3.c 311 0x401132 /tmp/dw2-skipped-line-entries-1.c: dw2-skipped-line-entries-1.c 104 0x40113c dw2-skipped-line-entries-1.c 105 0x401146 x dw2-skipped-line-entries-1.c - 0x401150 The problem is caused by the entry for line 211. Notice that this entry is at the same address as the previous entries. Further, the entry for 211 is a non-statement entry, while the previous entries are statement entries. As the entry for line 211 is a non-statement entry, and the previous entries at that address are statement entries in a different symtab, it is thought that it is better to prefer the earlier entries (in dw2-skipped-line-entries-1.c), and so the entry for line 211 will be discarded. As GDB parses the line table it switches between the 3 symtabs (based on source filename) adding the relevant entries to each symtab. Additionally, as GDB switches symtabs, it adds an END entry to the previous symtab. The problem then is that, for the line 211 entry, this is the only entry in dw2-skipped-line-entries-2.c before we switch symtab again. But the line 211 entry is discarded. This means that GDB switches from dw2-skipped-line-entries-1.c to dw2-skipped-line-entries-2.c, and then on to dw2-skipped-line-entries-3.c without ever adding an entry to dw2-skipped-line-entries-2.c. And here then is the bug. GDB updates its idea of the previous symtab not when an entry is written into a symtab, but every time we change symtab. In this case, when we switch to dw2-skipped-line-entries-3.c we add the END marker to dw2-skipped-line-entries-2.c, even though no entries were written to dw2-skipped-line-entries-2.c. At the same time, no END marker is ever written into dw2-skipped-line-entries-1.c as the dw2-skipped-line-entries-2.c entry (for line 211) was discarded. Here is the 'maint info line-table' for dw2-skipped-line-entries-1.c before this patch: INDEX LINE REL-ADDRESS UNREL-ADDRESS IS-STMT PROLOGUE-END EPILOGUE-BEGIN 0 101 0x000000000040110a 0x000000000040110a Y 1 END 0x0000000000401114 0x0000000000401114 Y 2 102 0x0000000000401128 0x0000000000401128 Y 3 103 0x0000000000401128 0x0000000000401128 Y 4 104 0x0000000000401128 0x0000000000401128 Y 5 104 0x000000000040113c 0x000000000040113c 6 105 0x0000000000401146 0x0000000000401146 Y 7 END 0x0000000000401150 0x0000000000401150 Y And after this patch: INDEX LINE REL-ADDRESS UNREL-ADDRESS IS-STMT PROLOGUE-END EPILOGUE-BEGIN 0 101 0x000000000040110a 0x000000000040110a Y 1 END 0x0000000000401114 0x0000000000401114 Y 2 102 0x0000000000401128 0x0000000000401128 Y 3 103 0x0000000000401128 0x0000000000401128 Y 4 104 0x0000000000401128 0x0000000000401128 Y 5 END 0x0000000000401132 0x0000000000401132 Y 6 104 0x000000000040113c 0x000000000040113c 7 105 0x0000000000401146 0x0000000000401146 Y 8 END 0x0000000000401150 0x0000000000401150 Y Notice that we gained an extra entry, the END marker that was added at position #5 in the table. Now, does this matter? I cannot find any bugs that trigger because of this behaviour. So why fix it? First, the current behaviour is inconsistent, as we switch symtabs, we usually get an END marker in the previous symtab. But occasionally we don't. I don't like things that are inconsistent for no good reason. And second, as I said, I want to change the line table parsing. To do this I want to check that my new parser creates an identical table to the current parser. But my new parser naturally "fixes" this inconsistency, so I have two choices, do extra work to make my new parser bug-compatible with the current one, or fix the current one. I'd prefer to just fix the current line table parser. There's a test that includes the above example and checks that the END markers are put in the correct place. But as I said, I've not been able to trigger any negative behaviour from the current solution, so there's no test that exposes any broken behaviour. Approved-By: Tom Tromey <tom@tromey.com>
2025-02-13Remove assumption from py-symbol.expTom Tromey1-8/+12
The current py-symbol.exp test makes an assumption about which symbol will be returned first. I don't think gdb should really make promises about the order in which the symbols are listed, though, and a series I am working on changes this behavior. This patch changes the test to merely ensure that both symbols are returned. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2025-02-13gdb, testsuite: Rename set_sanitizer procedures to append_environment.Christina Schimpe6-16/+16
The procedures set_sanitizer_1, set_sanitizer and set_sanitizer_default are used for the configuration of ASAN specific environment variables. However, they are actually generic. Rename them to append_environment* so that their purpose is more clear. Approved-By: Tom Tromey <tom@tromey.com>
2025-02-12Reorder gnatmake arguments in inline-section-gc.exp, againTom Tromey1-3/+9
Tom de Vries pointed out that commit 8cfa1fc4 ("Reorder gnatmake arguments in inline-section-gc.exp") caused a regression with an older version of dejagnu. This patch works around that problem by further reordering the arguments to gnatmake and also arranging to leave gnatmake in "-margs" mode.
2025-02-12Add copyright header to gnat_debug_info_test.adbTom Tromey1-0/+15
I noticed that gdb/testsuite/lib/gnat_debug_info_test.adb is missing a copyright header. This adds one, using the date range from the original commit.
2025-02-10gdb/dwarf: create multiple cooked index shards when reading .debug_namesSimon Marchi1-4/+16
New in v2: - install address map in a single shard - update test gdb.mi/mi-sym-info.exp to cope with the fact that different symbols could be returned when using --max-results When playing with the .debug_names reader, I noticed it was significantly slower than the DWARF scanner. Using a "performance" build of GDB (with optimization, no runtime sanitizer enabled, etc), I measure with the following command on a rather large debug info file (~4 GB): $ time ./gdb -q -nx --data-directory=data-directory <binary> -iex 'maint set dwarf sync on' -batch This measures the time it takes for GDB to build the cooked index (plus some startup and exit overhead). I have a version of the binary without .debug_names and a version with .debug_names added using gdb-add-index. The results are: - without .debug_names: 7.5 seconds - with .debug_names: 24 seconds This is a bit embarrassing, given that the purpose of .debug_names is to accelerate things :). The reason is that the .debug_names processing is not parallelized at all, while the DWARF scanner is heavily parallelized. The process of creating the cooked index from .debug_names is roughly in two steps: 1. scanning of .debug_names and creation of cooked index entries (see mapped_debug_names_reader::scan_all_names) 2. finalization of the index, name canonicalization and sorting of the entries (see cooked_index::set_contents). This patch grabs a low hanging fruit by creating multiple cooked index shards instead of a single one during step one. Just doing this allows the second step of the processing to be automatically parallelized, as each shard is sent to a separate thread to be finalized. With this patch, I get: - without .debug_names: 7.5 seconds - with .debug_names: 9.7 seconds Not as fast as we'd like, but it's an improvement. The process of scanning .debug_names could also be parallelized to shave off a few seconds. My profiling shows that out of those ~10 seconds of excecution, about 6 are inside scan_all_names. Assuming perfect parallelization with 8 threads, it means that at best we could shave about 5 seconds from that time, which sounds interesting. I gave it a shot, but it's a much more intrusive change, I'm not sure if I will finish it. This patch caused some regressions in gdb.mi/mi-sym-info.exp with the cc-with-debug-names board, in the test about the `--max-results` switch. It appears at this test is relying on the specific symbols returned when using `--max-results`. As far as I know, we don't guarantee which specific symbols are returned, so any of the matching symbols could be returned. The round robin method used in this patch to assign index entries to shards ends up somewhat randomizing which CU gets expanded first during the symbol search, and therefore which order they appear in the objfile's CU list, and therefore which one gets searched first. I meditated on whether keeping compunits sorted within objfiles would help make things more stable and predictable. It would somewhat, but it wouldn't remove all sources of randomness. It would still possible for a call to `expand_symtabs_matching` to stop on the first hit. Which compunit gets expanded then would still be dependent on the specific `quick_symbol_functions` internal details / implementation. Commit 5b99c5718f1c ("[gdb/testsuite] Fix various issues in gdb.mi/mi-sym-info.exp") had already started to make the test a bit more flexible in terms of which symbols it accepts, but with this patch, I think it's possible to get wildly varying results. I therefore modified the test to count the number of returned symbols, but not expect any specific symbol. Change-Id: Ifd39deb437781f72d224ec66daf6118830042941 Approved-By: Tom Tromey <tom@tromey.com>
2025-02-10gdb: fix selecting tail-call frames by nameAndrew Burgess2-0/+58
I noticed that attempting to select a tail-call frame using 'frame function NAME' wouldn't work: (gdb) bt #0 func_that_never_returns () at /tmp/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/frame-selection.c:49 #1 0x0000000000401183 in func_that_tail_calls () at /tmp/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/frame-selection.c:59 #2 0x00000000004011a5 in main () at /tmp/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/frame-selection.c:70 (gdb) frame function func_that_tail_calls No frame for function "func_that_tail_calls". (gdb) up #1 0x0000000000401183 in func_that_tail_calls () at /tmp/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/frame-selection.c:59 59 func_that_never_returns (); (gdb) disassemble Dump of assembler code for function func_that_tail_calls: 0x000000000040117a <+0>: push %rbp 0x000000000040117b <+1>: mov %rsp,%rbp 0x000000000040117e <+4>: call 0x40116c <func_that_never_returns> End of assembler dump. (gdb) The problem is that the 'function' mechanism uses get_frame_pc() and then compares the address returned with the bounds of the function we're looking for. So in this case, the bounds of func_that_tail_calls are 0x40117a to 0x401183, with 0x401183 being the first address _after_ the function. However, because func_that_tail_calls ends in a tail call, then the get_frame_pc() is 0x401183, the first address after the function. As a result, GDB fails to realise that frame #1 is inside the function we're looking for, and the lookup fails. The fix is to use get_frame_address_in_block, which will return an adjusted address, in this case, 0x401182, which is within the function bounds. Now the lookup works: (gdb) frame function func_that_tail_calls #1 0x0000000000401183 in func_that_tail_calls () at /tmp/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/frame-selection.c:59 59 func_that_never_returns (); (gdb) I've extended the gdb.base/frame-selection.exp test to cover this case.
2025-02-09gdb/testsuite: avoid incorrect symbols in gdb.base/condbreak-multi-context.ccAndrew Burgess2-72/+165
In a different series I tweak how disabled_by_cond is handled in update_breakpoint_locations for code_breakpoint objects, see: https://inbox.sourceware.org/gdb-patches/cover.1734366277.git.aburgess@redhat.com But when I did this I ran into a regression in the test script gdb.base/condbreak-multi-context.cc which I think is actually an issue with this test. The test relies on creating a multi-location breakpoint with a condition and having GDB disable some of the locations as the condition is only valid in some of the locations. Here's an example of the test creating one such breakpoint: Reading symbols from /tmp/build/gdb/testsuite/outputs/gdb.base/condbreak-multi-context/condbreak-multi-context... (gdb) break func if a == 10 warning: failed to validate condition at location 1, disabling: No symbol "a" in current context. warning: failed to validate condition at location 3, disabling: No symbol "a" in current context. Breakpoint 1 at 0x401142: func. (3 locations) (gdb) info breakpoints Num Type Disp Enb Address What 1 breakpoint keep y <MULTIPLE> stop only if a == 10 1.1 N* 0x0000000000401142 in Base::func() at /tmp/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/condbreak-multi-context.cc:23 1.2 y 0x000000000040114e in A::func() at /tmp/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/condbreak-multi-context.cc:31 1.3 N* 0x000000000040115a in C::func() at /tmp/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/condbreak-multi-context.cc:39 (*): Breakpoint condition is invalid at this location. (gdb) Notice that only location 1.2 is actually enabled, 1.1 and 1.3 are disabled due to the condition 'a == 10' not being valid. However, notice that this b/p is created before GDB has started the inferior. What I noticed is that if I first start the inferior then I get a different behaviour: Reading symbols from /tmp/build/gdb/testsuite/outputs/gdb.base/condbreak-multi-context/condbreak-multi-context... (gdb) start Temporary breakpoint 1 at 0x40110e: file /tmp/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/condbreak-multi-context.cc, line 49. Starting program: /tmp/build/gdb/testsuite/outputs/gdb.base/condbreak-multi-context/condbreak-multi-context Temporary breakpoint 1, main () at /tmp/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/condbreak-multi-context.cc:49 49 aobj.func (); (gdb) break func if a == 10 Breakpoint 2 at 0x401142: func. (3 locations) (gdb) info breakpoints Num Type Disp Enb Address What 2 breakpoint keep y <MULTIPLE> stop only if a == 10 2.1 y 0x0000000000401142 in Base::func() at /tmp/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/condbreak-multi-context.cc:23 2.2 y 0x000000000040114e in A::func() at /tmp/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/condbreak-multi-context.cc:31 2.3 y 0x000000000040115a in C::func() at /tmp/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/condbreak-multi-context.cc:39 (gdb) Notice that now all three locations are valid. What's actually happening is that, on my machine libm.so contains a global symbol 'a' which for 2.1 and 2.3 is being used to satisfy the condition. I don't believe this is actually the intention of the test, this is just an unfortunate consequence of name collision. The test actually relies on the local variables 'a' and 'c', and my libm.so contains a global version of both. So I propose that we just update the test, I've gone for the super inventive 'aaa' and 'ccc'. With this change, after starting the inferior I now see the expected behaviour where only one of the three locations is enabled. However, while I'm fixing this I figure that it would be nice if the test checked both cases, creating the breakpoints before starting the inferior, and after starting the inferior. So I've updated the test to check both cases. This has meant converting the mostly linear test script into a set of parameterised functions which I then call with a flag to indicate if the inferior should be started before of after creating the breakpoints. Approved-By: Tom Tromey <tom@tromey.com> Tested-By: Hannes Domani <ssbssa@yahoo.de>
2025-02-09gdb/mi: include ranges in =library-unloaded eventAndrew Burgess1-1/+14
Having looked at the dlmopen support in GDB, it occurred to me that the current MI =library-unloaded event doesn't incude enough information to be useful. Consider the gdb.mi/mi-dlmopen.exp test, this test loads libraries into multiple linker namespaces, and then unloads these libraries. We should probably figure out a way to include the linker namepsace ID in GDB's output, e.g. in the =library-loaded and =library-unloaded MI events, and in the output of 'info sharedlibrary'. But this commit is not about doing that. This commit includes the 'ranges' information in the =library-unloaded event output. This is the same ranges information as is included in the =library-loaded output. Even without the linker namespace ID, this should allow MI consumers to figure out which library instance is being unloaded. Here is the 'info sharedlibrary' output for mi-dlmopen.exp at the point where all the shared libraries are loaded: info sharedlibrary &"info sharedlibrary\n" ~"From To Syms Read Shared Object Library\n" ~"0x00007ffff7fca000 0x00007ffff7ff03f5 Yes /lib64/ld-linux-x86-64.so.2\n" ~"0x00007ffff7eda3d0 0x00007ffff7f4e898 Yes /lib64/libm.so.6\n" ~"0x00007ffff7d0e800 0x00007ffff7e6dccd Yes /lib64/libc.so.6\n" ~"0x00007ffff7fbd040 0x00007ffff7fbd116 Yes /tmp/build/gdb/testsuite/outputs/gdb.mi/mi-dlmopen/dlmopen-lib.1.so\n" ~"0x00007ffff7fb8040 0x00007ffff7fb80f9 Yes /tmp/build/gdb/testsuite/outputs/gdb.mi/mi-dlmopen/dlmopen-lib-dep.so\n" ~"0x00007ffff7bfe3d0 0x00007ffff7c72898 Yes /lib64/libm.so.6\n" ~"0x00007ffff7a32800 0x00007ffff7b91ccd Yes /lib64/libc.so.6\n" ~"0x00007ffff7fca000 0x00007ffff7ff03f5 Yes /lib64/ld-linux-x86-64.so.2\n" ~"0x00007ffff7fb3040 0x00007ffff7fb3116 Yes /tmp/build/gdb/testsuite/outputs/gdb.mi/mi-dlmopen/dlmopen-lib.1.so\n" ~"0x00007ffff7fae040 0x00007ffff7fae0f9 Yes /tmp/build/gdb/testsuite/outputs/gdb.mi/mi-dlmopen/dlmopen-lib-dep.so\n" ~"0x00007ffff7ce1040 0x00007ffff7ce1116 Yes /tmp/build/gdb/testsuite/outputs/gdb.mi/mi-dlmopen/dlmopen-lib.1.so\n" ~"0x00007ffff7cdc040 0x00007ffff7cdc0f9 Yes /tmp/build/gdb/testsuite/outputs/gdb.mi/mi-dlmopen/dlmopen-lib-dep.so\n" ~"0x00007ffff79253d0 0x00007ffff7999898 Yes /lib64/libm.so.6\n" ~"0x00007ffff7759800 0x00007ffff78b8ccd Yes /lib64/libc.so.6\n" ~"0x00007ffff7fca000 0x00007ffff7ff03f5 Yes /lib64/ld-linux-x86-64.so.2\n" ~"0x00007ffff7cd7040 0x00007ffff7cd7116 Yes /tmp/build/gdb/testsuite/outputs/gdb.mi/mi-dlmopen/dlmopen-lib.2.so\n" ^done (gdb) Notice that dlmopen-lib.1.so is loaded multiple times. Here is the =library-unloaded event when one copy of this library is unloaded before this patch: =library-unloaded,id="/tmp/build/gdb/testsuite/outputs/gdb.mi/mi-dlmopen/dlmopen-lib.1.so", target-name="/tmp/build/gdb/testsuite/outputs/gdb.mi/mi-dlmopen/dlmopen-lib.1.so", host-name="/tmp/build/gdb/testsuite/outputs/gdb.mi/mi-dlmopen/dlmopen-lib.1.so", thread-group="i1", It is not possible, given this information, to know which copy of dlmopen-lib.1.so has actually been unloaded. An MI consumer would need to query the full shared library list and update from that information. After this patch the new output is: =library-unloaded,id="/tmp/build/gdb/testsuite/outputs/gdb.mi/mi-dlmopen/dlmopen-lib.1.so", target-name="/tmp/build/gdb/testsuite/outputs/gdb.mi/mi-dlmopen/dlmopen-lib.1.so", host-name="/tmp/build/gdb/testsuite/outputs/gdb.mi/mi-dlmopen/dlmopen-lib.1.so", thread-group="i1", ranges=[{from="0x00007ffff7fbd040",to="0x00007ffff7fbd116"}], still-in-use="false" The new 'ranges' field allows an MI consumer to uniquely identify which library instance was just unmapped. A frontent could, e.g. update a library list with no need to query the full shared library list. To include the 'ranges' field I updated mi_interp::on_solib_unloaded to call a new helper function. The new helper function is split out from the existing mi_output_solib_attribs. I was tempted to just call mi_output_solib_attribs, but doing so would mean that the 'symbols-loaded' field was also added to the =library-unloaded event, however, the docs for 'symbols-unloaded' on =library-loaded says: The @var{symbols-loaded} field is emitted only for backward compatibility and should not be relied on to convey any useful information. And it seemed silly to add a fields to =library-unloaded, which I would then document as something that should be ignored. The new helper function means I can avoid emitting the 'symbols-loaded' field. I have also added a 'still-in-use' field. When true this indicates that the library was removed from the inferior's library list, but the mapping was not removed from the inferior's address space as there is another copy of the library that is still using the library. In the above list, notice that ld-linux-x86-64.so.2 appears 3 times, but each instance is mapped as 0x00007ffff7fca000. When one copy of ld-linux-x86-64.so.2 is unloaded, here's the event: =library-unloaded,id="/lib64/ld-linux-x86-64.so.2", target-name="/lib64/ld-linux-x86-64.so.2", host-name="/lib64/ld-linux-x86-64.so.2", thread-group="i1", ranges=[{from="0x00007ffff7fca000",to="0x00007ffff7ff03f5"}], still-in-use="true" The 'still-in-use' field is 'true', this indicates there are at least one instance of this library remaining mapped at 0x00007ffff7fca000. Reviewed-By: Eli Zaretskii <eliz@gnu.org>
2025-02-09gdb: include a still-mapped flag in solib unload notificationAndrew Burgess7-33/+517
Consider the gdb.base/dlmopen.exp test case. The executable in this test uses dlmopen to load libraries into multiple linker namespaces. When a library is loaded into a separate namespace, its dependencies are also loaded into that namespace. This means that an inferior can have multiple copies of some libraries, including the dynamic linker, loaded at once. However, glibc optimises at least the dynamic linker case. Though the library appears to be mapped multiple times (it is in the inferior's solib list multiple times), there is really only one copy mapped into the inferior's address space. Here is the 'info sharedlibrary' output on an x86-64/Linux machine once all the libraries are loaded: (gdb) info sharedlibrary From To Syms Read Shared Object Library 0x00007ffff7fca000 0x00007ffff7ff03f5 Yes /lib64/ld-linux-x86-64.so.2 0x00007ffff7eda3d0 0x00007ffff7f4e898 Yes /lib64/libm.so.6 0x00007ffff7d0e800 0x00007ffff7e6dccd Yes /lib64/libc.so.6 0x00007ffff7fbd040 0x00007ffff7fbd116 Yes /tmp/build/gdb/testsuite/outputs/gdb.base/dlmopen/dlmopen-lib.1.so 0x00007ffff7fb8040 0x00007ffff7fb80f9 Yes /tmp/build/gdb/testsuite/outputs/gdb.base/dlmopen/dlmopen-lib-dep.so 0x00007ffff7bfe3d0 0x00007ffff7c72898 Yes /lib64/libm.so.6 0x00007ffff7a32800 0x00007ffff7b91ccd Yes /lib64/libc.so.6 0x00007ffff7fca000 0x00007ffff7ff03f5 Yes /lib64/ld-linux-x86-64.so.2 0x00007ffff7fb3040 0x00007ffff7fb3116 Yes /tmp/build/gdb/testsuite/outputs/gdb.base/dlmopen/dlmopen-lib.1.so 0x00007ffff7fae040 0x00007ffff7fae0f9 Yes /tmp/build/gdb/testsuite/outputs/gdb.base/dlmopen/dlmopen-lib-dep.so 0x00007ffff7ce1040 0x00007ffff7ce1116 Yes /tmp/build/gdb/testsuite/outputs/gdb.base/dlmopen/dlmopen-lib.1.so 0x00007ffff7cdc040 0x00007ffff7cdc0f9 Yes /tmp/build/gdb/testsuite/outputs/gdb.base/dlmopen/dlmopen-lib-dep.so 0x00007ffff79253d0 0x00007ffff7999898 Yes /lib64/libm.so.6 0x00007ffff7759800 0x00007ffff78b8ccd Yes /lib64/libc.so.6 0x00007ffff7fca000 0x00007ffff7ff03f5 Yes /lib64/ld-linux-x86-64.so.2 0x00007ffff7cd7040 0x00007ffff7cd7116 Yes /tmp/build/gdb/testsuite/outputs/gdb.base/dlmopen/dlmopen-lib.2.so Notice that every copy of /lib64/ld-linux-x86-64.so.2 is mapped at the same address. As the inferior closes the libraries that it loaded, the various copies of the dynamic linker will also be unloaded. Currently, when this happens GDB calls notify_solib_unloaded, which triggers the gdb::observers::solib_unloaded observer. This observer will call disable_breakpoints_in_unloaded_shlib (in breakpoint.c), which disables any breakpoints in the unloaded solib. The problem with this, is that, when the dynamic linker (or any solib) is only really mapped once as is the case here, we only want to disable breakpoints in the library when the last instance of the library is unloaded. The first idea that comes to mind is that GDB should not emit the solib_unloaded notification if a shared library is still in use, however, this could break MI consumers. Currently, every time a copy of ld-linux-x86-64.so.2 is unloaded, GDB's MI interpreter will emit a =library-unloaded event. An MI consumer might use this to update the library list that it displays to the user, and fewer notify_solib_unloaded calls will mean fewer MI events, which will mean the MI consumer's library list could get out of sync with GDB. Instead I propose that we extend GDB's solib_unloaded event to add a new flag. The new flag indicates if the library mapping is still in use within the inferior. Now the MI will continue to emit the expected =library-unloaded events, but disable_breakpoints_in_unloaded_shlib can check the new flag, when it is true (indicating that the library is still mapped into the inferior), no breakpoints should be disabled. The other user of the solib_unloaded observer, in bsd-uthread.c, should, I think, do nothing if the mapping is still in use. This observer is also disabling breakpoints when a library is unloaded. Most of the changes in this commit relate to passing the new flag around for the event. The interesting changes are mostly in solib.c, where the flag value is determined, and in breakpoint.c and bsd-uthread.c, where the flag value is read. There's a new MI test, the source of which is mostly copied from the gdb.base/dlmopen.exp test. This new test is checking we see all the expected =library-unloaded events.
2025-02-09gdb/testsuite: restructure gdb.base/dlmopen.expAndrew Burgess1-32/+49
In the next commit I want to add more tests to the dlmopen.exp script. Doing this will be easier if the dlmopen.exp script was structured so that the current tests were contained inside separatate procs. So this commit moves all of the current tests within dlmopen into two procs, and then calls these. There should be no changes to what is actually being tested in this commit.
2025-02-09gdb: Support some escaping of args with startup-with-shell being offMichael Weghorn3-70/+248
I (Andrew Burgess) have taken this patch from this series: https://inbox.sourceware.org/gdb-patches/20211022071933.3478427-1-m.weghorn@posteo.de/ I started off reviewing that series, but wanted to explore some alternative strategies for solving the problems this series addresses. However, this patch I think is super useful, so I've taken it mostly as it was in the original series. I have made a few minor cleanups, and I've also added some more tests. Any bugs should be considered mine (Andrew's), but I've left the original author (Michael Weghorn) in place as the GDB side changes are mostly their work. The function execv_argv::init_for_no_shell (gdb/nat/fork-inferior.c), is passed a single string ALLARGS containing all of the inferior arguments, and contains some custom code for splitting this argument string into a vector of separate arguments. This function is used when startup-with-shell is off (which is not the default). The algorithm in this function was just splitting on whitespace characters, and ignoring any quoting, so for example: (gdb) set startup-with-shell off (gdb) set args "first arg" second_arg would result in three arguments ("first), (arg"), and (second_arg) being passed to the inferior (the parenthesis are not part of the parsed arguments). This commit replaces this custom argument splitting with a use of the existing gdb_argv class (which uses the libiberty buildargv function). This does a better job of supporting quoting and escaping, so for the example given above we now pass two arguments (first arg) and (second_arg), which is certainly what I would have expected as a GDB user. This commit changes the 'execv_argv' class accordingly and drops the optimization to have all the 'char *' in 'm_argv' point to a single string rather than allocating a separate string for each arg. This is needed because we are now going to be stripping some escaping from the arguments, for example: (gdb) set startup-with-shell off (gdb) set args "literal \$" In this case we will pass the single argument (literal $) to the inferior, the escaping backslash will be removed. This might seem strange as usually the backslash would be stripped by the shell, and now we have no shell. However, I think the consistent behaviour is a good thing; whether we start with a shell or not the escaping will be removed. Using gdb_argv will mean that quote characters are also stripped. If we consider the first example again: (gdb) set startup-with-shell off (gdb) set args "first arg" second_arg This is now going to pass (first arg) and (second_arg), the quotes have been removed. If the user did want the original behaviour then they are going to have to now do this: (gdb) set startup-with-shell off (gdb) set args \"first arg\" second_arg or they could do this: (gdb) set startup-with-shell off (gdb) set args '"first' 'arg"' second_arg This commit also extends the three tests that cover inferior argument passing to cover the case where 'startup-with-shell' is off. All of these new tests pass for native targets, but there are still problems when using remote targets. The remote target problems arise because of how escaping is handled while passing arguments to remote targets. I have a larger series that aims to address this issue: https://inbox.sourceware.org/gdb-patches/cover.1730731085.git.aburgess@redhat.com This patch was originally part of that series, but getting a 14 patch series reviewed is not easy, so I've pulled this patch out on its own for now, and the new tests are (rather crudely) disabled for remote targets. My hope is to work through my 14 patch series posting all of the patches in smaller groups, which will hopefully make reviewing easier. As more of that series gets merged, the remote argument handling will improve, before, eventually, no tests will need to be disabled. Co-Authored-By: Andrew Burgess <aburgess@redhat.com> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28392 Tested-By: Guinevere Larsen <guinevere@redhat.com> Reviewed-By: Keith Seitz <keiths@redhat.com>
2025-02-08gdb/tui: use wrefresh if output is not surpressedAndrew Burgess2-0/+120
Recent work in the TUI has improved GDB's use of the curses wnoutrefresh and doupdate mechanism, which improves performance by batching together updates and then doing a single set of writes to the screen when doupdate is finally called. The tui_batch_rendering type is a RAII class which, in its destructor, calls doupdate to send the batched updates to the screen. However, if there is no tui_batch_rendering active on the call stack then any wnoutrefresh calls will remain batched but undisplayed until the next time doupdate happens to be called. This problem can be seen in PR gdb/32623. When an inferior is started the 'Starting program' message is not immediately displayed to the user. The 'Starting program' message originates from run_command_1 in infcmd.c, the message is sent to the current_uiout, which will be the TUI ui_out. After the message is sent, ui_out::flush() is called, here's the backtrace when that happens: #0 tui_file::flush (this=0x36e4ab0) at ../../src/gdb/tui/tui-file.c:42 #1 0x0000000001004f4b in pager_file::flush (this=0x36d35f0) at ../../src/gdb/utils.c:1531 #2 0x0000000001004f71 in gdb_flush (stream=0x36d35f0) at ../../src/gdb/utils.c:1539 #3 0x00000000006975ab in cli_ui_out::do_flush (this=0x35a50b0) at ../../src/gdb/cli-out.c:250 #4 0x00000000009fd1f9 in ui_out::flush (this=0x35a50b0) at ../../src/gdb/ui-out.h:263 #5 0x00000000009f56ad in run_command_1 (args=0x0, from_tty=1, run_how=RUN_NORMAL) at ../../src/gdb/infcmd.c:449 #6 0x00000000009f599a in run_command (args=0x0, from_tty=1) at ../../src/gdb/infcmd.c:511 And if we check out tui_file::flush (tui-file.c) we can see that this just calls tui_win_info::refresh_window(), which in turn, just uses wnoutrefresh to batch any pending output. The problem is that, in the above backtrace, there is no tui_batch_rendering active, and so there will be no doupdate call to flush the output to the screen. We could add a tui_batch_rendering into tui_file::flush. And tui_file::write. And tui_file::puts ..... ... but that all seems a bit unnecessary. Instead, I propose that tui_win_info::refresh_window() should be changed. If suppress_output is true (i.e. a tui_batch_rendering is active) then we should continue to call wnoutrefresh(). But if suppress_output is false, meaning that no tui_batch_rendering is in place, then we should call wrefresh(), which immediately writes the output to the screen. Testing but PR gdb/32623 was a little involved. We need to 'run' the inferior and check for the 'Starting program' message. But DejaGNUU can only check for the message once it knows the message should have appeared. But, as the bug is that output is not displayed, we don't have any output hints that the inferior is started yet... In the end, I have the inferior create a file in the test's output directory. Now DejaGNU can send the 'run' command, and wait for the file to appear. Once that happens, we know that the 'Starting program' message should have appeared. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32623 Approved-By: Tom Tromey <tom@tromey.com>
2025-02-07gdb/testsuite: fix "up to main" in gdb.base/corefile-exec-context.expLancelot SIX1-1/+1
On ubuntu systems with libc debug info available (libc6-dbg), I see the following failures for the gdb.base/corefile-exec-context.exp testcase: show args Argument list to give program being debugged when it is started is "aaaaa bbbbb ccccc ddddd e\ e\ e\ e\ e". (gdb) PASS: gdb.base/corefile-exec-context.exp: show args up #1 __pthread_kill_internal (signo=6, threadid=133859295332160) at ./nptl/pthread_kill.c:78 78 in ./nptl/pthread_kill.c (gdb) FAIL: gdb.base/corefile-exec-context.exp: move up to main This failures is because the pattern used to parse the output of `up` is not expecting what is seen when debugging information is present for those frames. This patch adjusts the pattern to allow both possible outputs. Tested on ubuntu-22.04 and ubuntu24.04 with libc6-dbg installed for gdb build with --with-separate-debug-dir=/usr/lib/debug. Change-Id: I217d4b20006d0ecdb4b7a71eeb8d01597ec5ac63 Approved-By: Tom Tromey <tom@tromey.com>
2025-02-06[gdb/testsuite] Use -nostdlib in gdb.base/list-dot-nodebug.expTom de Vries2-26/+52
When running test-case gdb.base/list-dot-nodebug.exp with target board cc-with-gnu-debuglink, I run into: ... (gdb) list .^M warning: 1 ../sysdeps/x86_64/crtn.S: No such file or directory^M (gdb) FAIL: gdb.base/list-dot-nodebug.exp: debug=none: print before start ... The problem is that the call to gdb_gnu_strip_debug in gdb.base/list-dot-nodebug.exp has no effect, because the target board makes sure that compilation delivers an executable that is already stripped, with a .gnu_debuglink section linking to the debug info. Fix this by using -nostdlib instead of static, which means the call to gdb_gnu_strip_debug can be removed. This also allows us to extend the test-case to excercise "list ." before starting the inferior, for the debug=some scenario, which is currently skipped: ... # We don't test "list ." before starting with some debug info # because GDB will choose the symtab that has debuginfo, and # print the copyright blurb. This test isn't interested (yet?) # in checking if this default location choice is consistent. ... While we're at it, make the effect of "list ." on the current source location explicit using "info source" before and after "list .". While we're at it, make sure when running with target board cc-with-gdb-index or cc-with-debug-names, that the failure to compile the debug=none variant due to: ... Error while writing index ...: No debugging symbols ... doesn't stop the test-case from running the debug=some variant. Tested on x86_64-linux. Reviewed-By: Guinevere Larsen <guinevere@redhat.com>
2025-02-06gdb/testsuite: gdb.base/gcorebg.exp against installed binariesLancelot SIX3-25/+29
It is possible to run GDB's testsuite against installed binaries rather than the one from the build tree. For example, one could do: $ make check-gdb RUNTESTFLAGS=GDB=/usr/bin/gdb Running the testsuite this way causes error for gdb.base/gcorebg.exp: Running [...]/gdb/testsuite/gdb.base/gcorebg.exp ... FAIL: gdb.base/gcorebg.exp: detached=detached: Spawned gcore finished FAIL: gdb.base/gcorebg.exp: detached=detached: Core file generated by gcore FAIL: gdb.base/gcorebg.exp: detached=standard: Spawned gcore finished FAIL: gdb.base/gcorebg.exp: detached=standard: Core file generated by gcore This is due to 2 problems. First, when running this way, the $GDB_DATA_DIRECTORY is not set (on purpose) as the installed GDB does not need to be specified where to find it. See this section in gdb/testsuite/lib/gdb.exp: if ![info exists GDB] { [....] } else { # If the user specifies GDB on the command line, and doesn't # specify GDB_DATA_DIRECTORY, then assume we're testing an # installed GDB, and let it use its own configured data directory. if ![info exists GDB_DATA_DIRECTORY] { set GDB_DATA_DIRECTORY "" } } The testbg.exp file always assumes a non-empty GDB_DATA_DIRECTORY. As a consequence, when calling the gcorebg binary with an empty argument (i.e. missing argument), the program fails: gcorebg: [...]/gdb/testsuite/gdb.base/gcorebg.c:42: main: Assertion `argc == 5' failed. FAIL: gdb.base/gcorebg.exp: detached=standard: Spawned gcore finished This patch does adjust the gcorebg.c and gcorebg.exp files to allow not specifying the data-directory. The other issue is that the testsuite assumes that the `gcore` to test is always the one from the build tree. However, if someone is testing an installed binary by setting GDB, I think that person would expect to test the `gcore` script next to the binary that was specified (unless GCORE is specified to explicitly specified). This patch does that adjustment as well. To that end, it needs to move the block setting GCORE after the block setting GDB. Change-Id: I070e039903c0b5afeac357d8fac7d710ff6697b9 Approved-By: Tom Tromey <tom@tromey.com>
2025-02-05Print only process ptids from linux-fork.cKevin Buettner1-1/+1
This commit causes a "process ptid" to be passed to all calls of target_pid_to_str in linux-fork.c. A "process ptid" is one in which only the pid component is set to a non-zero value; both the lwp and tid components are zero. The reason for doing this is that pids associated with checkpoints can never be a thread due to the fact that checkpoints (which are implemented by forking a process) can only (reasonably) work with single-threaded processes. Without this commit, many of the "info checkpoints" commands in gdb.multi/checkpoint-multi.exp will incorrectly show some of the checkpoints as threads. E.g... Id Active Target Id Frame * 1.0 y Thread 0x7ffff7cb5740 (LWP 581704) at 0x401199, file hello.c, line 51 1.2 n process 581716 at 0x401199, file hello.c, line 51 1.3 n process 581717 at 0x401199, file hello.c, line 51 2.1 n process 581708 at 0x401258, file goodbye.c, line 62 2.2 y Thread 0x7ffff7cb5740 (LWP 581712) at 0x401258, file goodbye.c, line 62 3.0 y Thread 0x7ffff7cb5740 (LWP 581713) at 0x40115c, file hangout.c, line 31 3.2 n process 581715 at 0x40115c, file hangout.c, line 31 (gdb With this commit in place, the output looks like this instead: Id Active Target Id Frame * 1.0 y process 535276 at 0x401199, file hello.c, line 51 1.2 n process 535288 at 0x401199, file hello.c, line 51 1.3 n process 535289 at 0x401199, file hello.c, line 51 2.1 n process 535280 at 0x401258, file goodbye.c, line 62 2.2 y process 535284 at 0x401258, file goodbye.c, line 62 3.0 y process 535285 at 0x40115c, file hangout.c, line 31 3.2 n process 535287 at 0x40115c, file hangout.c, line 31 (For brevity, I've removed the directory elements in each of the paths above.) The testcase, gdb.multi/checkpoint-multi.exp, has been updated to reflect the fact that only "process" should now appear in output from "info checkpoints". Reviewed-By: Tom Tromey <tom@tromey.com> Approved-By: Andrew Burgess <aburgess@redhat.com>
2025-02-05Capitalize output of successful checkpoint commandKevin Buettner3-3/+3
This commit causes the output of a "checkpoint" command to be changed from: checkpoint N: fork returned pid DDDD to: Checkpoint N: fork returned pid DDDD This change was made to bring the output of the "checkpoint" command in line with that of other commands, e.g.: (gdb) break main Breakpoint 1 at ... (gdb) catch exec Catchpoint 2 (exec) (gdb) add-inferior [New inferior 2] Added inferior 2 The tests gdb.base/checkpoint.exp, gdb.base/kill-during-detach.exp, and gdb.multi/checkpoint-multi.exp have been updated to accept the new (capitalized) output from the "checkpoint" command. Reviewed-By: Tom Tromey <tom@tromey.com> Approved-By: Andrew Burgess <aburgess@redhat.com>
2025-02-05Make linux checkpoints work with multiple inferiorsKevin Buettner2-12/+812
The current linux checkpoint code, most of which may be found in linux-fork.c, is quite broken when attempting to use more than one inferior. Running GDB will show internal errors when starting two inferiors, placing a checkpoint in one, then switching to the other and doing one of the following commands, "restart", "detach", "kill", or continue (to program exit). Test cases for two of those scenarios may be found in this bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31065 I've tested for each of the scenarios and many more in the new test case, gdb.multi/checkpoint-multi.exp. I started off with the goal of fixing just those problems, and was mostly successful with a much smaller patch, but doing "info checkpoints" with more than one inferior didn't work correctly due to some of the inferiors being in the wrong program space. That led me to making the linux-fork code fully inferior-aware. Prior to this commit, the list of forks was being maintained in a global named named 'fork_list'. I turned this into a per-inferior data structure. There was also global named 'highest_fork_num' which is also now part of the per-inferior struct. A registry key named 'checkpoint_inferior_data_key' along with function 'get_checkpoint_inferior_data' is used to access the per-inferior data. This new function, get_checkpoint_inferior_data, is only called by the new functions 'fork_list', 'reset_highest_fork_num', and increment_highest_fork_num, each of which is passed a pointer to the inferior. Most occurrences referring to the (previously) global 'fork_list' have been replaced by 'fork_list (inf)'. In some functions, where the 'fork_list' is referenced multiple times, a local named 'fork_list' is declared and initialized instead, like this: auto &fork_list = ::fork_list (inf); The constructor for 'struct fork_info' has gained an additional parameter. In addition to passing the pid of the new fork, we now also pass the fork identifier, fork_num, to the constructor. This integer is shown to the user in the "info checkpoints" command and is provided by the user, perhaps in conjunction with the inferior number, in commands which manipulate checkpoints, e.g. 'restart' and 'delete checkpoint'. When checkpoints are used in only one inferior, this commit will present information to the user and will accept checkpoint identifiers to commands in much the same way as the code did before this commit. Per Pedro Alves's recommendations, the "info checkpoints" command has been changed somewhat. "info checkpoints" used to display "(main process)" for the first process in the checkpoint list. This is no longer done because it does not provide useful information. It also used to display "<running>", when the process is running and no useful frame information may be displayed. This has been changed to "(running)" in order to be more consistent with the output of the "info threads" command. A new column has been added to the output for showing the active process in the output from "info checkpoints". This column will display 'y' for the active process and 'n' for the others. For the active inferior a '*' is also printed preceding the checkpoint identifier. Here's what things look(ed) like before and after for just one inferior: Before: (gdb) info checkpoints * 0 Thread 0x7ffff7cd3740 (LWP 84201) (main process) at 0x40114a, file hello.c, line 28 1 process 84205 at 0x401199, file hello.c, line 51 2 process 84206 at 0x4011a3, file hello.c, line 53 After: (gdb) info checkpoints Id Active Target Id Frame * 0 y process 551311 at 0x40114a, file hello.c, line 28 1 n process 551314 at 0x401199, file hello.c, line 51 2 n process 551315 at 0x4011a3, file hello.c, line 53 (The Thread versus process distinction is handled by another patch - the "After" example assumes that patch is applied too.) When there are multiple inferiors, the "info checkpoints" output looks like this: (gdb) info checkpoints Id Active Target Id Frame 1.0 y process 535276 at 0x401199, file hello.c, line 51 1.1 n process 535283 at 0x401199, file hello.c, line 51 1.2 n process 535288 at 0x401199, file hello.c, line 51 2.1 n process 535280 at 0x401258, file goodbye.c, line 62 2.2 y process 535284 at 0x401258, file goodbye.c, line 62 * 3.0 y process 535285 at 0x40115c, file hangout.c, line 31 3.2 n process 535287 at 0x40115c, file hangout.c, line 31 A new function named 'parse_checkpoint_id' has been added. As its name suggests, it's responsible for parsing a string representing a checkpoint identifier. These identifiers may be either a decimal number representing the checkpoint number in the current inferior or two decimal numbers separated by '.', in which case the first is the inferior number and the second is the checkpoint number in that inferior. It is called by delete_checkpoint_command, detach_checkpoint_command, info_checkpoints_command, and restart_command. Calls to 'parse_checkpoint_id' replace calls to 'parse_and_eval_long', plus error checking and error reporting code near the calls to 'parse_and_eval_long'. As such, error checking and reporting has been consolidated into a single function and the messages output are more uniform, though this has necessitated changes to the existing test case gdb.base/checkpoint.exp. The functions 'find_fork_ptid' and 'find_fork_pid' used to return a pointer to a fork_info struct. They now return a pair consisting of the pointer to a fork_info struct in addition to a pointer to the inferior containing that checkpoint. 'find_fork_id' returns a pointer to a fork_info struct just as it did before, but it's now gained a new parameter, 'inf', which is the inferior in which to look. info_checkpoints_command used to simply iterate over the list of forks (checkpoints), printing each one out. It now needs to iterate over all inferiors and, for those which have checkpoints, it needs to iterate over the list of checkpoints in that inferior. As noted earlier, the format of the output has been changed so that checkpoint identifiers incorporating an inferior number may be printed. linux_fork_context, called by restart_command, now contains code to switch inferiors when the fork being restarted is in an inferior which is different from the current one. The scoped_switch_fork_info class now also contains code for switching inferiors in both the constructor and destructor. gdb/linux-nat.c has a few changes. All but one of them are related to passing the inferior to one of the linux-fork functions. But one of the tests in linux_nat_target::detach has also changed in a non-obvious way. In attempting to determine whether to call linux_fork_detach(), that code used to do: if (pid == inferior_ptid.pid () && forks_exist_p ()) It's been simplified to: if (forks_exist_p (inf)) I had added the 'pid == inferior_ptid.pid ()' condition in late 2023 while working on a detach bug. It was kind of a hack to prevent calling linux_fork_detach() when in a different inferior. That's no longer needed since the call to forks_exist_p does this directly - i.e. it is now inferior-aware. Finally, the header file 'linux-fork.h' has been updated to reflect the fact that add_fork, linux_fork_killall, linux_fork_detach, and forks_exist_p all now require that a pointer to an inferior be passed to these functions. Additionally (as mentioned earlier), find_fork_pid now returns std::pair<fork_info *, inferior *> instead 'of fork_info *'. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31065 Reviewed-By: Tom Tromey <tom@tromey.com> Approved-By: Andrew Burgess <aburgess@redhat.com>
2025-02-04pre-commit: run flake8 on more Python filesSimon Marchi1-1/+1
pre-commit currently runs flake8 only on `gdb/python/**/*.py`. There are more files we can run it on, without running it on all the testsuite files. Add: - gdb/gdb-gdb.py.in - gdb/*.py - gdb/testsuite/*.py Fix the new errors that popped up: gdb/copyright.py:29:21: W605 invalid escape sequence '\*' gdb/copyright.py:29:29: W605 invalid escape sequence '\*' gdb/copyright.py:29:38: W605 invalid escape sequence '\*' gdb/copyright.py:29:46: W605 invalid escape sequence '\*' gdb/copyright.py:34:1: F401 'datetime' imported but unused gdb/testsuite/analyze-racy-logs.py:150:9: E722 do not use bare 'except' Change-Id: Ia864c22d4f170d4e18ce3beb06a86c49966654b2 Approved-By: Tom Tromey <tom@tromey.com>
2025-02-04Reorder gnatmake arguments in inline-section-gc.expTom Tromey1-2/+2
inline-section-gc.exp ends up passing "-lm" to gnatmake as an "marg" -- meaning gnatmake should process it itself. However, the gnat-llvm gnatmake does not know what to do with this, so the test fails. This patch rearranges the arguments so that the (implicit) trailing -lm ends up being passed through to the linker.
2025-02-04gdb/python: add void_type () method to gdb.Architecture objectJan Vrany1-0/+4
This commit adds a new method to Python architecture objects that returns a void type for that architecture. This will be useful later to create types for function symbols created using Python extension code. Reviewed-By: Eli Zaretskii <eliz@gnu.org> Approved-By: Andrew Burgess <aburgess@redhat.com>
2025-02-04gdb/python: add domain property to gdb.SymbolJan Vrany1-1/+2
Reviewed-By: Eli Zaretskii <eliz@gnu.org> Approved-By: Andrew Burgess <aburgess@redhat.com>
2025-02-04gdb/python: add subblocks property to gdb.BlockJan Vrany1-1/+5
This commit adds new propery "subblocks" to gdb.Block objects. This allows Python to traverse block tree starting with global block. Reviewed-By: Eli Zaretskii <eliz@gnu.org> Approved-By: Andrew Burgess <aburgess@redhat.com>
2025-02-04[gdb/testsuite] Fix gdb.ada/big_packed_array.exp on s390x-linuxTom de Vries1-1/+8
When running test-case gdb.ada/big_packed_array.exp on s390x-linux, I run into: ... (gdb) print bad^M $2 = (0 => 0 <repeats 24 times>, 1)^M (gdb) FAIL: gdb.ada/big_packed_array.exp: scenario=minimal: print bad ... This is with gcc 7.5.0, and this xfail should trigger: ... if { $have_xfail && [string is integer $last] \ && [expr ($last & 0xf) == 0] } { # gcc/101643 setup_xfail *-*-* } ... but it doesn't because $last is '1'. Fix this by using 0xf0 as mask for big endian. Tested on s390x-linux.
2025-02-04[gdb/testsuite] Fix gdb.ada/convvar_comp.exp on s390x-linuxTom de Vries2-2/+4
When running test-case gdb.ada/convvar_comp.exp on s390x-linux, I get: ... (gdb) run ^M Starting program: pb16_063 ^M ^M Breakpoint 1, pck.break_me (item=...) at pck.adb:17^M 17 function Break_Me (Item : T) return Boolean is^M (gdb) print item.started^M Cannot access memory at address 0x0^M (gdb) FAIL: gdb.ada/convvar_comp.exp: print item.started ... This happens as follows. The parameter item is available in (DW_OP_fbreg: -168): ... <2><912>: Abbrev Number: 18 (DW_TAG_formal_parameter) <913> DW_AT_name : (indirect string, offset: 0x14ca): item <919> DW_AT_type : <0x929> <91d> DW_AT_location : 3 byte block: 91 d8 7e (DW_OP_fbreg: -168) ... and according to the rules of -O0, it's considered to be available after the prologue, which looks like this: ... 0000000001002998 <pck__break_me>: 1002998: b3 c1 00 2b ldgr %f2,%r11 100299c: b3 c1 00 0f ldgr %f0,%r15 10029a0: e3 f0 ff 58 ff 71 lay %r15,-168(%r15) 10029a6: b9 04 00 bf lgr %r11,%r15 10029aa: e3 20 b0 a0 00 24 stg %r2,160(%r11) ... To detect the prologue, gdb checks the line info, which looks like this: ... pck.adb: File name Line number Starting address View Stmt pck.adb 17 0x1002998 x pck.adb 17 0x1002998 1 x pck.adb 19 0x10029b0 x pck.adb 20 0x10029b8 x pck.adb - 0x10029c6 ... and gdb concludes that it's an empty prologue, so we stop at 0x1002998 and try to print parameter item, which is not available yet. For more details, see this comment in skip_prologue_using_sal: ... /* For languages other than assembly, treat two consecutive line entries at the same address as a zero-instruction prologue. ... The same thing happens on x86_64-linux, but it causes no problem there, because amd64_skip_prologue decides not to trust the result: ... struct compunit_symtab *cust = find_pc_compunit_symtab (func_addr); /* LLVM backend (Clang/Flang) always emits a line note before the prologue and another one after. We trust clang and newer Intel compilers to emit usable line notes. */ if (post_prologue_pc && (cust != NULL && cust->producer () != nullptr && (producer_is_llvm (cust->producer ()) || producer_is_icc_ge_19 (cust->producer ())))) return std::max (start_pc, post_prologue_pc); ... because the producer is GCC. Work around this by setting a breakpoint on the first statement of pck.break_me instead. Tested on s390x-linux.
2025-02-04[gdb/testsuite] Use c++ flag in c++ test-casesTom de Vries21-25/+108
In some cases, test-cases use c++, but don't add "c++" to the compilation flags. This can cause problems with some compilers. Fix this in some test-cases. Approved-By: Tom Tromey <tom@tromey.com> PR testsuite/30380 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30380
2025-02-04[gdb/testsuite] Fix gdb.base/list-dot-nodebug.exp on openSUSETom de Vries1-1/+1
On openSUSE Leap 15.6 with test-case gdb.base/list-dot-nodebug.exp I run into: ... (gdb) list .^M warning: 1 ../sysdeps/x86_64/crtn.S: No such file or directory^M (gdb) FAIL: $exp: debug=none: print before start ... The intent of the debug=none case is to generate an executable with no debug info. However, we have quite a few CUs with debug info: ... $ readelf -wi outputs/gdb.base/list-dot-nodebug/list-dot-nodebug-none \ | egrep -c " @ " 431 ... This is because this code: ... gdb_gnu_strip_debug $executable no-debuglink ... uses $executable, and the variable is set here: ... set executable ${testfile}-none ... which sets it to "list-dot-nodebug-none" and consequently gdb_gnu_strip_debug cannot find it. Fix this by using "[standard_output_file $executable]" instead. Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com> PR testsuite/31721 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31721
2025-02-04[gdb/tui] Remove stale title when showing "No Source Available"Tom de Vries1-0/+3
When running test-case gdb.tui/main.exp, the last command discards the executable file and symbol table: ... (gdb) file No executable file now. Discard symbol table from `main'? (y or n) [answered Y; input not from terminal] No symbol file now. (gdb) ... and we end up with this source window: ... +-tui-layout.c----------------------------------------------------------------+ | | | | | | | | | | | | | [ No Source Available ] | | | | | | | | | | | | | +-----------------------------------------------------------------------------+ ... The source window title shouldn't be showing tui-layout.c. It's the source file containing function main for the executable that was just discarded. Fix this by clearing the title in tui_source_window::erase_source_content. Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com>
2025-02-02Avoid "text file busy" in dw2-using-debug-str.expTom Tromey1-0/+12
When I run: runtest dw2-using-debug-str.exp ... if I examine the gdb.log, I see: objcopy: unable to copy file '[...]/dw2-using-debug-str'; reason: Text file busy This happens because the inferior is still running, and objcopy -- despite the invocation seemingly not needing this -- tries to open it for writing. This patch works around the objcopy oddity by having gdb exit (killing the inferior) before the invocation. Fixing this points out that the test does not work in the --target_board=cc-with-gdb-index case. This patch also arranges to issue an "untested" here.
2025-01-31Remove obsolete test from gdb.cp/var-tag.expTom Tromey1-10/+1
There is a test in gdb.cp/var-tag.exp that is kfail'd. I happened across this while working on another series and found that the PR it referenced was closed as invalid. On that basis I think the test should be deleted. Reviewed-By: Keith Seitz <keiths@redhat.com>
2025-01-30Use "require" a two gdb.dwarf2 test filesTom Tromey2-9/+3
A couple of ".tcl" files in gdb.dwarf2 escaped notice during the "require" refactoring. This patch fixes these to use "require" rather than if/return.
2025-01-30gdb: add first gdbreplay test, connect.expAlexandra Hájková3-0/+294
When the changes on the remote protocol are made, we want to test all the corner cases to prevent regressions. Currently it can be tricky to simulate some corner case conditions that would expose possible regressions. When I want to add or change the remote protocol packet, I need to hack gdbserver to send a corrupted packet or an error to make sure GDB is able to handle such a case. This test makes it easy to send a corruped packet or an error message to GDB using the gdbreplay tool and check GDB deals with it as we expect it to. This test starts a communication with gdbsever setting the remotelog file. Then, it modifies the remotelog with update_log proc, injects an error message instead of the expected replay to the vMustReplyEmpty packet in order to test GDB reacts to the error response properly. After the remotelog modification, this test restarts GDB and starts communication with gdbreply instead of the gdbserver using the remotelog. Add a lib/gdbreplay-support.exp. update_log proc matches lines from GDB to gdbserver in a remotelogfile. Once a match is found then the custom line is used to build a replacement line to send from gdbserver to GDB. Approved-By: Andrew Burgess <aburgess@redhat.com>
2025-01-30[gdb/testsuite] Handle unordered dict in gdb.python/py-mi-notify.expTom de Vries1-1/+4
With test-case gdb.python/py-mi-notify.exp and python 3.4, I occasionally run into: ... python gdb.notify_mi('-test-notification', { 'data1' : 1 , 'data2' : 2 }) &"python gdb.notify_mi('-test-notification', { 'data1' : 1 , 'data2' : 2 })\n" =-test-notification,data2="2",data1="1" ^done (gdb) FAIL: $exp: python notification, with additional data (unexpected output) ... In contrast, a passing version looks like: ... python gdb.notify_mi('-test-notification', { 'data1' : 1 , 'data2' : 2 }) &"python gdb.notify_mi('-test-notification', { 'data1' : 1 , 'data2' : 2 })\n" =-test-notification,data1="1",data2="2" ^done (gdb) PASS: gdb.python/py-mi-notify.exp: python notification, with additional data ... The python method "gdb.notify_mi(name, data)" has parameter data which is a dictionary, and it iterates over that dictionary. The problem is that dictionaries are only guaranteed to be iterating in insertion order starting python 3.7 (though cpython does this starting python 3.6). Fix this in the same way as in commit 362a867f2ac ("[gdb/testsuite] Handle unordered dict in gdb.python/py-mi-cmd.exp"): by allowing the alternative order. Tested on x86_64-linux.
2025-01-29Use command style in "help" commandTom Tromey5-25/+25
This changes the help command to use the new command style when displaying text like: List of "catch" subcommands: As a side effect, this mildly -- but not hugely -- cleans up some i18n issues in help_list. The header comment for that function is also changed to the gdb style. Finally, this function used to print something like: Type "help catch" followed by catch subcommand name for full documentation. The second "catch" here seems redundant to me, so this patch removes it.
2025-01-29gdb/testsuite: add comments to line table from DWARF assemblerAndrew Burgess1-7/+7
Add comments to the assembler generated by the DWARF assembler that builds the line table. I found these comments useful when debugging issues with the line table parsing. This patch should make no difference to what is being tested. The test binaries should be unchanged after this commit. Approved-By: Kevin Buettner <kevinb@redhat.com>
2025-01-28[gdb/tui] Fix assert in tui_source_window_base::refresh_windowTom de Vries1-0/+3
Say we use the executable of test-case gdb.tui/tui-missing-src.exp like this: ... $ gdb.sh -q -tui outputs/gdb.tui/tui-missing-src/tui-missing-src \ -ex "b f2"\ -ex run ... (from a directory not containing a file called main.c to make sure that the missing source stays missing) and then issue finish: ... (gdb) finish Run till exit from #0 f2 (x=4) at f2.c:5 0x0000000000400570 in main () at main.c:7 Value returned is $1 = 13 (gdb) ... and use control-<minus> to decrease the font size (IOW increase the $LINES and $COLUMNS) on the terminal, we get: ... gdb/tui/tui-winsource.c:340: internal-error: refresh_window: \ Assertion `pad_x + view_width <= pad_width || m_pad.get () == nullptr' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. ... The tui_source_window_base class has variable m_pad which keeps track of a curses pad that is used to display the source code or disassembly efficiently. The assert in tui_source_window_base::refresh_window triggers while preparing to display part of the pad. The problem is that the window is in a state in which the pad is not used, because m_content.empty () == true. Instead, it simply shows "[ No Source Available ]". Fix this by bailing out of tui_source_window_base::refresh_window before accessing the m_pad variable, if m_content.empty () == true. Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com> PR tui/32592 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32592
2025-01-24Fix C++ template function matching in cooked indexTom Tromey3-3/+27
In commit 64a97606 ("Support template lookups in strncmp_iw_with_mode"), gdb was changed so that a command like "break func<templ>" would match instantiations like "func<templ<int>>". The new indexer does not support this and so this is a regression. This went unnoticed because gdb.linespec.cpcompletion.exp puts all these functions into the main file, and this CU is expanded early. This patch fixes the bug by changing the cooked index entry comparison function. It also updates the test to fail without this fix. Regression tested on x86-64 Fedora 40. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32482
2025-01-24[gdb/testsuite] Record less in gdb.reverse/time-reverse.expTom de Vries2-4/+15
While stepping through gdb.reverse/time-reverse.exp I realized that we're recording the instructions for resolving the PLT entries for functions time and syscall, while that's not really the focus of the test-case. Limit the scope of the test, by calling the functions once before starting to record. Also call "info record" after recording to make it clear how many instructions were recorded. On x86_64-linux, before this patch (but with info record added), we have: ... $ grep "Log contains" gdb.log Log contains 750 instructions. Log contains 1218 instructions. ... and with this patch we have: ... $ grep "Log contains" gdb.log Log contains 24 instructions. Log contains 19 instructions. ... Tested on x86_64-linux. Approved-By: Guinevere Larsen <guinevere@redhat.com>
2025-01-23[gdb/cli] Fix return from frame containing inline frameTom de Vries2-0/+82
Consider test-case gdb.base/return-3.exp: ... $ gdb -q outputs/gdb.base/return-3/return-3 Reading symbols from outputs/gdb.base/return-3/return-3... (gdb) ... Function bar is an inlined function, and consequently we cannot return from it: ... (gdb) b bar Breakpoint 1 at 0x4006ac: file return-3.c, line 25. (gdb) r Starting program: return-3 ... Breakpoint 1, bar () at return-3.c:25 25 c++; (gdb) return Can not force return from an inlined function. (gdb) ... However, function foo is not an inline function, and we should be able to return from it, but we get the same error message: ... (gdb) up 31 bar (); (gdb) return Can not force return from an inlined function. (gdb) ... Fix this by using the selected frame rather than the current frame in return_command, such that we get instead: ... (gdb) up 31 bar (); (gdb) return 40 printf ("%d\n", c); (gdb) ... Tested on aarch64-linux. Reviewed-By: Guinevere Larsen <guinevere@redhat.com> PR cli/32479 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32479
2025-01-22Remove gnatmake_version_at_leastTom Tromey5-25/+4
This removes gnatmake_version_at_least in favor of using the more flexible gnat_version_compare. I think these two version numbers should be the same, as gnatmake is shipped with the compiler.
2025-01-22Avoid crash with 'lengthTom Tromey4-0/+103
While testing gnat-llvm, I found a gdb crash when applying 'length to a non-array type. This patch fixes the crash.
2025-01-22Preserve local variables in another Ada test caseTom Tromey3-2/+45
I found another Ada test case where gnat-llvm optimizes away the local variables. This patch applies the same fix to it as previous patches.
2025-01-22[gdb/testsuite] Fix gdb.base/branch-to-self.exp on arm-linuxTom de Vries1-1/+16
On arm-linux (ubuntu 24.04 with gcc 13.3.0) with target board unix/-marm and test-case gdb.base/branch-to-self.exp I run into: ... (gdb) continue^M Continuing.^M ^M Breakpoint 2, main () at branch-to-self.c:38^M 38 for (;;); /* loop-line */^M (gdb) PASS: $exp: single-step: continue to breakpoint: hit breakpoint si^M 0x0040058c 38 for (;;); /* loop-line */^M (gdb) FAIL: $exp: single-step: si ... In contrast, on the same machine but with debian testing and gcc 14.2.0 we have: ... (gdb) continue^M Continuing.^M ^M Breakpoint 2, main () at branch-to-self.c:38^M 38 for (;;); /* loop-line */^M (gdb) PASS: $exp: single-step: continue to breakpoint: hit breakpoint si^M ^M Breakpoint 2, main () at branch-to-self.c:38^M 38 for (;;); /* loop-line */^M (gdb) PASS: $exp: single-step: stepi ... The difference is in the instruction(s) generated for the loop. In the passing case, we have: ... 588: eafffffe b 588 <main+0x24> ... and in the failing case: ... 588: e320f000 nop {0} 58c: eafffffd b 588 <main+0x24> ... The purpose of this part of the test-case is to: - generate a branch instruction that jumps to itself, and - set a breakpoint on it, and check that stepi-ing from that breakpoint triggers the breakpoint again. As we can see, in the failing case we failed to generate a branch instruction that jumps to itself, and consequently we cannot expect to hit the breakpoint again after issuing a single si. Fix this by issuing stepi until we hit the breakpoint. Tested on arm-linux. Reviewed-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
2025-01-21[gdb/symtab] Fix gdb.base/fission-macro.exp with unix/-m32Tom de Vries1-2/+6
When running test-case gdb.base/fission-macro.exp on openSUSE Tumbleweed (using gcc 14) with target board unix/-m32, I get: ... (gdb) info macro FIRST^M Defined at /data/vries/gdb/src/gdb/testsuite/gdb.base/fission-macro.c:0^M -DFIRST=1^M (gdb) FAIL: $exp: \ dwarf_version=5: dwarf_bits=32: strict_dwarf=0: info macro FIRST ... instead of the expected: ... (gdb) info macro FIRST^M Defined at /data/vries/gdb/src/gdb/testsuite/gdb.base/fission-macro.c:18^M (gdb) PASS: $exp: \ dwarf_version=5: dwarf_bits=32: strict_dwarf=0: info macro FIRST ... A dwarf-5 .debug_str_offsets section starts with a header consisting of: - an initial length (4 bytes for 32-bit and 12 bytes for 64-bit), - a 2 byte version string, and - 2 bytes padding so in total 8 bytes for 32-bit and 16 bytes for 64-bit. This offset is calculated here in dwarf_decode_macros: ... str_offsets_base = cu->header.addr_size; ... which is wrong for both dwarf-5 cases (and also happens to be wrong for dwarf-4). Fix this by computing str_offsets_base correctly for dwarf-5, for both the 32-bit and 64-bit case. Likewise, fix this for dwarf-4, using str_offsets_base 0. We can only test this with gcc-15, because gcc 14 and earlier don't have the fix for PR debug/115066. Tested on x86_64-linux. Tested test-case using a current gcc trunk build, and gcc 14. Approved-By: Tom Tromey <tom@tromey.com> PR symtab/31897 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31897
2025-01-21[gdb/testsuite] Use -g3 in gdb.base/lineinc.expTom de Vries1-1/+2
The stated intention of test-case gdb.base/lineinc.exp is: ... # Test macro handling of #included files. ... However, the test-case does not produce any macro debug information. Fix this by adding macros in the compilation flags. Tested on x86_64-linux.
2025-01-20gdb/testsuite: Fix file location for gdb.base/backtrace-through-cu-nodebugGuinevere Larsen1-7/+7
The newly added test gdb.base/backtrace-through-cu-nodebug.exp had a problem in the call to gdb_compile, that caused the .o files to be outputted in the GDB file tree. This commit fixes the issues in the calls. Reported-By: Tom de Vries <tdevries@suse.de> Approved-By: Tom de Vries <tdevries@suse.de>