Alan Modra [Thu, 13 Feb 2025 01:46:26 +0000 (12:16 +1030)]
dlltool memory leaks
dlltool copies strings with strdup all over the place, seeming to take
the attitude that anything might be modified. That leads to lots of
memory leaks. Fixing the leaks by removing the strdup calls of course
means you need to take good care that strings *aren't* modified. This
isn't as easy as it sounds due to functions like xlate that have
const char* params but then manage to modify the strings. I've fixed
xlate, but if I've missed something somewhere then this patch likely
will break dlltool. Testsuite coverage of dlltool isn't good.
The leaks in defparse.y are small. It also is a little work to verify
that all the strings I'm freeing in defparse.y are in fact malloc'd,
which is no doubt why the leaks are there.
Using bfd_xalloc in make_one_lib_file and functions called from there
results in memory being freed automatically at the bfd_close in
make_one_lib_file, without any fuss.
The patch also makes use of xasprintf to replace xmalloc followed by
sprintf.
* defparse.y (opt_name2): Free incoming ID strings after
adding prefix/suffix.
* dlltool.c (struct ifunct): Constify char* fields.
(struct iheadt, struct dlist): Likewise.
(set_dll_name_from_def, def_heapsize, def_stacksize),
(def_section, assemble_file): Use xasprintf.
(def_name, def_library): Free dll_name and name.
(def_description, new_directove): Don't strdup incoming args.
(append_import): Likewise.
(def_import): Free module after appending dllext.
(run): Free temp_base.
(scan_filtered_symbols): Don't segfault on NULL strchr return.
Remove unnecessary strdup.
(scan_drectve_symbols): Likewise. Constify pointers.
Use bfd_malloc_and_get_section. Use xmemdup.
(add_excludes): Use xasprintf and xstrdup.
(gen_exp_file): Free xlate return. Constify pointer to suit
struct changes. Free copy.
(xlate): Always copy arg. Use xasprintf and xstrdup.
(make_imp_label): Add bfd arg. Use bfd_xalloc.
(gen_lib_file): Adjust to suit.
(make_one_lib_file): Likewise. Use bfd_xalloc for section data
and relocs. Simplify code calling xlate, and free xlate return.
(dll_name_list_free_contents): Flatten recursion.
(mangle_defs): Free d_export_vec.
(main): Formatting. Use xasprintf.
* resres.c (write_res_id): Free section data.
Alan Modra [Thu, 13 Feb 2025 00:29:51 +0000 (10:59 +1030)]
gas: replace bfd_alloc with notes_alloc
bfd_alloc can return NULL on out-of-memory so code needs to check the
return value and print an error. That check was missing in write.c.
notes_alloc won't return NULL, instead the underlying obstack_alloc
prints an OOM message and the process exits. This is more convenient,
and when the bfd_alloc memory is attached to the gas output bfd it is
released only slightly before the notes obstack.
* config/obj-macho.c (obj_mach_o_set_indirect_symbols): Use
notes_calloc rather than bfd_zalloc.
* write.c (set_symtab): Use notes_alloc.
Alan Modra [Wed, 12 Feb 2025 21:55:01 +0000 (08:25 +1030)]
gas obj-coff memory leaks
This patch addresses memory leaks in gas that show up when running the
testsuite on x86_64-w64-mingw32. The seh_ctx_cur, and weak sym naming
leaks can occur many times during assembly. The symbol hook and
section leaks are not so important since this memory needs to persist
until closing the output bfd.
* config/obj-coff-seh.c (do_seh_endproc): Free seh_ctx_cur and
its fields.
* config/obj-coff-seh.h (struct seh_context): Remove unused
"next" field.
* config/obj-coff.c (coff_obj_symbol_new_hook): Use notes_alloc
for aux entries.
(coff_obj_symbol_clone_hook): Likewise.
(obj_coff_def): Don't strdup name unless we need to do so
for tc_canonicalize_symbol_name. Free after making symbol.
(weak_name2altname, weak_altname2name): Return a char*.
(weak_uniquify): Use notes_concat.
(pecoff_obj_set_weak_hook, pecoff_obj_clear_weak_hook): Free name
returned by weak_name2altname.
(coff_frob_symbol): Similarly for weak_altname2name.
(obj_coff_section): Use notes_memdup0.
* symbols.h: Add include guard.
(notes_memdup0): New inline function.
Tom Tromey [Thu, 13 Feb 2025 03:43:38 +0000 (20:43 -0700)]
Remove assumption from py-symbol.exp
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>
Kevin Buettner [Thu, 13 Feb 2025 17:53:17 +0000 (10:53 -0700)]
Update my maintenance areas in MAINTAINERS file
I've dropped maintenance of the mep target. Additionally, I'm removed
myself as an authorized committer for PowerPC, ia64, AIX, and
GNU/Linux PPC native.
gdb, testsuite: Rename set_sanitizer procedures to append_environment.
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.
Tom Tromey [Wed, 12 Feb 2025 15:49:30 +0000 (08:49 -0700)]
Reorder gnatmake arguments in inline-section-gc.exp, again
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.
Rohr, Stephan [Thu, 1 Aug 2024 17:46:18 +0000 (19:46 +0200)]
gdb: remove check for minimal symbols in 'start_command'
GDB aborts the 'start' command if the minimal symbols cannot be
resolved. On Windows, GDB reads the minimal symbols from the COFF
header of the PE file. The symbol table is deprecated and the
number of symbols in the COFF header may be zero:
FILE HEADER VALUES
8664 machine (x64)
E number of sections 66E889EC time date stamp Mon Sep 16 21:41:32 2024
FB400 file pointer to symbol table
0 number of symbols
F0 size of optional header
22 characteristics
GDB is not able to read the minimal symbols; the `start' command fails
with an error:
(gdb) start
No symbol table loaded. Use the "file" command.
Manually inserting a breakpoint in main works fine:
(gdb) tbreak main
Temporary breakpoint 1 at 0x14000100c: file test.cpp, line 6.
(gdb) run
Starting program: C:\test-clang
Temporary breakpoint 1, main () at test.cpp:6
6 std::cout << "Hello World.\n";
Remove the check entirely; a 'NOT_FOUND_ERROR' is thrown if 'main'
cannot be resolved. The error is consumed in 'create_breakpoint ()'
and an error message is displayed to the user.
Approved-by: Kevin Buettner <kevinb@redhat.com> Reviewed-By: Guinevere Larsen <guinevere@redhat.com>
Simon Marchi [Mon, 10 Feb 2025 16:54:58 +0000 (11:54 -0500)]
gdb/dwarf: rename cooked_index::m_vector to m_shards
I think that is clearer and helps readability.
Rename a few iteration variables from "index" or "idx" to "shard". In
my mental model, the "index" is the whole thing, so it's confusing to
use that word when referring to shards.
Change-Id: I208cb839e873c514d1f8eae250d4a16f31016148 Approved-By: Tom Tromey <tom@tromey.com>
Simon Marchi [Mon, 10 Feb 2025 16:54:57 +0000 (11:54 -0500)]
gdb/dwarf: remove cooked_index::vec_type
I find this typedef to be confusing. The name is a bit too generic, so
it's not clear what it represents. When using the typedef for a
cooked_index_shard unique pointer, I think that spelling out the vector
type is not overly long.
Change-Id: I99fdab5cd925c37c3835b466ce40ec9c1ec7209d Approved-By: Tom Tromey <tom@tromey.com>
Kito Cheng [Mon, 20 Jan 2025 11:24:36 +0000 (19:24 +0800)]
RISC-V: Add .bfloat16 directive
RISC-V already support bfloat16 instruciton like Zfbfmin, Zvfbfmin and
Zvfbfwma, so I think it's reasonable to add .bfloat16 directive to
support bfloat16 data type.
And the code logic mostly support by common code already.
Nelson Chu [Thu, 6 Feb 2025 13:47:37 +0000 (21:47 +0800)]
RISC-V: Move all global static target stuff into private data for disassembler.
I got a request said that the JDK multi-thread compiler may be broken
if two or more threads are trying to print/disassemble stuff, and filling
the disassemble_info, setting callbacks, and grabbing the function pointer
to disasm at the same time. Since such as the target global static stuff,
including subset of extensions and mapping symbol stuff, seems to only be
one globally. Ideally, for dis-assembler, all global static target stuff
should/can be better to be defined into the target private data, since they
are target-dependency.
opcodes/
* riscv-dis.c: Moved all global static target-dependency stuff into
riscv_private_data, including architecture and mapping symbol stuff.
(set_default_riscv_dis_options): Updated since global static target-
dependency stuff are moved into riscv_private_data.
(parse_riscv_dis_option_without_args): Likewise.
(parse_riscv_dis_option): Likewise.
(parse_riscv_dis_options): Likewise.
(maybe_print_address): Likewise.
(print_reg_list): Likewise.
(riscv_get_spimm): Likewise.
(print_insn_args): Likewise.
(riscv_disassemble_insn): Likewise.
(riscv_update_map_state): Likewise.
(riscv_search_mapping_symbol): Likewise.
(riscv_data_length): Likewise.
(print_insn_riscv): Likewise. Call the riscv_init_disasm_info before
parsing any disassembler options, since the related stuff are moved
into riscv_private_data.
(riscv_init_disasm_info): Likewise. Parse and set the architecture
string and privileged spec version since riscv_get_disassembler is
no longer needed.
(riscv_get_disassembler): Removed.
(disassemble_free_riscv): Only free the subset_list if
riscv_private_data exsits.
* disassemble.c (disassembler): Since riscv_get_disassembler is
removed, call to print_insn_riscv.
* disassemble.h: Removed extern riscv_get_disassembler.
Flavio Cruz [Mon, 3 Feb 2025 04:15:22 +0000 (23:15 -0500)]
Port GDB to Hurd x86_64.
This port extends the existing i686 port to support x86_64 by reusing
existing code whenever it makes sense.
* gdb/amd64-gnu-tdep.c: Adds logic for handling signal frames and
position of amd64 registers in the different Hurd structs.
The signal code is very similar to i686, except the trampoline code
is adapted.
* gdb/config/i386/nm-i386gnu.h: renamed to gdb/config/i386/nm-x86-gnu.h
and adapt it for x86_64.
* gdb/config/i386/i386gnu.mn: renamed to gdb/config/i386/nm-x86-gnu.mn
and reuse it for x86_64.
* gdb/configure.host: recognize gnu64 as a host.
* gdb/configure.nat: recognize gnu64 host and update existing i386gnu to
reuse the new shared files.
* gdb/configure.tgt: recognize x86_64-*-gnu* triplet and use
amd64-gnu-tdep.c.
* gdb/i386-gnu-tdep.c: added i386_gnu_thread_state_reg_offset that is
copied from i386-gnu-nat.c. This makes it similar to amd64.
* gdb/i386-gnu-nat.c: rename it to x86-gnu-nat.c since we reuse this for
i386 and amd64. Updated REG_ADDR to use one of the structures. Added
VALID_REGISTER to make sure it's a register we can provide at this time
(not all of them are available in amd64). FLAGS_REGISTER is either rfl
or efl depending on the arch. Renamed functions and class from i386 to x86
whenever they can be reused.
Clean up after commit 112cf77b1855 ("MIPS: use is_whitespace()") and
untangle the code flow in the handling of forced size suffixes, noting
that owing to the loop right above the only data `c' can hold at this
point is '\0', '.', or a white-space character. No functional change.
MIPS16/GAS: Reject instructions that end with a dot
Fix a regression from commit 3fb49709438e ("MIPS16/GAS: Fix forced size
suffixes with argumentless instructions") and reject MIPS16 instructions
that end with a dot and no forced size suffix following, e.g.:
Clean up after commit 29c108c96106 ("MIPS: Support `-gnuabi64' target
triplet suffix for 64-bit Linux targets") and discard individual MIPS
"want64=true" settings, the use of which has been superseded by commit 42429eacb42f ("Require a 64-bit bfd_vma for MIPS ELF") back in 2013[1].
I spotted some places where tui_win_info::refresh_window() was being
called when suppress_output was false. This means that there is no
tui_batch_rendering in place on the call stack, and so, after that
commit, we might be performing more wrefresh() calls than necessary.
Before the above commit we would have been calling wnoutrefresh() and,
due to the missing tui_batch_rendering, there might have been a delay
before doupdate() was called.
To (hopefully) make screen updates smoother, this commit adds
tui_batch_rendering in a few places where it is possible that there
might be multiple window updates performed, this will mean the final
write to screen is deferred until the tui_batch_rendering goes out of
scope.
Other than possibly smother screen updates, there should be no user
visible changes after this commit.
Andrew Burgess [Sat, 8 Feb 2025 21:32:05 +0000 (21:32 +0000)]
gdb/tui: remove unnecessary wmove call from tui_status_window
I've been looking recently at when the TUI calls wnoutrefresh vs
wrefresh, and the ordering of other screen update actions relative to
these calls.
I noticed in tui_status_window::rerender() a call to wmove() that is
placed after the refresh_window() call. This surely means that the
cursor is moved, but, this update is not sent to the screen.
But we call wmove() at the start of tui_status_window::rerender()
before anything is sent to the screen, so the final wmove() call is
pointless as far as I can tell.
I propose removing it. This is trivial, but removing pointless work
like this slowly makes the TUI code easier to understand.
There should be no user visible changes after this commit.
Guinevere Larsen [Mon, 13 Jan 2025 17:04:04 +0000 (14:04 -0300)]
gdb: Deprecate stabs debug info
GCC has deprecated stabs generation in GCC 12 and entirely removed it in
GCC 13, which was released in April 2023. At the time it was proposed
that GDB deprecate stabs as well, but the decision was to support it a
bit longer. With this patch, it'll be deprecated on GDB 17, and removed
on GDB 18, which following the current cadence, will be released early
2026, meaning we will have supported stabs for nearly 3 years longer
than GCC, which I think is reasonable.
As pointed out in the previous discussion on this topic[1], there are
several existing issues on the code, and none of the current maintainers
knows how to fix it. Unless someone steps up to fix this before the
removal on GDB 18, I don't see why we should keep this old code that
breaks all conventions of modern debuginfo readers and doesn't even
work, instead of being able to further advance adjacent code.
Finally, deprecating and removing stabs will make a.out/dbx inferiors be
essentially unsupported, as the only debuginfo GDB supports for those
formats is stabs, meaning users would only have assembly-level debugging
for that format. With that in mind, this commit deprecates the a.out/dbx
format as well.
Simon Marchi [Sun, 9 Feb 2025 05:51:04 +0000 (00:51 -0500)]
gdb/dwarf: create multiple cooked index shards when reading .debug_names
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>
Simon Marchi [Sun, 9 Feb 2025 05:51:02 +0000 (00:51 -0500)]
gdb/dwarf: allow for cooked_index_shard::m_addrmap to be nullptr
The following patch makes the .debug_names reader create multiple cooked
index shards, only one of them having an address map. The others will
have a nullptr address map.
Change the code using cooked_index_shard::m_addrmap to account for the
fact that it can be nullptr.
Change-Id: Id05b974e661d901dd43bb5ecb3a8fcfc15abc7ed Approved-By: Tom Tromey <tom@tromey.com>
Simon Marchi [Sun, 9 Feb 2025 05:51:01 +0000 (00:51 -0500)]
gdb/dwarf: write offset to parent entry for DW_IDX_parent
New in v2:
- add doc
- fix computation of offset in entry pool
Due to a mistake in the DWARF 5 spec, the way that GDB interprets
DW_IDX_parent when generating and reading .debug_names is not correct.
In Section 6.1.1.2, the parent index entry attribute is described as:
Parent debugging information entry, a reference to the index entry for
the parent. This is represented as the offset of the entry relative to
the start of the entry pool.
But in Table 6.1, DW_IDX_parent is described as:
Index of name table entry for parent
These two contradict each other. The former is the correct one and the
latter is an unfortunate leftover from an earlier version of the
proposal, according to [1]. It does make sense, because pointing to a
name table entry is ambiguous, while poiting to an index entry directly
is not. Unfortunately, GDB implemented pointing to a name table entry.
Changes on the writer side:
- For each written pool entry, remember the offset within the pool.
- Change the DW_IDX_parent form to DW_FORM_data4.
Using DW_FORM_udata isn't an option, because we don't know the actual
value when doing the first pass of writing the pool (see next point),
so we wouldn't know how many bytes to reserve, if we used a
variable-size encoding.
Using a fixed 4 bytes encoding would be an issue if the entry pool
was larger than 4 GiB, but that seems unlikely.
Note that clang uses DW_FORM_ref4 for this, but I'm not sure it is
appropriate, since forms of the reference class are specified as
referring "to one of the debugging information entries that describe
the program". Since we're not referring to a DIE, I decided to stay
with a form of the "constant" class. I think that readers will be
able to understand either way.
- Write a dummy 4 byte number when writing the pool, then patch those
values later. This is needed because parents can appear before their
children in the pool (there's no way to ensure that parents always
appear before their children), so we might now know at first what
value to put in.
- Add a `write_uint` method to `class data_buf` to support that use
case of patching a value in the middle of the data buffer.
- Simplify the type of `m_name_to_value_set`, we no longer need to
track the index at which a name will be written at.
- Produce a new augmentation string, "GDB3", to be able to distinguish
"old" and "new" indexes. It would be possible for a reader to
distinguish the two semantics of DW_IDX_parent using the form.
However, current versions of GDB don't do that, so they would be
confused trying to read a new index. I think it is preferable to use
a new augmentation string so that they will reject a new index
instead.
Changes on the reader side:
- Track the GDB augmentation version, in addition to whether the
augmentation string indicates the index was produced by GDB.
- When reading index entries, maintain a "pool offset" -> "cooked index
entry" mapping, to be able to find parents by pool offset.
- When resolving parents, keep the existing behavior of finding parents
by name table index if the augmentation string is "GDB2. Otherwise,
look up parents by pool offset. This assumes that .debug_names from
other producers (if/when we add support for reading them) use pool
offsets for DW_IDX_parent. This at least what clang does.
- Simplify augmentation string comparison a bit by using array views.
Update the "Extensions to ‘.debug_names’" section of the documentation
to reflect the new augmentation string version.
Tested by:
- manually producing executables with "GDB2" and "GDB3" .debug_names
sections and reading them.
- running the testsuite with the cc-with-debug-names board
Trying to pass an array to this function doesn't work, as template
argument deduction fails:
test.c:698:8: error: no matching function for call to ‘func(int [12])’
698 | func (array);
| ~~~~~^~~~~~~
test.c:686:6: note: candidate: ‘template<class T> void func(gdb::array_view<U>)’
686 | void func(gdb::array_view<T> view) {}
| ^~~~
test.c:686:6: note: template argument deduction/substitution failed:
test.c:698:8: note: mismatched types ‘gdb::array_view<U>’ and ‘int*’
698 | func (array);
| ~~~~~^~~~~~~
Similarly, trying to compare a view with an array doesn't work. This:
int array[12];
gdb::array_view<int> view;
if (view == array) {}
... fails with:
test.c:698:8: error: no matching function for call to ‘func(int [12])’
698 | func (array);
| ~~~~~^~~~~~~
test.c:686:6: note: candidate: ‘template<class T> void func(gdb::array_view<U>)’
686 | void func(gdb::array_view<T> view) {}
| ^~~~
test.c:686:6: note: template argument deduction/substitution failed:
test.c:698:8: note: mismatched types ‘gdb::array_view<U>’ and ‘int*’
698 | func (array);
| ~~~~~^~~~~~~
With this new overload, we can do:
func (gdb::make_array_view (array));
and
if (view == gdb::make_array_view (array)) {}
This is not ideal, I wish that omitting `gdb::make_array_view` would
just work, but at least it allows creating an array view and have the
element type automatically deduced from the array type.
If someone knows how to make these cases "just work", I would be happy
to know how.
Change-Id: I6a71919d2d5a385e6826801d53f5071b470fef5f Approved-By: Tom Tromey <tom@tromey.com>
Hui Li [Thu, 6 Feb 2025 12:29:56 +0000 (20:29 +0800)]
gdb: LoongArch: Improve the handling of atomic sequence
In the current code, when using software single-step to debug atomic
instruction sequence, the execution of the atomic instruction sequence
may not be completed normally.
Here is a test with setting a software watchpoint to execute in software
single-step mode:
$ cat test.c
int a = 0;
int main()
{
a = 1;
return 0;
}
$ gcc -g test.c -o test
$ gdb test
..
(gdb) start
..
Temporary breakpoint 1, main () at test.c:4
4 a = 1;
(gdb) set can-use-hw-watchpoints 0
(gdb) n
5 return 0;
(gdb) watch a
Watchpoint 2: a
(gdb) c
Continuing.
At this point, the program continues to execute and can not exit
normally because it incorrectly handled the following ll/sc atomic
sequence in __run_exit_handlers () from /lib64/libc.so.6 during
software single-step execution.
The root cause of this problem is that a breakpoint was inserted in the
middle of ll/sc atomic sequence during software single-step execution.
The execution result of the atomic instruction sequence is disrupted,
causing the program unable to complete the execution of the atomic
instruction sequence normally.
Further explanation, if the current pc is 0x00007ffff7df7a50, it is a
conditional branch instruction, breakpoint should only be set at the
jump destination address (0x00007ffff7df7a64, which is outside of the
ll/sc atomic instruction sequence) and should not set at the address
of pc + 4 (0x00007ffff7df7a54, which is in the middle of ll/sc atomic
sequence).
Modify a judgment condition in loongarch_deal_with_atomic_sequence()
to ensure that breakpoints can not be inserted in the middle of ll/sc
atomic sequence to address such issues.
Signed-off-by: Hui Li <lihui@loongson.cn> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Andrew Burgess [Wed, 15 Jan 2025 15:09:30 +0000 (15:09 +0000)]
gdb: fix selecting tail-call frames by name
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.
Alan Modra [Mon, 10 Feb 2025 02:44:16 +0000 (13:14 +1030)]
tc-i386.c fix for oss-fuzz gas fuzzing
oss-fuzz fuzz_as is seriously broken with respect to gas static
variables, so much so that most fuzz_as reports should simply be
ignored. This patch is a fix for
https://oss-fuzz.com/testcase-detail/6268463220654080
H.J. Lu [Mon, 10 Feb 2025 00:38:57 +0000 (08:38 +0800)]
x86-64: Use x86_64_elf_howto_table for standard relocations
For standard relocations, use x86_64_elf_howto_table, instead of calling
elf_x86_64_rtype_to_howto.
* elf64-x86-64.c (elf_x86_64_tls_transition): Use
x86_64_elf_howto_table, instead of elf_x86_64_rtype_to_howto.
(elf_x86_64_convert_load_reloc): Use x86_64_elf_howto_table,
instead of elf_x86_64_rtype_to_howto, for R_X86_64_PC32.
Tom Tromey [Thu, 6 Feb 2025 21:07:59 +0000 (14:07 -0700)]
Add dwarf2_per_bfd::start_reading
The cooked index "start_reading" method can only be called after the
dwarf2_per_bfd "index_table" member is set. This patch refactors this
code a little to centralize this constraint, adding a new
dwarf2_per_bfd::start_reading method and another (virtual) method to
dwarf_scanner_base.
This removes some casts, but also is also useful to support another
series I'm working on where the .gdb_index is rewritten.
Approved-By: Simon Marchi <simon.marchi@efficios.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>
Richard Allen [Sun, 9 Feb 2025 16:49:01 +0000 (10:49 -0600)]
gprof: fix odd inst len hist scale calculation
With even instruction sizes, this rounding never truncated.
Xtensa CPUs mostly use 2-3 byte instructions, and this can lead
to a histogram being captured with an odd length address range.
This small truncation prevented gprof from parsing gmon.out files
containing multiple histograms when at least one of them has an
odd address range length and another has any other address range.
The pr326664 fuzzer testcase has two .debug_info sections, one
SHF_ALLOC, one not. SEC_DEBUGGING is never set for SHF_ALLOC sections
that happen to be named .debug_info, nor are they compressed. However
in this case we get an output section that is both SEC_ALLOC and
SEC_DEBUGGING which confuses code setting up the output section names
(.zdebug_* for compressed debug sections), resulting in a -1u index
into a string table.
PR 32664
* elf.c (elf_fake_sections): Do not delay naming of SEC_ALLOC
sections.
Andrew Burgess [Mon, 23 Dec 2024 15:59:29 +0000 (15:59 +0000)]
gdb/mi: include ranges in =library-unloaded event
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:
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:
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.
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:
Andrew Burgess [Thu, 19 Dec 2024 11:56:16 +0000 (11:56 +0000)]
gdb: include a still-mapped flag in solib unload notification
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:
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.
Andrew Burgess [Thu, 19 Dec 2024 10:41:40 +0000 (10:41 +0000)]
gdb/testsuite: restructure gdb.base/dlmopen.exp
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.
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:
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>
Alan Modra [Sun, 9 Feb 2025 09:45:02 +0000 (20:15 +1030)]
PR32663, ld buffer overflow reading .debug_info
When reading debug info to print an error message, we'll be reading
the debug info off disk, not using edited debug info. sec->rawsize
if non-zero is the correct size.
PR 32663
* dwarf2.c (_bfd_dwarf2_slurp_debug_info): Use
bfd_get_section_limit_octets to properly size debug sections.
Alan Modra [Sun, 9 Feb 2025 02:22:23 +0000 (12:52 +1030)]
PR32662, segv in _bfd_generic_link_output_symbols
asymbol flags zero can result from certain combinations of ELF st_info
binding and type. asymbol section is set to bfd_abs_section for
genuine absolute symbols and also ones with a bogus st_shndx. A
fuzzed ELF object with such a symbol can tickle a bug in generic
linker code added by commit d3a65d4dea to avoid an abort, resulting
in a segfault. This patch fixes the segfault by removing the
sym->section->owner->flags test. I think it should be OK to exclude
all symbols without any BSF flags set, not just IR symbols.
PR 32662
* linker.c (_bfd_generic_link_output_symbols): Exclude all
symbols with zero flags. Replace abort with assertion.
Tidy logic.
Andrew Burgess [Wed, 5 Feb 2025 20:12:03 +0000 (20:12 +0000)]
gdb/tui: use wrefresh if output is not surpressed
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.
Alexandre Oliva [Sat, 8 Feb 2025 06:12:24 +0000 (03:12 -0300)]
sparc: define _GLOBAL_OFFSET_TABLE_ when referenced
GCC testsuite gcc.dg/20050321-2.c hit link errors on undefined
_GLOBAL_OFFSET_TABLE_. The compiler output referenced only
_GLOBAL_OFFSET_TABLE_-offsets to set it up, and to compute the
GOT-relative address of local symbols, none of which triggered the
machinery that enabled the creation of the dynamic section, so
_GLOBAL_OFFSET_TABLE_ ended up undefined.
Enable the dynamic section if we find a relocation involving
_GLOBAL_OFFSET_TABLE_. While at that, optimize checks for references
to it.
for bfd/ChangeLog
* elfxx-sparc.c (_bfd_sparc_elf_check_relocs): Check for
_GLOBAL_OFFSET_TABLE_ references early, then compare hashed
symbols instead of strings.
(_bfd_sparc_elf_relocate_section): Compare hashed symbols.
for ld/ChangeLog
* testsuite/ld-sparc/got-def.s: New test.
* testsuite/ld-sparc/sparc.exp: Add it.
Alan Modra [Fri, 7 Feb 2025 08:13:00 +0000 (18:43 +1030)]
Re: x86-64: Estimate output section layout before sizing dynamic sections
Commit 73ab3b9825 results in a warning compiling eelf_x86_64_sol2.c,
breaking --enable-targets=all builds.
warning: ‘elf_x86_64_before_allocation’ defined but not used
Fix this by hooking up the chain of before_allocation functions, so
x86_64-solaris2 calls elf_x86_64_before_allocation, while
sparc64-solaris2 calls gldelf64_sparc_sol2_before_allocation.
Lancelot SIX [Fri, 7 Feb 2025 11:09:09 +0000 (11:09 +0000)]
gdb/testsuite: fix "up to main" in gdb.base/corefile-exec-context.exp
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>
Tom de Vries [Fri, 7 Feb 2025 15:17:52 +0000 (16:17 +0100)]
[gdb/corefiles] Fix segfault in core_target_open
On x86_64-freebsd, with test-case gdb.arch/i386-biarch-core.exp I run into a
segfault here in corelow.c:core_target_open:
...
{
gdb::unique_xmalloc_ptr<char> failing_command = make_unique_xstrdup
(bfd_core_file_failing_command (current_program_space->core_bfd ()));
if (failing_command != nullptr)
gdb_printf (_("Core was generated by `%s'.\n"),
failing_command.get ());
}
...
where bfd_core_file_failing_command returns nullptr, so the segfault happens
somewhere during "strdup (nullptr)".
There doesn't seem to be a need to make a copy of the string, so fix this by
dropping the make_unique_xstrdup.
Tested on x86_64-linux.
Tested the test-case on x86_64-freebsd.
Approved-By: Tom Tromey <tom@tromey.com>
PR corefiles/32634
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32634
Tom de Vries [Fri, 7 Feb 2025 14:57:24 +0000 (15:57 +0100)]
[gdb/build] Fix x86_64-w64-mingw32 build by avoiding SCNx8
With an x86_64-w64-mingw32 targeted cross-build on x86_64-linux, I run into:
...
gdb/cli/cli-decode.c: \
In function 'ui_file_style::color parse_cli_var_color(const char**)':
gdb/cli/cli-decode.c:2917:41: error: expected ')' before 'SCNx8'
int parsed_args = sscanf (*args, "#%2" SCNx8 "%2" SCNx8 "%2" SCNx8 "%n",
...
Apparantly, the definition of SCNx8 is missing in inttypes.h.
Rewrite the sscanf call to use SCNx32, which is available.
Tested by:
- completing aforementioned cross-build, and
- build & test on x86_64-linux.
Suggested-By: Tom Tromey <tom@tromey.com> Approved-By: Tom Tromey <tom@tromey.com>
MayShao-oc [Fri, 7 Feb 2025 09:31:42 +0000 (10:31 +0100)]
x86: Support x86 Zhaoxin PadLock XMODX instructions
The CPUID EDX bit[28] indicates its enablement, and it includes REP
XMODEXP and REP MONTMUL2. XMODX stands for modular exponentiation, it indicates
the support of modular exponentiation feature, both REP XMODEXP and
REP MONTMUL2 use it.
H.J. Lu [Thu, 30 Jan 2025 00:48:45 +0000 (08:48 +0800)]
x86-64: Estimate output section layout before sizing dynamic sections
When sizing dynamic sections, elf_x86_64_scan_relocs converts GOTPCREL
relocations to R_X86_64_PC32, R_X86_64_32S or R_X86_64_32 for local
symbols. But at that time, since the output section layout is unknown,
the local symbol values can't be determined. Later linker issues an
error if the converted relocation overflows when resolving relocations
against these local symbols. Update the x86-64 ELF linker to estimate
output section layout before sizing dynamic sections and use the
preliminary output section layout info to skip the GOTPCREL relocation
conversion if the converted relocation overflows.
bfd/
PR ld/32591
* elf64-x86-64.c (elf_x86_64_convert_load_reloc): Add an input
section argument. Use the lowest-addressed section to estimate
the __ehdr_start symbol value. Don't convert relocation if the
converted relocation will overflow.
Tom de Vries [Thu, 6 Feb 2025 14:57:08 +0000 (15:57 +0100)]
[gdb/testsuite] Use -nostdlib in gdb.base/list-dot-nodebug.exp
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.
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:
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>
Alan Modra [Thu, 6 Feb 2025 11:16:22 +0000 (21:46 +1030)]
PR 32603, ld -w misbehaviour
ld -w currently causes segmentation faults and other misbehaviour
since it changes einfo with %F in the format string (fatal error) to
not exit. This patch fixes that by introducing a new variant of einfo
called "fatal" that always exits, and replaces all einfo calls using
%F with a call to fatal without the %F. I considered modifying einfo
to inspect the first 2 or 4 chars in the format string, looking for
%F, but decided that was probably a bad idea given that translators
might have moved the %F. It's also a little nicer to inform the
compiler of a function that doesn't return.
The patch also fixes some formatting nits, and makes use of %pA
to print section names in a couple of places in aix.em.
Tom de Vries [Thu, 6 Feb 2025 06:35:09 +0000 (07:35 +0100)]
[gdb/build] Fix unused var in linux-fork.c
On x86_64-linux, with gcc 7.5.0 I ran into a build breaker:
...
linux-fork.c: In function ‘void detach_checkpoint_command(const char*, int)’:
linux-fork.c:744:16: error: unused variable ‘inf’ [-Werror=unused-variable]
auto [fi, inf] = parse_checkpoint_id (args);
^
linux-fork.c: In function ‘void linux_fork_context(fork_info*, int, inferior*)’:
linux-fork.c:1020:22: error: unused variable ‘oldinf’ [-Werror=unused-variable]
auto [oldfp, oldinf] = find_fork_ptid (inferior_ptid);
^
...
Fix this by dropping the unused variables, similar how that was done in commit bc13da1980c ("[gdb/build] Fix unused var in corelow.c").
H.J. Lu [Mon, 3 Feb 2025 22:16:28 +0000 (06:16 +0800)]
x86: Use hehdr_start for __ehdr_start
Use hehdr_start for __ehdr_start instead of elf_link_hash_lookup.
* elfxx-x86.c (elf_x86_linker_defined): Use hehdr_start if name
is NULL.
(_bfd_x86_elf_link_check_relocs): Pass NULL as __ehdr_start to
elf_x86_linker_defined.
Kevin Buettner [Wed, 5 Feb 2025 18:27:00 +0000 (11:27 -0700)]
Print only process ptids from linux-fork.c
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>
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>
Kevin Buettner [Wed, 5 Feb 2025 18:27:00 +0000 (11:27 -0700)]
Make linux checkpoints work with multiple inferiors
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:
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>
Guinevere Larsen [Tue, 28 Jan 2025 19:09:51 +0000 (16:09 -0300)]
gdb: restrict configure error with all targets and 64 bit bfd to mips
The recent commit b601c58034ed755fb765fc13782b6876bffd25d4 causes the
gdb configure to fail if --enable-targets=all was requested, but 64 bit
bfd was not enabled. This was due to a build failure first reported
against mips, and that I also encountered building on a 32 bit mips
system, but that looked like a general failure.
Further examination showed that this is, in fact, mips-specific (or at
least, not completely generic) as other targets like debian-i386 and
32-bit arm could build all targets just fine.
This commit restricts the new error to only trigger in mips hosts.
Jan Beulich [Mon, 3 Feb 2025 06:52:19 +0000 (07:52 +0100)]
gas MMIX: Use more of is_... framework like is_whitespace and is_end_of_stmt
Convert uses of ISSPACE() and testing for specific characters into
calls to is_whitespace and is_end_of_stmt. While doing that, also
remove some redundant tests, like ';' together with is_end_of_line[]
and is_whitespace and !is_end_of_line.
Note the invalid casts being fixed as part of moving to is_... macros;
there were (unsigned int) where there should have been (unsigned char)
applied on char as index to is_end_of_line[].
Beware that the input language changes slightly: some constructs with
whitespace characters other than space and TAB are now invalid.
Tom de Vries [Tue, 4 Feb 2025 21:11:13 +0000 (22:11 +0100)]
[gdb/tui] Clean up asserts in tui_source_window_base::refresh_window
Commit 1c525b0e037 ("[gdb/tui] Fix assert in
tui_source_window_base::refresh_window") added an early return in
tui_source_window_base::refresh_window.
Assert after the early return that "m_pad != nullptr", and clean up the
following asserts that allow for m_pad == nullptr.
Tested on x86_64-linux.
Reported-By: Andrew Burgess <aburgess@redhat.com> Co-Authored-By: Andrew Burgess <aburgess@redhat.com> Approved-By: Andrew Burgess <aburgess@redhat.com>
Tom de Vries [Tue, 4 Feb 2025 21:07:22 +0000 (22:07 +0100)]
[pre-commit] Require pre-commit version 3.2.0
Recent commit 0bd340d6704 ("pre-commit autoupdate") bumped the isort version
to 6.0.0.
Subsequently, I started running into:
...
$ SKIP=flake8,isort pre-commit run
An error has occurred: InvalidManifestError:
==> File /home/vries/.cache/pre-commit/repommstqefj/.pre-commit-hooks.yaml
==> At Hook(id='isort')
==> At key: stages
==> At index 0
=====> Expected one of commit, commit-msg, manual, merge-commit, \
post-checkout, post-commit, post-merge, post-rewrite, prepare-commit-msg, \
push but got: 'pre-commit'
Check the log at /home/vries/.cache/pre-commit/pre-commit.log
...
I found a similar PR [1], that explains that using pre-commit as a stage (as
isort 6.0.0 does) is supported starting pre-commit 3.2.0.
Add minimum_pre_commit_version 3.2.0 in .pre-commit-config.yaml, as suggested
in the PR.
After adding this, I get a more helpful message:
...
$ SKIP=flake8,isort pre-commit run
An error has occurred: InvalidConfigError:
==> File .pre-commit-config.yaml
==> At Config()
==> At key: minimum_pre_commit_version
=====> pre-commit version 3.2.0 is required but version 2.17.0 is installed. \
Perhaps run `pip install --upgrade pre-commit`.
Check the log at /home/vries/.cache/pre-commit/pre-commit.log
...
and after doing so which upgrades pre-commit to version 4.1.0, as well as
re-installing pre-commit using:
...
$ pre-commit uninstall
$ pre-commit install
...
I have a functional setup again.
Interestingly, since pre-commit 4.1.0 runs in a python 3.11 environment, I no
longer need to skip flake8 and isort, as I needed to previously when the
system python 3.6 was used.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
[1] https://github.com/psf/black/issues/4065
Simon Marchi [Thu, 5 Dec 2024 17:41:21 +0000 (12:41 -0500)]
pre-commit: run flake8 on more Python files
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:
Tom Tromey [Mon, 3 Feb 2025 19:12:29 +0000 (12:12 -0700)]
Reorder gnatmake arguments in inline-section-gc.exp
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.
The function start address in a SFrame FDE (sfde_func_start_address)
is encoded as a signed offset to the function start address from the
SFrame section.
The PC range start address in a SFrame FRE (sfre_start_address) is
encoded as an unsigned offset to the range from the function start
address.
Jens Remus [Tue, 4 Feb 2025 14:13:24 +0000 (15:13 +0100)]
gas: sframe: Use appropriate struct cfi_insn_data union members
Use the appropriate struct cfi_insn_data union members to access
fields when generating SFrame information from CFI directives.
gas/
* gen-sframe.c (sframe_xlate_do_def_cfa, sframe_xlate_do_offset,
sframe_xlate_do_val_offset): Access ri fields, as .cfi_def_cfa,
.cfi_offset, and .cfi_val_offset define a register and offset
value.
* (sframe_xlate_do_def_cfa_register): Access r field, as
.cfi_def_cfa_register defines a register.
Tom de Vries [Tue, 4 Feb 2025 13:06:20 +0000 (14:06 +0100)]
[gdb/testsuite] Fix gdb.ada/big_packed_array.exp on s390x-linux
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'.
Tom de Vries [Tue, 4 Feb 2025 13:06:20 +0000 (14:06 +0100)]
[gdb/testsuite] Fix gdb.ada/convvar_comp.exp on s390x-linux
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.
Tom de Vries [Tue, 4 Feb 2025 09:34:39 +0000 (10:34 +0100)]
[gdb/testsuite] Fix gdb.base/list-dot-nodebug.exp on openSUSE
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
Tom de Vries [Tue, 4 Feb 2025 09:21:28 +0000 (10:21 +0100)]
[gdb/tui] Remove stale title when showing "No Source Available"
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.