aboutsummaryrefslogtreecommitdiff
path: root/gdb
AgeCommit message (Collapse)AuthorFilesLines
2025-03-04gdb/dwarf: make dwarf2_get_dwz_file a method of dwarf2_per_bfdSimon Marchi9-44/+32
dwarf2_get_dwz_file looks more or less like a simple getter of dwarf2_per_bfd::dwz_file, so make it into a method. I typically avoid the `get_` prefix for getters, but that would conflict with the field name here. Change-Id: Idd0d5b1bd3813babf438b20aac514b19c77cfc18 Approved-By: Tom Tromey <tom@tromey.com>
2025-03-04gdb/dwarf: remove create_cu_from_index_listSimon Marchi3-24/+3
I noticed that create_cu_from_index_list is only used in read-gdb-index.c, so I started by moving it there. But given that this function is use at only one spot and doesn't do much, I opted to inline its code in the caller instead. Change-Id: Iebe0dc20d345fa70a2f11aa9ff1a04fe26a31407 Approved-By: Tom Tromey <tom@tromey.com>
2025-03-04Check whether gnatmake can link with -sharedTom Tromey2-0/+10
Currently, gnat-llvm does not ship a shared libgnat. This patch changes the relevant test to check whether linking with -shared actually works.
2025-03-04Check whether gnatmake supports -OgTom Tromey2-0/+9
gnat-llvm does not support the -Og flag. This arranges to check for this flag before using it.
2025-03-04Look for -fgnat-encodings optionTom Tromey2-4/+24
gnat-llvm does not support the -fgnat-encodings option, and does not emit GNAT encodings at all -- it only supports the equivalent of GCC's "minimal" encodings; which is to say, ordinary DWARF. This patch changes gdb to test whether gnatmake supports this flag and adapt accordingly. foreach_gnat_encoding is changed to pretend that the "minimal" mode is in effect, as some test examine the mode.
2025-03-04Check -fvar-tracking via ada_simple_compileTom Tromey3-2/+7
A couple of Ada tests check whether the C compiler supports -fvar-tracking. However, this doesn't really work when using gnat-llvm, because that will invoke clang under the hood. This patch arranges to check gnatmake instead, which is more robust even when toolchains are mix-and-matched.
2025-03-04Introduce ada_simple_compileTom Tromey2-11/+56
This introduces ada_simple_compile, an Ada-specific analog of gdb_simple_compile. gdb_compile_test is split into two procs to make this possible. ada_simple_compile isn't used in this patch but will be by later patches in this series.
2025-03-04Check for compiler support in scalar_storage.expTom Tromey1-2/+14
gnat-llvm does not currently handle Scalar_Storage_Order. This patch changes the scalar_storage.exp test to check the compiler error messages and report "unsupported" in this case. This way, the test ought to start working automatically if this feature is added to gnat-llvm.
2025-03-03Obvious comment fix in cooked-index.hTom Tromey1-1/+1
I noticed that cooked-index.h still refers to a vector of parent maps, but the code itself actually uses a parent_map here.
2025-03-03Add language to type unit in debug-names-tu.exp.tclTom Tromey6-45/+67
I think debug-names-tu.exp.tcl only passes by accident -- the type unit does not have a language, which gdb essentially requires. This isn't noticeable right now because the type unit in question is expanded in one phase and then the symbol found in another. However, I'm working on a series that would regress this. This patch partially fixes the problem by correcting the test case, adding the language to the TU. Hoewver, it then goes a bit further and arranges for this information not to be written to .debug_names. Whether or not a type should be considered "static" seems like something that is purely internal to gdb, so this patch has the entry-creation function apply the appropriate transform. It also may make sense to change the "debug_names" proc in the test suite to process attributes more like the ordinary "cu" proc does.
2025-03-03gdb/dwarf: remove unnecessary abfd parameter in dwarf2_per_bfd::locate_sectionsSimon Marchi2-6/+5
The parameter `abfd` is always the same as `this->obfd`, there is no need to pass it as a parameter. Change-Id: If7ad58ad4efdf6b070cbf2b8a73436bd8b452fa6 Approved-By: Tom Tromey <tom@tromey.com>
2025-03-03gdb/dwarf: rename dwarf2_per_cu_data -> dwarf2_per_cuSimon Marchi21-298/+260
This scratches an itch I had for a while. I don't know why this struct type has "data" in its name. Others like "dwarf2_per_objfile" and "dwarf2_per_bfd" don't. The primary job of a structure is to hold data, there's no need to specify it. It also makes the name a bit shorter, which is always nice. Rename related types too. Change-Id: Ifb63195ff105809fc15b502f639c0bb4d18a675e Approved-By: Tom Tromey <tom@tromey.com> Reviewed-By: Guinevere Larsen <guinevere@redhat.com>
2025-03-03Bploc should try to return full pathSimon Farre1-3/+22
Compilers often emit relative paths in the line number program, relative to the build directory for that compilation unit (if it's DWARF>=4 I think). Therefore use symtab->fullname() when not null as this seemingly has attempted path normalization for the symtab and only fall back on symtab->filename which will never be null if that fails. This has a much better UX. Applications may choose to expose this name as a clickable link to some file, at which point a non-normalized and non-absolute path would lead nowhere. When I wrote this feature the first time, I don't think this relative-to-cu-scheme was as prevalent in the output of gcc/clang for DWARF. Approved-By: Tom Tromey <tom@tromey.com>
2025-03-03[gdb/doc] Indicate in which languages 'filename'::funcaddr worksTom de Vries1-4/+8
In the docs I read [1]: ... In this section, we discuss operators that you can use in GDB expressions regardless of your programming language. ... GDB supports these operators, in addition to those common to programming languages: ‘::’ allows you to specify a variable in terms of the file or function where it is defined. See Program Variables. ... In fact, this is not supported in Ada: ... (gdb) b *'foo.adb'::foo No file or function "foo.adb'". (gdb) ... and likewise in a few other working languages. Fix this by making this restriction explicit. Approved-By: Eli Zaretskii <eliz@gnu.org> PR gdb/32753 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32753 [1] https://sourceware.org/gdb/current/onlinedocs/gdb.html/Expressions.html
2025-03-03[gdb/doc] Fix address location with file prefixTom de Vries1-2/+4
In the docs I read [1]: ... Address locations indicate a specific program address. They have the generalized form *address. funcaddr An address of a function or procedure derived from its name. ... 'filename':funcaddr Like funcaddr above, but also specifies the name of the source file explicitly. This is useful if the name of the function does not specify the function unambiguously, e.g., if there are several functions with identical names in different source files. ... This is incorrect, the notation is in fact 'filename'::funcaddr. Fix this by correcting the typo, and add a reference to "variable name conflict", where the concept is explained in more detail. Approved-By: Eli Zaretskii <eliz@gnu.org> PR gdb/32748 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32748 [1] https://sourceware.org/gdb/current/onlinedocs/gdb.html/Address-Locations.html
2025-03-03[gdb/doc] Don't advertise *&function for pascal and modula-2Tom de Vries1-4/+3
In the docs I read [1]: ... Address locations indicate a specific program address. They have the generalized form *address. ... funcaddr An address of a function or procedure derived from its name. ... In Pascal and Modula-2, this is &function. ... I tried "break *&function" for Pascal and Modula-2, and this doesn't work, while "break *function" works fine. Fix this by updating the documentation to reflect actual behaviour. Approved-By: Eli Zaretskii <eliz@gnu.org> PR gdb/32754 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32754 [1] https://sourceware.org/gdb/current/onlinedocs/gdb.html/Address-Locations.html
2025-03-03gdb: remove some unused includes from printcmd.cSimon Marchi1-2/+0
clangd reports them as unused. Change-Id: I50a3c13db128ffe1630364f707d66a24ce11d352
2025-03-03gdb: remove unused include from frame.cSimon Marchi1-1/+0
clangd reports it as unused. Change-Id: I636e57747d3c42ce6615a14d4cf5dc115628a73d
2025-02-28gdb/dwarf: add dwarf2_per_bfd::filename and use it where possibleSimon Marchi4-18/+17
I noticed we quite often use: bfd_get_filename (per_bfd->obfd) Add a shortcut for that. Change-Id: I4e33925a481fd44088386510b01936d38e1d7d38 Approved-By: Andrew Burgess <aburgess@redhat.com>
2025-02-28[gdb/testsuite] Fix gdb.base/nostdlib.exp on aarch64Tom de Vries1-2/+22
On aarch64-linux, in test-case gdb.base/nostdlib.exp I run into: ... (gdb) continue^M Continuing.^M warning: Temporarily disabling breakpoints for unloaded shared library \ "/lib/ld-linux-aarch64.so.1"^M ^M Breakpoint 2, _start () at nostdlib.c:20^M 20 {^M (gdb) FAIL: $exp: pie=pie: continue to marker ... This happens as follows: - the test-case sets a breakpoint on *_start, - the breakpoint resolves to *_start in the executable, - the executable is started, and the breakpoint resolves to *_start in the dynamic linker, - execution stops at *_start in the dynamic linker, - the test-case issues a continue, expecting to continue to the breakpoint on marker, - while continuing, the dynamic linker is reported as unloaded, - the breakpoint again resolves to *_start in the executable, - execution stops at *_start in the executable, and - the test-case concludes that it failed to "continue to marker". This doesn't happen on x86_64-linux. There, after the executable is started, the breakpoint again resolves to *_start in the exec. This is similar to what happens when printing _start. On aarch64-linux, we print the _start in the dynamic linker: ... $ gdb -q -batch outputs/gdb.base/nostdlib/nostdlib-pie \ -ex "b _start" \ -ex run \ -ex "print _start" \ -ex "info break" Breakpoint 1 at 0x2bc: file nostdlib.c, line 23. Breakpoint 1.2, _start () at ../sysdeps/aarch64/dl-start.S:22 22 ENTRY (_start) $1 = {void (void)} 0xfffff7fd6ac0 <_start> Num Type Disp Enb Address What 1 breakpoint keep y <MULTIPLE> breakpoint already hit 1 time 1.1 y 0x0000aaaaaaaa02bc in _start at nostdlib.c:23 1.2 y 0x0000fffff7fd6ac0 in _start at dl-start.S:22 ... On x86_64-linux, we print the _start in the exec: ... Breakpoint 1 at 0x2c5: file nostdlib.c, line 23. Breakpoint 1.2, 0x00007ffff7fe4f00 in _start () from \ /lib64/ld-linux-x86-64.so.2 $1 = {void (void)} 0x5555555542c1 <_start> Num Type Disp Enb Address What 1 breakpoint keep y <MULTIPLE> breakpoint already hit 1 time 1.1 y 0x00005555555542c5 in _start at nostdlib.c:23 1.2 y 0x00007ffff7fe4f00 <_start> ... The difference may be down to the availability of debug info for the _start in the dynamic linker. Finally, the described scenario on aarch64-linux is not deterministic. The behavior depends on the dynamic linker being reported as unloaded, which has been classified as a GLIBC bug, so that might get fixed. Ideally this test-case would stop at both *_start in the executable and the dynamic linker, but in absense of a way to specify this reliably (see PR32748), fix this by making this a temporary breakpoint, ensuring that the breakpoint will only trigger once. Approved-by: Kevin Buettner <kevinb@redhat.com> PR testsuite/32743 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32743
2025-02-27gdb, gdbserver, gdbsupport: fix some namespace comment formattingSimon Marchi21-23/+23
I noticed a // namespace selftests comment, which doesn't follow our comment formatting convention. I did a find & replace to fix all the offenders. Change-Id: Idf8fe9833caf1c3d99e15330db000e4bab4ec66c
2025-02-27gdb/dwarf: fix failed assertion in dwarf2_find_containing_comp_unit selftestSimon Marchi1-2/+9
Commit 2f0521c0d6f6 ("gdb/dwarf: fix signature_type created with nullptr section") added some asserts in the dwarf2_per_cu_data constructor to verify that the passed dwarf2_per_bfd and dwarf2_section_info are not nullptr. However, the dummy dwarf2_per_cu_data objects created in the dwarf2_find_containing_comp_unit selftests are passed nullptr for those parameters. I prefer to keep the asserts in place, as protection for the non-test code and as self documentation, so fix this by passing some dummy pointers in the test. Change-Id: Ic7cdc1b976f7506041b651222234eefc998e473a Reviewed-By: Tom de Vries <tdevries@suse.de>
2025-02-27gdb/dwarf: pass unit length to dwarf2_per_cu_data constructorSimon Marchi3-38/+46
Most of the time, the length of a unit is known when constructing a dwarf2_per_cu_data or signatured_type. Add a construtor parameter for it. In the few cases where it isn't, pass 0, which leaves it unset. Change-Id: I0c8b9683164d3e3f3823ed995f71689a4d17fd96 Reviewed-By: Tom de Vries <tdevries@suse.de>
2025-02-26[gdb/build] Fix unused var in dwarf2/read.cTom de Vries1-1/+1
On x86_64-linux, with gcc 7.5.0 I ran into a build breaker: ... gdb/dwarf2/read.c: In function ‘void read_comp_units_from_section()’: gdb/dwarf2/read.c:4297:31: error: unused variable ‘sig_type_it’ \ [-Werror=unused-variable] auto [sig_type_it, inserted] = sig_types.emplace (sig_ptr); ^ ... Fix this by dropping the unused variable. Tested on x86_64-linux, by completing a build.
2025-02-25gdb/dwarf: fix signature_type created with nullptr sectionSimon Marchi2-1/+4
Commit c44ab627b02 ("gdb/dwarf: pass section to dwarf2_per_cu_data constructor") introduced a regression when using dwp. It can be reproduced with: $ make check TESTS="gdb.base/ptype-offsets.exp" RUNTESTFLAGS="--target_board=fission-dwp" Then, to investigate: $ ./gdb -nx -q --data-directory=data-directory testsuite/outputs/gdb.base/ptype-offsets/ptype-offsets -ex 'ptype int' Reading symbols from testsuite/outputs/gdb.base/ptype-offsets/ptype-offsets... /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:3195:38: runtime error: member call on null pointer of type 'struct dwarf2_section_info' Commit c44ab627b02 removed the assignment of signatured_type::section (dwarf2_per_cu_data::section, really) in fill_in_sig_entry_from_dwo_entry with the justification that the section was already set when constructing the signatured_type. Well, that was true except for one spot in lookup_dwp_signatured_type which passes a nullptr section to add_type_unit. Fix that by passing the section to add_type_unit in that one spot. This is the same section that would have been set by fill_in_sig_entry_from_dwo_entry before. Add some asserts in the dwarf2_per_cu_data constructor to verity that the passed dwarf2_per_bfd and dwarf2_section_info are non-nullptr. Change-Id: If27dae6b4727957c96defc058c7e4be31472005b Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32739 Co-Authored-By: Tom de Vries <tdevries@suse.de> Approved-By: Tom Tromey <tom@tromey.com>
2025-02-25gdb/dwarf: convert dwarf2_per_bfd::signatured_types to a gdb::unordered_setSimon Marchi3-136/+102
I'd like to add these asserts in dwarf2_per_cu_data's constructor: gdb_assert (per_bfd != nullptr); gdb_assert (section != nullptr); However, these dummy instances of signatured_type, used as hash table lookup keys, are in the way: signatured_type find_sig_entry (nullptr, nullptr, sect_offset {}, sig); This motivated me to convert the dwarf2_per_bfd::signatured_types hash table to a gdb::unordered_set. This allows finding an entry by simply passing the signature (an integer) and removes the need to create dummy signatured_type objects. There is one small unfortunate pessimization: lookup_dwo_signatured_type, for instance, does a lookup by signature to find an existing signatured_type. If not found, it adds a new one by calling add_type_unit. The current code passes down the slot where to put the new element, avoiding an extra hash when inserting the new signatured_type. With the new code, I don't see a way to do that. This is probably negligible, but it bugs me. If we used a map of signature -> signatured_type, I would see a way, but then it would waste space. I see one change in behavior, that is not really important IMO. In read_comp_units_from_section, if duplicate signature type entries are detected, the code prior to this patch overwrites the existing signatured_type in the hash table with the new one. With this patch, the existing signatured_type is kept: the call to emplace does not insert the value if an existing equal value exists. Other than that, no behavior change expected. Change-Id: I0bef1b49cc63dbdf4e32fa9d4ea37f83025efc3e Approved-By: Tom Tromey <tom@tromey.com>
2025-02-25gdb/dwarf: change some per-objfile functions to be per-bfdSimon Marchi1-31/+31
I identified the following functions that currently take a dwarf2_per_objfile, but could take a less specific dwarf2_per_bfd. - try_open_dwop_file - open_dwo_file - open_dwp_file The uses of the per-objfile object in try_open_dwop_file can be replaced with equivalent per-bfd ones. Change-Id: Ia31fa0b988375e86a715ee863d4ec3c572ce89c0 Approved-By: Tom Tromey <tom@tromey.com>
2025-02-25gdb/dwarf: use dwz_file::filename in a few spotsSimon Marchi2-4/+4
I found a few spots where the existing dwz_file::filename method could be used. Change-Id: I0522b1e3abbfac2f392f9ec777c37b242ee236d8 Approved-By: Tom Tromey <tom@tromey.com>
2025-02-25gdb: move "gdb:function_view" into quick-symbol.h typedefsSimon Marchi12-144/+122
All users of these typedefs use them inside a gdb::function_view. Move the gdb::function_view in the typedefs themselves. This shortens the types in function signatures and helps with readability, IMO. Rename them to remove the `_ftype` suffix: this suffix is not as relevant in C++ as it was in C. With function_view, the caller can pass more than just a simple "function". Anyway, I think it's clearer to name them after the role the callback has (listener, matcher, etc). Adjust some related comments. Change-Id: Iaf9f8ede68b51ea9e4d954792e8eb90def8659a6 Approved-By: Tom Tromey <tom@tromey.com>
2025-02-25gdb/dwarf: initialize tu_stats fieldsSimon Marchi1-7/+7
Initialize fields of tu_stats to 0, remove the explicit default initialization of dwarf2_per_bfd::tu_stats. Change-Id: I98b2d5c4171291a3df2569466559174fb7cf32b6 Approved-By: Tom Tromey <tom@tromey.com>
2025-02-25Remove struct print_one_inferior_dataTom Tromey1-6/+0
struct print_one_inferior_data is not used, so remove it.
2025-02-25gdb/dwarf: remove unused include in read.cSimon Marchi1-1/+0
This include is reported as unused by clangd. Change-Id: I95b73f85607537551ef54e46551197d1371d621b
2025-02-25gdb/amd-dbgapi: add displaced stepping supportSimon Marchi3-0/+239
Implement the target_ops displaced stepping methods to add displaced stepping support when debugging AMD GPU programs. The knowledge of how to prepare and finish displaced steps is provided by the amd-dbgapi library, so the code here is relatively straightforward. No need to parse instructions or handle fixups, that is done by the lib We just need to remember, for each thread doing a displaced step, the displaced stepping id given by the library. Add a test to exercise the new functionality. The compiler generates DWARF that GDB doesn't understand yet [1], so trying to step over a breakpoint with DWARF present gives: (gdb) si Unhandled dwarf expression opcode 0xe9 The test purposefully builds the binary without DWARF info to circumvent this. [1] https://llvm.org/docs/AMDGPUDwarfExtensionsForHeterogeneousDebugging.html Change-Id: I53f459221a42d4b02a6041eadb8cf554500e2162 Approved-By: Lancelot Six <lancelot.six@amd.com> (amdgpu)
2025-02-25gdb: add target displaced stepping supportSimon Marchi6-27/+270
The amd-dbgapi library, used in the AMD GPU port, has the capability to prepare and cleanup displaced step operations. In order to use it, add the following target_ops methods: - supports_displaced_step - displaced_step_prepare - displaced_step_finish - displaced_step_restore_all_in_ptid Prior to this patch, displaced stepping preparation and cleanup is done solely by gdbarches. Update infrun to use these new target methods instead of gdbarch hooks. To keep the behavior for other architectures unchanged, make the default implementations of the new target_ops method forward to the thread's gdbarch. displaced_step_restore_all_in_ptid won't be needed for the AMD GPU port, but was added for completeness. It would be weird for infrun displaced stepping code to call target methods except for that one thing where it calls a gdbarch method. Since this patch only adds infrastructure, no behavior change is expected. Change-Id: I07c68dddb5759a55cd137a711d2679eedc0d9285
2025-02-25gdb/amd-dbgapi: use gdb::unordered_mapSimon Marchi1-2/+3
Since we have gdb::unordered_map, swap std::unordered_map for that. Change-Id: If2ef652fe18c1a440a25cff6131d29e37091bdbe Approved-By: Lancelot Six <lancelot.six@amd.com> (amdgpu)
2025-02-25gdb/remote: Set the thread of the remote before sending qRcmd.Ciaran Woodward1-0/+3
GDB allows remotes to implement extension commands which can be accessed using the 'monitor' command. This allows remotes to implement functionality which does not exist in GDB for whatever reason (doesn't make sense, too specific to one target, etc.) However, before this change, the remote would not necessarily know which thread/inferior was currently selected on the GDB client. This prevents the implementation of any 'monitor' commands which are specific to a single inferior/thread on the remote. This is because GDB informs the remote of the current thread lazily - only when it is relevant to the RSP command next being sent. qRcmd is the underlying RSP command used for monitor commands, so this change ensures that GDB will update the remote with the 'current' thread if it has changed since the remote was last informed. Approved-By: Tom Tromey <tom@tromey.com>
2025-02-25gdb/windows: remove disable_breakpoints_in_shlibs callAndrew Burgess1-1/+0
I noticed that the disable_breakpoints_in_shlibs function disables breakpoints without calling notify_breakpoint_modified. This commit is one step towards fixing this issue. There are currently only two uses of disable_breakpoints_in_shlibs, one in clear_solib (in solib.c), and the other in windows_nat_target::do_initial_windows_stuff (in windows-nat.c). I believe that the call in windows-nat.c can be shown to be redundant, and therefore can be removed. windows_nat_target::do_initial_windows_stuff is called from two places: windows_nat_target::attach and windows_nat_target::create_inferior, these are the target_ops functions used to attach to a running process, or for creating a new process, and are only called from attach_command or run_command_1, both in infcmd.c. Both attach_command and run_command_1 call target_pre_inferior before calling the relevant target_ops function. In target_pre_inferior, so long as the target doesn't have a global solist (and windows doesn't), we always call no_shared_libraries (from solib.c), which calls clear_solib (also in solib.c), which in turn calls disable_breakpoints_in_shlibs. My claim then, is that, any time we reach the disable_breakpoints_in_shlibs call in windows_nat_target::do_initial_windows_stuff, we will have always have called disable_breakpoints_in_shlibs already via clear_solib. I think it should be safe to remove the disable_breakpoints_in_shlibs call from windows_nat_target::do_initial_windows_stuff. There should be no user visible changes. My ultimate goal, which I'll address in follow on commits, is to delete disable_breakpoints_in_shlibs completely. Removing this call means that we only have one disable_breakpoints_in_shlibs call remaining in GDB. Testing for this change has been minimal. My only Windows build machine is not great, and I've never managed to get DejaGNU running in that environment. This commit builds, and a few basic, manual tests seem fine, but beyond that, this change is untested. Approved-By: Tom Tromey <tom@tromey.com>
2025-02-25gdb: don't show incorrect source file in source windowTom de Vries4-18/+129
Consider the test-case sources main.c and foo.c: $ cat main.c extern int foo (void); int main (void) { return foo (); } $ cat foo.c extern int foo (void); int foo (void) { return 0; } and main.c compiled with debug info, and foo.c without: $ gcc -g main.c -c $ gcc foo.c -c $ gcc -g main.o foo.o In TUI mode, if we run to foo: $ gdb -q a.out -tui -ex "b foo" -ex run it gets us "[ No Source Available ]": ┌─main.c─────────────────────────────────────────┐ │ │ │ │ │ │ │ [ No Source Available ] │ │ │ │ │ └────────────────────────────────────────────────┘ (src) In: foo L?? PC: 0x400566 ... Breakpoint 1, 0x0000000000400566 in foo () (gdb) But after resizing (pressing ctrl-<minus> in the gnome-terminal), we get instead the source for main.c: ┌─main.c─────────────────────────────────────────┐ │ 3 int │ │ 4 main (void) │ │ 5 { │ │ 6 return foo (); │ │ 7 } │ │ │ │ │ └────────────────────────────────────────────────┘ (src) In: foo L?? PC: 0x400566 ... Breakpoint 1, 0x0000000000400566 in foo () (gdb) which is inappropriate because we're stopped in function foo, which is not in main.c. The problem is that, when the window is resized, GDB ends up calling tui_source_window_base::rerender. The rerender function has three cases, one for when the window already has some source code content (which is not the case here), a case for when the inferior is active, and we have a selected frame (which is the case that applies here), and a final case for when the inferior is not running. For the case which we end up in, the source code window has no content, but the inferior is running, so we have a selected frame, GDB calls the get_current_source_symtab_and_line() function to get the symtab_and_line for the current location. The get_current_source_symtab_and_line() will actually return the last recorded symtab and line location, not the current symtab and line location. What this means, is that, if the current location has no debug information, get_current_source_symtab_and_line() will return any previously recorded location, or failing that, the default (main) location. This behaviour of get_current_source_symtab_and_line() also causes problems for the 'list' command. Consider this pure CLI session: (gdb) break foo Breakpoint 1 at 0x40110a (gdb) run Starting program: /tmp/a.out Breakpoint 1, 0x000000000040110a in foo () (gdb) list 1 extern int foo (void); 2 3 int 4 main (void) 5 { 6 return foo (); 7 } (gdb) list . Insufficient debug info for showing source lines at current PC (0x40110a). (gdb) However, if we look at how GDB's TUI updates the source window during a normal stop, we see that GDB does a better job of displaying the expected contents. Going back to our original example, when we start GDB with: $ gdb -q a.out -tui -ex "b foo" -ex run we do get the "[ No Source Available ]" message as expected. Why is that? The answer is that, in this case GDB uses tui_show_frame_info to update the source window, tui_show_frame_info is called each time a prompt is displayed, like this: #0 tui_show_frame_info (fi=...) at ../../src/gdb/tui/tui-status.c:269 #1 0x0000000000f55975 in tui_refresh_frame_and_register_information () at ../../src/gdb/tui/tui-hooks.c:118 #2 0x0000000000f55ae8 in tui_before_prompt (current_gdb_prompt=0x31ef930 <top_prompt+16> "(gdb) ") at ../../src/gdb/tui/tui-hooks.c:165 #3 0x000000000090ea45 in std::_Function_handler<void(char const*), void (*)(char const*)>::_M_invoke (__functor=..., __args#0=@0x7ffc955106b0: 0x31ef930 <top_prompt+16> "(gdb) ") at /usr/include/c++/9/bits/std_function.h:300 #4 0x00000000009020df in std::function<void(char const*)>::operator() (this=0x5281260, __args#0=0x31ef930 <top_prompt+16> "(gdb) ") at /usr/include/c++/9/bits/std_function.h:688 #5 0x0000000000901c35 in gdb::observers::observable<char const*>::notify (this=0x31dda00 <gdb::observers::before_prompt>, args#0=0x31ef930 <top_prompt+16> "(gdb) ") at ../../src/gdb/../gdbsupport/observable.h:166 #6 0x00000000008ffed8 in notify_before_prompt (prompt=0x31ef930 <top_prompt+16> "(gdb) ") at ../../src/gdb/event-top.c:518 #7 0x00000000008fff08 in top_level_prompt () at ../../src/gdb/event-top.c:534 #8 0x00000000008ffdeb in display_gdb_prompt (new_prompt=0x0) at ../../src/gdb/event-top.c:487 If we look at how tui_show_frame_info figures out what source to display, it doesn't use get_current_source_symtab_and_line(), instead, it finds a symtab_and_line directly from a frame_info_pt. This means we are not dependent on get_current_source_symtab_and_line() returning the current location (which it does not). I propose that we change tui_source_window_base::rerender() so that, for the case we are discussing here (the inferior has a selected frame, but the source window has no contents), we move away from using get_current_source_symtab_and_line(), and instead use find_frame_sal instead, like tui_show_frame_info does. This means that we will always use the inferior's current location. Tested on x86_64-linux. Reviewed-By: Tom de Vries <tdevries@suse.de> Reported-By: Andrew Burgess <aburgess@redhat.com> Co-Authored-By: Andrew Burgess <aburgess@redhat.com> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32614
2025-02-24[gdb/testsuite] Exit left-over gdb in gdb.mi/mi-break.expTom de Vries9-38/+92
After test-case gdb.mi/mi-break.exp, a gdb instance is left running. The test-case starts two instances using mi_clean_restart, one using separate-mi-tty. For each instance, gdb_exit is called once, from two different locations: - mi_clean_restart, and - gdb_finish. But this doesn't seem to be effective for the separate-mi-tty case. Fix this by calling gdb_mi_exit at the end of proc test_break. Likewise in a few more more test-case. Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com> PR testsuite/32709 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32709
2025-02-24Use ui_out for "info checkpoints"Kevin Buettner1-33/+92
In his review of my recent checkpoint work (commit e5501dd4321), Andrew Burgess suggested that I use GDB's structured table generation mechanism for the "info checkpoints" command. This patch does that. Andrew also recommended using print_stack_frame() for the "Frame" column. I tried this, but ran into some problems, which are described in a comment in the code. I got it to mostly work, except for the case when the current/active fork is running. Switching context away from and then back to a running fork doesn't work. It could, perhaps, be made to work, but I'm not convinced that the checkpoint facility is important enough to expend the effort for this case. So, instead, I simply adapted the existing checkpoint frame printing code to use the ui_out machinery instead of gdb_printf. Approved-By: Tom Tromey <tom@tromey.com>
2025-02-24gdb/styling: only check TERM environment once, during initialisationAndrew Burgess5-21/+113
We currently check the TERM environment variable any time we call one of the ui_file::can_emit_style_escape() functions. This seems excessive. During GDB's startup we also check for the NO_COLOR environment variable and disable styling if this is set. I propose that we combine these two checks, and perform them just once during startup (as the current NO_COLOR check is currently done). As with the NO_COLOR check, if the TERM variable is set to "dumb" indicating that styling is not supported then we should just set cli_styling to false. This does mean that the user can then 'set style enabled on', even for a dumb terminal, which was not possible previously. Before this commit the "dumb" terminal check was separate and would prevent styling even if 'set style enabled on' was in effect. Of course, trying to turn on styling in a dumb terminal might not give the results that a user hope for. And so, I have implemented a check in `set_style_enabled`, so in a dumb terminal a user will see this: (gdb) set style enabled on warning: The current terminal doesn't support styling. Styled output might not appear as expected. After which GDB will try to emit styling. We could, potentially, prevent styling being enabled instead of emitting a warning, but I'm inclined to let the user turn on styling if they really want to. Approved-By: Kevin Buettner <kevinb@redhat.com> Acked-By: Tom Tromey <tom@tromey.com>
2025-02-24gdb/tui: use correct setting to control asm window stylingAndrew Burgess3-5/+85
Currently the TUI's asm window uses `source_styling` to control styling. This setting is supposed to be for styling of source files though, and the asm window displays disassembler output. We have a different setting for this `disassemble_styling`, which is controlled with 'set style disassembler enabled on|off'. Switch to use the correct control variable. I've written a new test for this, but this required some additions to the tuiterm library in order to grab character attributes for a screen region. Approved-By: Tom Tromey <tom@tromey.com>
2025-02-24gdb/doc: fix help text for 'set style disassembler enabled'Andrew Burgess1-3/+11
The help text for 'set/show style disassembler enable' was output of date. It talks about GDB requiring the Python Pygments library, but for many common architectures this is no longer the case, libopcode is used for styling. The Python Pygments library is still used as a fallback for those architectures that libopcode doesn't currently style. I've updated the help text to try and explain all this. The manual was already updated. Approved-By: Eli Zaretskii <eliz@gnu.org>
2025-02-24[gdb/doc] Fix documentation of handle SIGKILLTom de Vries1-1/+1
Here ( https://sourceware.org/gdb/current/onlinedocs/gdb.html/Signals.html ) I read: ... GDB has the ability to detect any occurrence of a signal in your program. You can tell GDB in advance what to do for each kind of signal. ... However, here ( https://man7.org/linux/man-pages/man2/ptrace.2.html ) I read: ... While being traced, the tracee will stop each time a signal is delivered, even if the signal is being ignored. (An exception is SIGKILL, which has its usual effect.) ... So, it seems to be that for SIGKILL we can't tell GDB in advance what to do. Fix the documentation to reflect this. Approved-By: Eli Zaretskii <eliz@gnu.org> PR gdb/32714 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32714
2025-02-24gdb, testsuite, rust: fix for empty arrayRudnicki, Piotr2-1/+5
For the Rust language, to avoid segmentation fault in case of an empty array, do not try to copy any elements, but allocate and return the empty array immediately. With the command before the change, gdb crashes with message: (gdb) set lang rust (gdb) p [1;0] Fatal signal: Segmentation fault After the fix in this commit, gdb shows following message: (gdb) set lang rust (gdb) p [1;0] $1 = [] Update the existing test case gdb.rust/expr.exp to verify the change. Approved-By: Tom Tromey <tom@tromey.com>
2025-02-24gdb/testsuite/lib/rocm.exp: Fix a typo in a commentShahab Vahedi1-1/+1
"Check we have ..." --> "Check if we have ..." This is for consistency with the previous comment and the code downstream.
2025-02-24gdb: handle empty locspec when printing breakpointsAndrew Burgess3-25/+72
For background reading, please see the previous patch, and the patch before that! After the last two patches, internal breakpoints can now be marked as shlib_disabled if the library in which they are placed is unloaded. The patch before last discusses a situation related to the gdb.base/nostdlib.exp test, when run on a GNU/Linux glibc based system where executables are compiled as PIE by default. In this case it is observed that the dynamic linker will actually report itself as unloaded (i.e. remove itself from the list of currently loaded shared libraries). This behaviour is likely a bug in the dynamic linker, but this behaviour exists in released versions of the dynamic linker, so GDB should (if the cost is not too great) be changed to handle this situation. This commit handles a problem with the 'maint info breakpoints' command. When the dynamic linker is unloaded the 'shlib event' breakpoint is marked as shlib_disabled (i.e. placed into the pending state). When displaying the breakpoint in the 'maint info breakpoints' output, GDB will try to print the locspec (location_spec *) as a string Unfortunately, the locspec will be nullptr as the internal breakpoints are not created via a location_spec, this means that GDB ends up trying to call location_sepc::to_string() on a nullptr, resulting in undefined behaviour (and a crash). For most internal breakpoint types this is not a problem. If we consider bp_longjmp_master for example, if the shared library containing a breakpoint of this type is unloaded then first GDB marks the breakpoint as shlib_disabled, then after unloading the shared library breakpoint_re_set is called, which will delete the internal breakpoint, and then try to re-create it (if needed). As a result, the user never gets a change to run 'maint info breakpoints' on a bp_longjmp_master breakpoint in the shlib_disabled state. But bp_shlib_event and bp_thread_event breakpoints are not deleted and recreated like this (see internal_breakpoint::re_set), so it is possible, in rare cases, that we could end up trying to view one of these breakpoint in a shlib_disabled state, and it would be nice if GDB didn't crash as a result. I've updated the printing code to check for and handle this case, and I've updated the docs to mention this (rare) case. For testing, I've extended gdb.base/nostdlib.exp to compile as pie and nopie, and then run 'maint info breakpoints'. If we're running on a buggy glibc then this will trigger the crash. I don't know how I can trigger this problem without a buggy glibc as this would require forcing the dynamic linker to be unloaded. Reviewed-By: Eli Zaretskii <eliz@gnu.org> Approved-By: Tom Tromey <tom@tromey.com>
2025-02-24gdb: disable internal b/p when a solib is unloadedAndrew Burgess2-6/+49
Bug PR gdb/32079 highlights an issue where GDB will try to remove a breakpoint for a shared library that has been unloaded. This will trigger an error from GDB like: (gdb) next 61 dlclose (handle[dl]); (gdb) next warning: error removing breakpoint 0 at 0x7ffff78169b9 warning: error removing breakpoint 0 at 0x7ffff7730b57 warning: error removing breakpoint 0 at 0x7ffff7730ad3 54 for (dl = 0; dl < 4; ++dl) (gdb) What happens is that as the inferior steps over the dlclose() call, GDB notices that the library has been unloaded and calls disable_breakpoints_in_unloaded_shlib. However, this function only operates on user breakpoints and tracepoints. In the example above what is happening is that the test loads multiple copies of libc into different linker namespsaces. When we 'next' over the dlclose call one of the copies of libc is unloaded. As GDB placed longjmp master breakpoints within the copy of libc that was just unloaded, the warnings we see are GDB trying (and failing) to remove these breakpoints. I think the solution is for disable_breakpoints_in_unloaded_shlib to handle all breakpoints, even internal ones like the longjmp master breakpoints. If we do this then the breakpoint will be marked as shlib_disabled and also will be marked as not inserted. Later when we call breakpoint_re_set() and the longjmp breakpoints are deleted we will no longer try to remove them. This solution is inspired by a patch suggested in the bug report: https://sourceware.org/bugzilla/show_bug.cgi?id=32079#c3 There are some differences with my approach compared to the patch suggested in the bug. First I have no need to delete the breakpoint inside disable_breakpoints_in_unloaded_shlib as an earlier patch in this series arranged for breakpoint_re_set to be called when shared libraries are removed. Calling breakpoint_re_set will take care of deleting the breakpoint for us. For details see the earlier commit titled: gdb: fixes for code_breakpoint::disabled_by_cond logic Next, rather than only handling bp_longjmp and bp_longjmp_master, I allow all breakpoints to be handled. I also only give the warning about disabling breakpoints for user breakpoints, I don't see the point of warning the user about internal b/p changes. With this done the issues in PR gdb/32079 are resolved. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32079 Tested-By: Hannes Domani <ssbssa@yahoo.de> Approved-By: Tom Tromey <tom@tromey.com>
2025-02-24gdb: don't clear inserted flag in disable_breakpoints_in_unloaded_shlibAndrew Burgess1-4/+15
This commit removes the clearing of bp_location::inserted from disable_breakpoints_in_unloaded_shlib, my claim is that this call is not needed (any more), and with the next commit, this line actually causes some problems. The disable_breakpoints_in_unloaded_shlib function was added back in 2004 with commit 84acb35a5a97c, and from this first version the function cleared the bp_location::inserted flag. The motivation for this is that the shared library might have already been unmapped, in which case, a later attempt to remove the location could fail. In 2013 a similar function disable_breakpoints_in_freed_objfile was added. This function also cleared bp_location::inserted for similar reasons. This code was added in commit: commit 63644780babdca3f40e1978a236b6cd78473c91b Date: Tue Mar 12 11:10:18 2013 +0100 New remove-symbol-file command. Then in 2014 the clearing of bp_location::inserted was removed from disable_breakpoints_in_freed_objfile in the commit: commit 08351840eabb44799e3d01026610420758f4fa40 Date: Tue Apr 22 23:19:19 2014 +0100 Stale breakpoint instructions, spurious SIGTRAPS. The reason that clearing the ::inserted flag was removed in this commit is that if the disable_breakpoints_in_freed_objfile function was called when the b/p were actually inserted, and the memory for the associated objfile wasn't actually unmapped, then we could end up leaving breakpoints inserted into the inferior, which leads to spurious SIGTRAPs. In the next commit I'll change disable_breakpoints_in_unloaded_shlib so that all breakpoints, not just user breakpoints, will be disabled (via shlib_disabled) when a shared library is unloaded. This addresses PR gdb/32079, see the next commit for a fuller justification for this change. The problem is that when I tested the next commit I ran into some regressions from the gdb.base/nostdlib.exp test when run on an AArch64 GNU/Linux system where executables are compiled as PIE by default. This test compiles a simple binary with the -nostdlib flag. What happens is this: - The executable is compiled as PIE, this means that we get a dynamically linked executable, the dynamic linker is used to perform the PIE relocation, but the executable uses no other shared libraries. - When GDB starts the inferior, initially the dynamic linker is discovered as a shared library being used by the application, GDB loads in the library and its debug symbols, placing the internal "shlib event" breakpoints so that future shared library events can be tracked. - For the target I tested on systemtap probes were not used, instead GDB fell back to the old style even breakpoint. - As the inferior progresses, after the PIE relocation has been performed, the dynamic linker performs some house keeping on the list of shared libraries being used by the application. During this process the dynamic linker is removed from the list of shared libraries being used by the inferior, this causes GDB see a shared library event, which GDB understands to mean that it should unload the dynamic linker from the inferior. I spoke with the glibc engineers at RH, and the feeling is that this is likely a bug (it's still being investigated). But I don't think it really matters if this is a bug or not. There are versions of glibc in the wild that have this behaviour, so GDB should (if the cost is not too great) be updated to handle this. Obviously after removing the dynamic linker from the list of shared libraries, the dynamic linker is not actually unmapped, that would not be possible, it's the dynamic linker that does the unmapping, so the dynamic linker is left mapped into the inferior's address space. - With the next patch in place all breakpoints (user and internal) within the dynamic linker are disabled (shlib_disabled) and currently marked as not inserted (bp_location::inserted flag is cleared). - Having processed the shared library event GDB then resumes the inferior. As the shared library event is not a full stop of the inferior (i.e. we don't remove all breakpoints before handling the event), all of the breakpoints in the dynamic linker are still inserted, but are now marked as not-inserted. - GDB then resumes the inferior and immediately hits the breakpoint that is still inserted. As GDB thinks this breakpoint is not inserted, this is reported to the user as a SIGTRAP. The fix I think is just to not clear the bp_location::inserted flag in disable_breakpoints_in_unloaded_shlib. This will leave the breakpoint as inserted in the case above. GDB will now be able to successfully resume the inferior after the shared library event (knowing there is a breakpoint inserted GDB will step over it and continue as expected). The next time the inferior performs a full stop the now shlib_disabled breakpoint will be removed from the inferior we would want. For the usual case, where a shared library is being unloaded due to say a dlclose, the breakpoints in the library will be marked as disabled, but will be left inserted. The next time remove_breakpoints is called GDB will try to remove those breakpoint locations. If the removal fails, as the breakpoint is marked shlib_disabled, GDB will hide the error message from the user and just assume that the shared library has been unmapped. This functionality was first added in 2008 in commit 879d1e6b4674bc8. There are two aspects to testing this change. First whether no clearing the ::inserted flag causes general problems. That is tested by running the full testsuite (I see no regressions). Then there is the specific problem that caused me to make this change. That issue only occurs on AArch64, with GNU/Linux using glibc, when the executable is compiled as PIE, and doesn't use any shared libraries other than the dynamic linker (which can be the gdb.base/nostdlib.exp test if run on the right system). What I don't know is how to recreate this setup in a more general form. We can't use add-symbol-file/remove-symbol-file as that passes through disable_breakpoints_in_freed_objfile instead, which the ::installed flag is already not adjusted. Also the bug doesn't trigger on x86 targets due to code in handle_signal_stop which sees the inserted breakpoint, and decides this must be a breakpoint that actually exists in the program, and then because gdbarch_decr_pc_after_break returns non-zero for x86, GDB steps the inferior past the breakpoint. This is the big difference from AArch64 where gdbarch_decr_pc_after_break returns zero, and so the inferior gets stuck hitting the unexpectedly inserted breakpoint. Approved-By: Tom Tromey <tom@tromey.com>
2025-02-24gdb: handle dprintf breakpoints when unloading a shared libraryAndrew Burgess2-7/+121
While working on the previous commit I realised that GDB would not handle dprintf breakpoints correctly when a shared library was unloaded. Consider this example using the test binary from shlib-unload.exp. In the function 'foo' we create a dprintf is in a shared library: (gdb) b 59 Breakpoint 1 at 0x401215: file /tmp/projects/binutils-gdb/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/shlib-unload.c, line 59. (gdb) r Starting program: /tmp/projects/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/shlib-unload/shlib-unload Breakpoint 1, main () at /tmp/projects/binutils-gdb/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/shlib-unload.c:59 59 res = dlclose (handle); /* Break here. */ (gdb) dprintf foo,"In foo" Dprintf 2 at 0x7ffff7fc50fd: file /tmp/projects/binutils-gdb/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/shlib-unload-lib.c, line 23. (gdb) n Error in re-setting breakpoint 2: Function "foo" not defined. warning: error removing breakpoint 2 at 0x7ffff7fc50fd warning: error removing breakpoint 2 at 0x7ffff7fc50fd warning: error removing breakpoint 2 at 0x7ffff7fc50fd warning: error removing breakpoint 2 at 0x7ffff7fc50fd warning: error removing breakpoint 2 at 0x7ffff7fc50fd warning: error removing breakpoint 2 at 0x7ffff7fc50fd warning: error removing breakpoint 2 at 0x7ffff7fc50fd warning: error removing breakpoint 2 at 0x7ffff7fc50fd Cannot remove breakpoints because program is no longer writable. Further execution is probably impossible. 60 assert (res == 0); (gdb) What happens here is that as the inferior steps over the dlclose call the shared library containing 'foo' is unloaded and disable_breakpoints_in_unloaded_shlib is called. However in disable_breakpoints_in_unloaded_shlib we have this check: if (b.type != bp_breakpoint && b.type != bp_jit_event && b.type != bp_hardware_breakpoint && !is_tracepoint (&b)) continue; As the dprintf has type bp_dprintf then this check triggers and we ignore the dprintf, meaning the dprintf is not disabled. When the inferior stops after the 'next' GDB tries to remove all breakpoints but the dprintf can no longer be removed, the memory in which it was placed has been unmapped from the inferior. The fix is to start using is_breakpoint() in disable_breakpoints_in_unloaded_shlib instead of the bp_breakpoint and bp_hardware_breakpoint checks. The is_breakpoint() function also checks for bp_dprintf. With this fix in place GDB now correctly disables the breakpoint and we no longer see the warning about removing the breakpoint. During review it was pointed out that PR gdb/23149 and PR gdb/20208 both describe something similar, though for these bugs, the inferior is restarted (which unloads all currently loaded shlib) rather than passing over the dlclose. But the consequences are pretty similar. I've included a test which covers this case. One additional thing that these two bugs did show though is that disable_breakpoints_in_shlibs also needs to start using is_breakpoint for the same reason. Without this change, when an inferior is restarted we get a warning like this for dprintf breakpoints: warning: Temporarily disabling breakpoints for unloaded shared library "..." but we don't get a similar warning for "normal" breakpoints. This is because disable_breakpoints_in_shlibs is called from clear_solib, which is called when an inferior is restarted. It is best not to think too hard about disable_breakpoints_in_shlibs, as this function is pretty broken, e.g. it doesn't call notify_breakpoint_modified, despite modifying the breakpoints. But for now I'm ignoring that, but fixing this is definitely on my list for my next set of breakpoint related fixes, it's just that a lot of these breakpoint fixes end up being depending on one another, but I want to avoid making this series too long. So for now, I'm ignoring the existing bug (missing breakpoint modified events), and fixing disable_breakpoints_in_shlibs to cover dprintf. With these fixes in place, the two bugs mentioned above should be fixed. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=23149 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=20208 Tested-By: Hannes Domani <ssbssa@yahoo.de> Approved-By: Tom Tromey <tom@tromey.com>