aboutsummaryrefslogtreecommitdiff
path: root/gdb
AgeCommit message (Collapse)AuthorFilesLines
2025-05-06Introduce apply_bit_offset_to_field helper functionTom Tromey3-40/+72
This patch makes a new function, apply_bit_offset_to_field, that is used to handle the logic of DW_AT_bit_offset. Currently there is just a single caller, but the next patch will change this.
2025-05-06Use OBSTACK_ZALLOC when allocating batonsTom Tromey1-6/+9
I found some places in dwarf2/read.c that allocate a location baton, but fail to initialize one of the fields. It seems safer to me to use OBSTACK_ZALLOC here, so this patch makes this change. This will be useful in a subsequent patch as well, where a new field is added to one of the batons.
2025-05-06Clean up handle_member_locationTom Tromey1-3/+2
This removes a redundant check from handle_member_location, and also changes the complaint -- currently it will issue the "complex location" complaint, but really what is happening here is an unrecognized form.
2025-05-06Handle dynamic field propertiesTom Tromey9-91/+237
I found a situation where gdb could not properly decode an Ada type. In this first scenario, the discriminant of a type is a bit-field. PROP_ADDR_OFFSET does not handle this situation, because it only allows an offset -- not a bit-size. My original approach to this just added a bit size as well, but after some discussion with Eric Botcazou, we found another failing case: a tagged type can have a second discriminant that appears at a variable offset. So, this patch changes this code to accept a general 'struct field' instead of trying to replicate the field-finding machinery by itself. This is handled at property-evaluation time by simply using a 'field' and resolving its dynamic properties. Then the usual field-extraction function is called to get the value. Because the baton now just holds a field, I renamed PROP_ADDR_OFFSET to PROP_FIELD. The DWARF reader now defers filling in the property baton until the fields have been attached to the type. Finally, I noticed that if the discriminant field has a biased representation, then unpack_field_as_long would not handle this either. This bug is also fixed here, and the test case checks this. Regression tested on x86-64 Fedora 41.
2025-05-06Add new unpack_field_as_long overloadTom Tromey2-6/+22
This introduces a new unpack_field_as_long that takes the field object directly, rather than a type and an index. This will be used in the next patch.
2025-05-06Add resolve_dynamic_fieldTom Tromey2-42/+62
The final patch in this series will change one dynamic property approach to use a struct field rather than an offset and a field type. This is convenient because the reference in DWARF is indeed to a field -- and this approach lets us reuse the field-extraction logic that already exists in gdb. However, the field in question may have dynamic properties which must be resolved before it can be used. This patch prepares for this by introducing a separate resolve_dynamic_field function. This patch should cause no visible changes to behavior.
2025-05-06Constify property_addr_infoTom Tromey2-14/+14
This changes most places to use a const property_addr_info. This seems more correct to me because normally the user of a property_addr_info should not modify it. Furthermore, some functions already take a const object, and for a subsequent patch it is convenient if other functions do as well.
2025-05-06gdb/testsuite: Add require allow_hipcc_tests in gdb.rocm/mi-attach.expLancelot SIX1-1/+2
The gdb.rocm/mi-attach.exp test is missing a proper `require` check to ensure that the current configuration can run ROCm tests. This issue has been reported by Baris. This patch adds the missing `allow_hipcc_tests` requirement, and also adds `load_lib rocm.exp` to enable this test. Change-Id: Ie136adfc2d0854268b92af5c4df2dd0334dce259 Reviewed-By: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> Approved-By: Tom Tromey <tom@tromey.com>
2025-05-06gdb: support zero inode in generate-core-file commandAndrew Burgess1-1/+1
It is possible, when creating a shared memory segment (i.e. with shmget), that the id of the segment will be zero. When looking at the segment in /proc/PID/smaps, the inode field of the entry holds the shared memory segment id. And so, it can be the case that an entry (in the smaps file) will have an inode of zero. When GDB generates a core file, with the generate-core-file (or its gcore alias) command, the shared memory segment should be written into the core file. Fedora GDB has, since 2008, carried a patch that tests this case. There is no fix for GDB associated with the test, and unfortunately, the motivation for the test has been lost to the mists of time. This likely means that a fix was merged upstream without a suitable test, but I've not been able to find and relevant commit. The test seems to be checking that the shared memory segment with id zero, is being written to the core file. While looking at this test and trying to work out if it should be posted upstream, I saw that GDB does appear to write the shared memory segment into the core file (as expected), which is good. However, GDB still isn't getting this case exactly right. In gcore_memory_sections (gcore.c) we call back into linux-tdep.c (via the gdbarch_find_memory_regions call) to correctly write the shared memory segment into the core file, however, in linux_make_mappings_corefile_notes, when we use linux_find_memory_regions_full to create the NT_FILE note, we call back into linux_make_mappings_callback for each mapping, and in here we reject any mapping with a zero inode. The result of this, is that, for a shared memory segment with a non-zero id, after loading the core file, the shared memory segment will appear in the 'proc info mappings' output. But, for a shared memory segment with a zero id, the segment will not appear in the 'proc info mappings' output. I propose fixing this by not checking the inode in linux_make_mappings_callback. The inode check was in place since the code was originally added in commit 451b7c33cb3c9ec6272c36870 (in 2012). The test for this bug, based on the original Fedora patch, can be found on the mailing list here: https://inbox.sourceware.org/gdb-patches/0d389b435cbb0924335adbc9eba6cf30b4a2c4ee.1741776651.git.aburgess@redhat.com I have not committed this test into the tree though because the test was just too unreliable. User space doesn't have any control over the shared memory id, so all we can do is spam out requests for new shared memory segments and hope that we eventually get the zero id. Obviously, this can fail; the zero id might already be in use by some long running process, or the kernel, for whatever reason, might choose to never allocate the zero id. The test I posted (see above thread) did work more than 50% of the time, but it was far closer to a 50% success rate than 100%, and I really don't like introducing unreliable tests.
2025-05-06gdb/testsuite: add gcore_cmd_available predicate procAndrew Burgess7-4/+25
Add a new gcore_cmd_available predicate proc that can be used in a 'requires' line, and make use of it in a few tests. All of the tests I have modified call gdb_gcore_cmd as one of their first actions and exit if the gcore command is not available, so it makes sense (I think) to move the gcore command check into a requires call. There should be no change in what is actually run after this commit.
2025-05-06gdb/python/guile: check if styling is disabled in Color.escape_sequenceAndrew Burgess6-7/+41
I noticed that the gdb.Color.escape_sequence() method would produce an escape sequence even when styling is disabled. I think this is the wrong choice. Ideally, when styling is disabled (e.g. with 'set style enabled off'), GDB should not be producing styled output. If a GDB extension is using gdb.Color to apply styling to the output, then currently, the extension should be checking 'show style enabled' any time Color.escape_sequence() is used. This means lots of code duplication, and the possibility that some locations will be missed, which means disabling styling no longer does what it says. I propose that Color.escape_sequence() should return the empty string if styling is disabled. A Python extension can then do: python c_none = gdb.Color('none') c_red = gdb.Color('red') print(c_red.escape_sequence(True) + "Text in red." + c_none.escape_sequence(True)) end If styling is enable this will print some red text. And if styling is disabled, then it will print text in the terminal's default color. I have applied the same fix to the guile API. I have extended the tests to cover this case. Approved-By: Tom Tromey <tom@tromey.com>
2025-05-05Fix sign of Ada rational constantsTom Tromey3-6/+18
My earlier patch commit 0c03db90 ("Use correct sign in get_mpz") was (very) incorrect. It changed get_mpz to check for a strict sign when examining part of an Ada rational constant. However, in Ada the "delta" for a fixed-point type must be positive, and so the components of the rational representation will be positive. This patch corrects the error. It also renames the get_mpz function, in case anyone is tempted to reuse this code for another purpose. Finally, this pulls over the test from the internal AdaCore test suite that found this issue.
2025-05-02[gdb/testsuite] Simplify gdb.tui/tui-layout-asm.expTom de Vries1-37/+69
On x86_64-cygwin, with test-case gdb.tui/tui-layout-asm.exp I run into: ... WARNING: The following failure is probably due to the TUI window width. See the comments in the test script for more details. FAIL: $exp: scroll to end of assembler (scroll failed) ... The problem is as follows. On the TUI screen, we have: 1 | 0x1004010ff <__gdb_set_unbuffered_output+95> nop | 2 | 0x100401100 <__cxa_atexit> jmp *0x6fc2(%rip) # 0x10040 | ... We send the down key, which should have the effect of scrolling up. So, we expect that the second line moves to the first line. That seems to be the case indeed: ... 1 | 0x100401100 <__cxa_atexit> jmp *0x6fc2(%rip) # 0x1004080c8 <__imp___cxa_ | ... but the line has changed somewhat, so the matching fails. We could increase the width of the screen, as suggested in the test-case, but I think that approach is fragile. Instead, fix this by relaxing the matching: just check that the line before scrolling is fully contained in the line after scrolling, or the other way around. Doing so gets us the next failure: ... FAIL: $exp: scroll to end of assembler (too much assembler) ... The test-case states: ... if { $down_count > 250 } { # Maybe we should accept this as a pass in case a target # really does have loads of assembler to scroll through. fail "$testname (too much assembler)" ... and I agree, so fix this by issuing a pass. This results in the test-case taking ~20 seconds, so reduce the maximum number of scrolls from 250 to 25, bringing that down to ~10 seconds. Tested on x86_64-cygwin and x86_64-linux. PR testsuite/32898 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32898
2025-05-02[gdb/symtab] Throw DWARF error on out-of-bounds DW_FORM_strxTom de Vries2-3/+45
With the test-case contained in the patch, and gdb build with -fsanitize=address we get: ... ==23678==ERROR: AddressSanitizer: heap-buffer-overflow ...^M READ of size 1 at 0x6020000c30dc thread T3^[[1m^[[0m^M ptype global_var^M #0 0x2c6a40b in bfd_getl32 bfd/libbfd.c:846^M #1 0x168f96c in read_str_index gdb/dwarf2/read.c:15349^M ... The executable contains an out-of-bounds DW_FORM_strx attribute: ... $ readelf -wi $exec <2eb> DW_AT_name :readelf: Warning: string index of 1 converts to \ an offset of 0xc which is too big for section .debug_str (indexed string: 0x1): <string index too big> ... and read_str_index doesn't check for this: ... info_ptr = (str_offsets_section->buffer + str_offsets_base + str_index * offset_size); if (offset_size == 4) str_offset = bfd_get_32 (abfd, info_ptr); ... and consequently reads out-of-bounds. Fix this in read_str_index by checking for the out-of-bounds condition and throwing a DWARF error: ... (gdb) ptype global_var DWARF Error: Offset from DW_FORM_GNU_str_index or DW_FORM_strx pointing \ outside of .debug_str_offsets section in CU at offset 0x2d7 \ [in module dw-form-strx-out-of-bounds] No symbol "global_var" in current context. (gdb) ... Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com>
2025-05-02[gdb/testsuite] Add gdb.dwarf2/dw-form-strx.expTom de Vries3-0/+125
Add a test-case using DW_FORM_strx. Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com>
2025-05-02[gdbsupport] Reimplement phex and phex_nz as templatesTom de Vries10-29/+29
Gdbsupport functions phex and phex_nz have a parameter sizeof_l: ... extern const char *phex (ULONGEST l, int sizeof_l); extern const char *phex_nz (ULONGEST l, int sizeof_l); ... and a lot of calls use: ... phex (l, sizeof (l)) ... Make this easier by reimplementing the functions as a template, allowing us to simply write: ... phex (l) ... Simplify existing code using: ... $ find gdb* -type f \ | xargs sed -i 's/phex (\([^,]*\), sizeof (\1))/phex (\1)/' $ find gdb* -type f \ | xargs sed -i 's/phex_nz (\([^,]*\), sizeof (\1))/phex_nz (\1)/' ... and manually review: ... $ find gdb* -type f | xargs grep "phex (.*, sizeof.*)" $ find gdb* -type f | xargs grep "phex_nz (.*, sizeof.*)" ... Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com>
2025-05-02Use emoji to indicate errors and warningsTom Tromey10-17/+207
This patch adds, at long last, some emoji output to gdb. In particular, warnings are indicated with the U+26A0 (WARNING SIGN), and errors with U+274C (CROSS MARK). There is a new setting to control whether emoji output can be used. It defaults to "auto", which means emoji will be used if the host charset is UTF-8. Note that disabling styling will also disable emoji, handy for traditionalists. I've refactored mingw console output a little, so that emoji will not be printed to the console. Note the previous code here was a bit strange in that it assumed that the first use of gdb_console_fputs would be to stdout. This version lets the user control the prefixes directly, so different emoji can be chosen if desired. Reviewed-By: Eli Zaretskii <eliz@gnu.org> Reviewed-By: Keith Seitz <keiths@redhat.com> Reviewed-By: Guinevere Larsen <guinevere@redhat.com>
2025-05-02[gdb/testsuite] Fix gdb.reverse/time-reverse.exp timeoutTom de Vries1-1/+25
After building gdb with "-O0 -g -fsanitize=thread" on aarch64-linux, with test-case gdb.reverse/time-reverse.exp I run into: ... (gdb) continue^M Continuing.^M FAIL: $exp: mode=c: continue to breakpoint: marker2 (timeout) ... The problem is that instruction stepping gets stuck in a loop with this call stack: time -> __GI___clock_gettime -> __kernel_clock_gettime -> __cvdso_clock_gettime. This is not specific to fsanitize=thread, it just makes gdb slow, which makes instruction stepping slow, which results in the application getting stuck. I ran into this as well with a regular gdb build on a 32-bit i686 laptop with 1GB of memory, an inherently slow setup. In that instance, I was able to observe that the loop we're stuck in is the outer loop in do_coarse in linux kernel source lib/vdso/gettimeofday.c. Fix this by setting "record full insn-number-max" to 2000, and handling running into the limit. Initially I tried the approach of using "stepi 2000" instead of continue, but that made the issue more likely to show up (for instance, I observed it after building gdb with -O0 on aarch64-linux). Tested on aarch64-linux. Approved-By: Guinevere Larsen <guinevere@redhat.com> PR testsuite/32678 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32678
2025-05-02[gdb/testsuite] Make gdb.reverse/time-reverse.exp more robustTom de Vries1-8/+11
I noticed that test-case gdb.reverse/time-reverse.exp contains: ... if [supports_process_record] { # Activate process record/replay gdb_test_no_output "record" "turn on process record" ... So I tried out forcing supports_process_record to 0, and got: ... FAIL: gdb.reverse/time-reverse.exp: mode=syscall: info record FAIL: gdb.reverse/time-reverse.exp: mode=syscall: reverse to marker1 FAIL: gdb.reverse/time-reverse.exp: mode=syscall: check time record FAIL: gdb.reverse/time-reverse.exp: mode=c: info record FAIL: gdb.reverse/time-reverse.exp: mode=c: reverse to marker1 FAIL: gdb.reverse/time-reverse.exp: mode=c: check time record ... Fix this by requiring supports_process_record alongside supports_reverse. I also noticed when running make-check-all.sh that there were a lot of failures with target board dwarf5-fission-debug-types. Fix this by not ignoring the result of "runto marker1". Then I noticed that $srcfile is used as a regexp. Fix this by applying string_to_regexp. Tested on x86_64-linux. Approved-By: Guinevere Larsen <guinevere@redhat.com>
2025-05-02Minor changes to Ada tests for gnat-llvmTom Tromey6-4/+56
I found a few more spots where a minor modification to a test lets it pass with gnat-llvm: * For array_subcript_addr, gnat-llvm was not putting the array into memory. Making the array larger works around this. * For bp_inlined_func, it is normal for gnat-llvm to sometimes emit a call to an out-of-line copy of the function, so accept this. * For null_overload and type-tick-size, I've applied the usual fix for keeping an unused local variable alive.
2025-05-02[gdb/testsuite] Make gdb.threads/inf-thr-count.exp more readableTom de Vries1-21/+34
While investigating a timeout in gdb.threads/inf-thr-count.exp I noticed that it uses quite some escaping, resulting in hard-to-parse regexps like "\\\$$::decimal". Fix this by reducing the escaping using: - quoting strings using {} instead of "", and - string_to_regexp. Also use multi_line to split up long multi-line regexps. Tested on x86_64-linux.
2025-05-02[gdb/testsuite] Fix timeout in gdb.threads/inf-thr-count.expTom de Vries1-1/+1
With test-case gdb.threads/inf-thr-count.exp, check-readmore and READMORE_SLEEP=1000 I run into: ... (gdb) set variable spin = 0^M (gdb) ^M Thread 1 "inf-thr-count" hit Breakpoint 2, breakpt () at /data/vries/gdb/src/gdb/testsuite/gdb.threads/inf-thr-count.c:49^M 49 }^M FAIL: gdb.threads/inf-thr-count.exp: set 'spin' flag to allow main thread to exit (timeout) PASS: gdb.threads/inf-thr-count.exp: wait for main thread to stop ... Fix this by using -no-prompt-anchor. Tested on x86_64-linux.
2025-04-30gdb/progspace: fix formatting issueGuinevere Larsen1-1/+1
The previous commit had a small styling issue that I forgot to fix before pushing. This commit fixes the styling issue.
2025-04-30gdb: Stop exec_close looking like a UAF weaknessGuinevere Larsen1-3/+5
A recent static analyzer run flagged that program_space::exec_close could be using a pointer after it has been freed. This is not true, as the pointer is never dereferenced, the address is used for comparisons. However, to avoid false positives from static analyzers (or bogus security bugs), this commit makes the code stop looking like a UAF by moving the unique_ptr into a local unique_ptr, so that there is no way someone would think memory could be used after being freed. Approved-By: Tom Tromey <tom@tromey.com>
2025-04-30[gdb/testsuite] Don't compile read1.so with -fsanitizeTom de Vries1-2/+3
After building gdb with: ... CFLAGS= -O0 -g -fstack-protector-all -fsanitize=thread -fno-exceptions CXXFLAGS= -O0 -g -fstack-protector-all -fsanitize=thread ... when doing: ... $ cd build/gdb $ make check-read1 RUNTESTFLAGS=gdb.threads/clone-attach-detach.exp ... I run into: ... Running /data/vries/gdb/src/gdb/testsuite/gdb.threads/clone-attach-detach.exp ... ThreadSanitizer:DEADLYSIGNAL ==4799==ERROR: ThreadSanitizer: SEGV on unknown address 0x000000000000 \ (pc 0x7f636029a947 bp 0x7f635dfbf090 sp 0x7f635dfbf028 T4824) ==4799==The signal is caused by a READ memory access. ==4799==Hint: address points to the zero page. ThreadSanitizer:DEADLYSIGNAL ThreadSanitizer: nested bug in the same thread, aborting. ... This doesn't happen when doing the same from build/gdb/testsuite, because CFLAGS doesn't get propagated from build/gdb. I'm not sure what is the root cause here, but when building with -fsanitize, I'm interested in running the sanitizer on gdb, not on testsuite utility libraries that are used with expect. Fix this by skipping -fsanitize when compiling read1.so and readmore.so. Tested on x86_64-linux, by rebuilding read1.so and running the test-case. Approved-By: Tom Tromey <tom@tromey.com>
2025-04-30[gdb/testsuite] Handle asm frame in gdb.python/py-missing-objfile.expTom de Vries1-0/+10
On arm-linux, with test-case gdb.python/py-missing-objfile.exp I get: ... (gdb) whatis global_exec_var^M type = volatile exec_type^M (gdb) FAIL: $exp: initial sanity check: whatis global_exec_var ... instead of the expected "type = volatile struct exec_type". The problem is that the current language is ASM instead of C, because the inner frame at the point of the core dump has language ASM: ... #0 __libc_do_syscall () at libc-do-syscall.S:47 #1 0xf7882920 in __pthread_kill_implementation () at pthread_kill.c:43 #2 0xf784df22 in __GI_raise (sig=sig@entry=6) at raise.c:26 #3 0xf783f03e in __GI_abort () at abort.c:73 #4 0x009b0538 in dump_core () at py-missing-objfile.c:34 #5 0x009b0598 in main () at py-missing-objfile.c:46 ... Fix this by manually setting the language to C. Tested on arm-linux and x86_64-linux. PR testsuite/32445 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32445
2025-04-30[gdb/build] Fix Wformat errors in gdb/riscv-tdep.cTom de Vries1-6/+7
When building gdb with --enable-targets=all on arm-linux, I run into: ... gdb/riscv-tdep.c: In function ‘bool try_read(regcache*, int, ULONGEST&)’: gdb/riscv-tdep.c:4887:18: error: format ‘%lx’ expects argument of type \ ‘long unsigned int’, but argument 2 has type ‘ULONGEST’ \ {aka ‘long long unsigned int’} [-Werror=format=] 4887 | warning (_("Can not read at address %lx"), addr); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ... and a few more Wformat errors, due to commit b9c7eed0c24 ("This commit adds record full support for rv64gc instruction set"). Fix these by using hex_string. Tested by completing a build on arm-linux.
2025-04-29gdb/dwarf: change a bunch of functions to be methods of ↵Simon Marchi1-59/+52
cooked_index_worker_debug_info Move a few functions exclusively used to process units to become methods of cooked_index_worker_debug_info. Rename them to a more consistent name scheme, which gets rid of outdated naming. The comments were also quite outdated. Change-Id: I2e7dcc2e4ff372007dcb4f6c3d34187c9cc2da05 Approved-By: Tom Tromey <tom@tromey.com>
2025-04-29gdb/dwarf: move cooked_index_worker_debug_info upSimon Marchi1-75/+73
The next patch moves some functions to be methods of cooked_index_worker_debug_info. Move cooked_index_worker_debug_info above those functions, to make that easier (methods can't be defined before the class declaration). Change-Id: I7723cb42efadb2cc86f2227b3c2fb275e2d620f9 Approved-By: Tom Tromey <tom@tromey.com>
2025-04-29gdb/dwarf: clean up some cutu_reader::is_dummy() callsSimon Marchi2-6/+4
This patch tries to standardize the places where we check if units are dummy. When checking if a unit is dummy, it is not necessary to check for some other conditions. - cutu_reader::is_dummy() is a superset of cutu_reader::cu() returning nullptr, so it's not necessary to check if the cu method return nullptr if also checking if the unit is dummy. - cutu_reader::is_dummy() is a superset of cutu_reader::top_level_die() returning nullptr, so same deal. Remove some spots that check for these conditions in addition to cutu_reader::is_dummy(). In addition, also remove the checks for: !new_reader->top_level_die ()->has_children in cooked_indexer::ensure_cu_exists. IMO, it is not useful to special case the units having a single DIE. Especially in this function, which deals with importing things from another unit, a unit with a single DIE would be an edge case that should not happen with good debug info. I think it's preferable to have simpler code. Change-Id: I4529d7b3a0bd2891a60f41671de8cfd3114adb4a Approved-By: Tom Tromey <tom@tromey.com>
2025-04-29gdb/dwarf: avoid cutu_reader movesSimon Marchi3-17/+19
In process_psymtab_comp_unit and ensure_cu_exists, we create a temporary cutu_reader on the stack, then move it to a heap allocated cutu_reader once we confirmed the unit is not dummy. I think it's unnecessary to create a temporary cutu_reader. The only downside of not doing so is that if it ends up that the CU is dummy, we made an allocation/deallocation for nothing. Dummy CUs are a rare thing, it shouldn't change anything. This allows removing the cutu_reader move constructor. Change-Id: I44742d471c495055ee46db41c0e7bdfbd2d5c0b7 Approved-By: Tom Tromey <tom@tromey.com>
2025-04-29gdb/dwarf: read multiple .debug_info.dwo sectionsSimon Marchi1-11/+26
When building with gcc, with flags -gdwarf-5, -gsplit-dwarf and -fdebug-types-section, the resulting .dwo files contain multiple .debug_info.dwo sections. One for each type unit and one for the compile unit. This is correct, as per DWARF 5, section F.2.3 ("Contents of the Split DWARF Object Files"): The split DWARF object files each contain the following sections: ... .debug_info.dwo (for the compilation unit) .debug_info.dwo (one COMDAT section for each type unit) ... GDB currently assumes that there is a single .debug_info.dwo section, causing unpredictable behavior. For example, sometimes this crash: ==81781==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x508000007a71 at pc 0x58704d32a59c bp 0x7ffc0acc0bb0 sp 0x7ffc0acc0ba0 READ of size 1 at 0x508000007a71 thread T0 #0 0x58704d32a59b in bfd_getl32 /home/smarchi/src/binutils-gdb/bfd/libbfd.c:846 #1 0x58704ae62dce in read_initial_length(bfd*, unsigned char const*, unsigned int*, bool) /home/smarchi/src/binutils-gdb/gdb/dwarf2/leb.c:92 #2 0x58704aaf76bf in read_comp_unit_head(comp_unit_head*, unsigned char const*, dwarf2_section_info*, rcuh_kind) /home/smarchi/src/binutils-gdb/gdb/dwarf2/comp-unit-head.c:47 #3 0x58704aaf8f97 in read_and_check_comp_unit_head(dwarf2_per_objfile*, comp_unit_head*, dwarf2_section_info*, dwarf2_section_info*, unsigned char const*, rcuh_kind) /home/smarchi/src/binutils-gdb/gdb/dwarf2/comp-unit-head.c:193 #4 0x58704b022908 in create_dwo_unit_hash_tables /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:6233 #5 0x58704b0334a5 in open_and_init_dwo_file /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:7588 #6 0x58704b03965a in lookup_dwo_cutu /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:7935 #7 0x58704b03a5b1 in lookup_dwo_comp_unit /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:8009 #8 0x58704aff5b70 in lookup_dwo_unit /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:2802 The first time that locate_dwo_sections gets called for a .debug_info.dwo section, dwo_sections::info gets initialized properly. The second time it gets called for a .debug_info.dwo section, the size field in dwo_sections::info gets overwritten with the size of the second section. But the buffer remains pointing to the contents of the first section, because the section is already "read in". So the size does not match the buffer. And even if it did, we would only keep the information about one .debug_info.dwo, out of the many. First, add an assert in locate_dwo_sections to make sure we don't try to fill in a dwo section info twice. Add the assert to other functions with the same pattern, while at it. Then, change dwo_sections::info to be a vector of sections (just like we do for type sections). Update locate_dwo_sections to append to that vector when seeing a new .debug_info.dwo section. Update open_and_init_dwo_file to read the units from each section. The problem can be observed by running some tests with the dwarf5-fission-debug-types target board. For example, gdb.base/condbreak.exp crashes (with the ASan failure shown above) before the patch and passes after). [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119766 Change-Id: Iedf275768b6057dee4b1542396714f3d89903cf3 Reviewed-By: Tom de Vries <tdevries@suse.de>
2025-04-29gdb/dwarf: scan .debug_info.dwo just onceSimon Marchi2-183/+94
When building -gsplit-dwarf and -fdebug-types-section in DWARF 5, the resulting .dwo files will typically have a .debug_info.dwo section with multiple type units followed by one compile unit: $ llvm-dwarfdump -F -color a-test.dwo | grep ' Unit' 0x00000000: Type Unit: length = 0x000008a0, format = DWARF32, version = 0x0005, unit_type = DW_UT_split_type, abbr_offset = 0x0000, addr_size = 0x08, name = 'vector<int, std::allocator<int> >', type_signature = 0xb499dcf29e2928c4, type_offset = 0x0023 (next unit at 0x000008a4) 0x000008a4: Type Unit: length = 0x00000099, format = DWARF32, version = 0x0005, unit_type = DW_UT_split_type, abbr_offset = 0x0000, addr_size = 0x08, name = 'allocator<int>', type_signature = 0x496a8791a842701b, type_offset = 0x0023 (next unit at 0x00000941) ... 0x000015c1: Compile Unit: length = 0x00000f58, format = DWARF32, version = 0x0005, unit_type = DW_UT_split_compile, abbr_offset = 0x0000, addr_size = 0x08, DWO_id = 0xe8e359820d1c5803 (next unit at 0x0000251d) In open_and_init_dwo_file, we call create_dwo_cus_hash_table, which scans the section, looking for compile units, then call create_dwo_debug_types_hash_table, which scans the section again, looking for type units. It would make more sense to scan the section just once and handle both compile and type units at the same time. To achieve this, add create_dwo_unit_hash_tables, which knows how to handle both unit kinds in a single scan. It replaces create_dwo_cus_hash_table and create_dwo_debug_type_hash_table. Change open_and_init_dwo_file to call it. Note that I removed the DWARF version check in open_and_init_dwo_file when processing .debug_type.dwo sections: in DWARF 5, the .debug_type.dwo sections will just not exist, so the `dwo_file->sections.types` vector will be empty. Change-Id: I6e51d0ca06c258e0bf0e59927d62ae2df314a162 Approved-By: Tom Tromey <tom@tromey.com>
2025-04-29gdb/dwarf: scan DWARF 5 DWO CUs by just reading the headerSimon Marchi1-24/+50
create_dwo_cus_hash_table is implemented by creating a cutu_reader (which is somewhat heavy) for all units in a .dwo file. The purpose of this cutu_reader is to be able to get the DWO ID, if it is specified by a DW_AT_GNU_dwo_id attribute. In DWARF 5, however, the DWO ID is available in the CU header. We can access it without accessing the DIEs, by just reading the header, which is more lightweight. Add a new code path to create_dwo_cus_hash_table that does that. The logic is copied from create_dwo_debug_type_hash_table, which does this already. This change helps circumvent a performance problem I want to fix (the same I was trying to fix in this patch [1]) when loading a file built with -gdwarf-5, -gsplit-dwarf and -fdebug-types-section. In this configuration, the produced .dwo files contain one compile unit and many type units each. All units in a given .dwo share the same abbrev table. Creating a cutu_reader for each unit meant re-reading the same abbrev table over and over. What's particularly bad is that this is done with the dwo_lock held, preventing other indexing threads from making progress. To give a rough idea, here's the time take by each worker to index units before this patch (on a rather large program): Time for "DWARF indexing worker": wall 18.627, user 0.885, sys 0.042, user+sys 0.927, 5.0 % CPU Time for "DWARF indexing worker": wall 18.888, user 0.862, sys 0.042, user+sys 0.904, 4.8 % CPU Time for "DWARF indexing worker": wall 19.172, user 1.848, sys 0.069, user+sys 1.917, 10.0 % CPU Time for "DWARF indexing worker": wall 19.297, user 1.544, sys 0.051, user+sys 1.595, 8.3 % CPU Time for "DWARF indexing worker": wall 19.545, user 3.408, sys 0.084, user+sys 3.492, 17.9 % CPU Time for "DWARF indexing worker": wall 19.759, user 4.221, sys 0.117, user+sys 4.338, 22.0 % CPU Time for "DWARF indexing worker": wall 19.789, user 4.187, sys 0.105, user+sys 4.292, 21.7 % CPU Time for "DWARF indexing worker": wall 19.825, user 4.933, sys 0.135, user+sys 5.068, 25.6 % CPU And the times with this patch: Time for "DWARF indexing worker": wall 0.163, user 0.089, sys 0.029, user+sys 0.118, 72.4 % CPU Time for "DWARF indexing worker": wall 0.176, user 0.096, sys 0.041, user+sys 0.137, 77.8 % CPU Time for "DWARF indexing worker": wall 0.265, user 0.167, sys 0.054, user+sys 0.221, 83.4 % CPU Time for "DWARF indexing worker": wall 0.353, user 0.257, sys 0.060, user+sys 0.317, 89.8 % CPU Time for "DWARF indexing worker": wall 0.524, user 0.399, sys 0.088, user+sys 0.487, 92.9 % CPU Time for "DWARF indexing worker": wall 0.648, user 0.517, sys 0.107, user+sys 0.624, 96.3 % CPU Time for "DWARF indexing worker": wall 0.657, user 0.523, sys 0.107, user+sys 0.630, 95.9 % CPU Time for "DWARF indexing worker": wall 0.753, user 0.612, sys 0.120, user+sys 0.732, 97.2 % CPU [1] https://inbox.sourceware.org/gdb-patches/20250326200002.136200-8-simon.marchi@efficios.com/ Change-Id: I34a422577e4c3ad7d478ec6df12a0e44d284c249 Approved-By: Tom Tromey <tom@tromey.com>
2025-04-29gdb/dwarf: replace some "compile unit" terminology with "unit"Simon Marchi10-177/+167
In DWARF 5 (and even previous versions, with type units), compile units are just one type of units. In many places, we still use "compile units" when in reality it would be better to talk about "units" (unless we specifically want to talk about compile units). Rename comp-unit-head.{c.h} to unit-head.{c,h}, and do a big pass of renames in it to remove the specific mentions of compile units, where in fact we want to talk about units in general. Change-Id: Ia06c90ccb25756c366f269a12620f2f7c8378adb Approved-By: Tom Tromey <tom@tromey.com>
2025-04-29gdb: add some scoped_time_its to profile startup timeSimon Marchi4-3/+20
I'm investigating some issues where GDB takes a lot of time to start up (read: for the DWARF index to be ready to do anything useful). Adding those scoped_time_it instances helped me gain some insights about where GDB spends time. I think they would be useful to have upstream, to make investigating future problems easier. It would also be useful to be able to give some numbers in the commit messages. Here's an example of what GDB outputs: Time for "minsyms install worker": wall 0.045, user 0.040, sys 0.004, user+sys 0.044, 97.8 % CPU Time for "minsyms install worker": wall 0.511, user 0.457, sys 0.048, user+sys 0.505, 98.8 % CPU Time for "minsyms install worker": wall 1.513, user 1.389, sys 0.111, user+sys 1.500, 99.1 % CPU Time for "minsyms install worker": wall 1.688, user 1.451, sys 0.102, user+sys 1.553, 92.0 % CPU Time for "minsyms install worker": wall 1.897, user 1.518, sys 0.089, user+sys 1.607, 84.7 % CPU Time for "minsyms install worker": wall 2.811, user 2.558, sys 0.231, user+sys 2.789, 99.2 % CPU Time for "minsyms install worker": wall 3.257, user 3.049, sys 0.188, user+sys 3.237, 99.4 % CPU Time for "minsyms install worker": wall 3.617, user 3.089, sys 0.211, user+sys 3.300, 91.2 % CPU Time for "DWARF indexing worker": wall 19.517, user 0.894, sys 0.075, user+sys 0.969, 5.0 % CPU Time for "DWARF indexing worker": wall 19.807, user 0.891, sys 0.086, user+sys 0.977, 4.9 % CPU Time for "DWARF indexing worker": wall 20.270, user 1.559, sys 0.119, user+sys 1.678, 8.3 % CPU Time for "DWARF indexing worker": wall 20.329, user 1.878, sys 0.147, user+sys 2.025, 10.0 % CPU Time for "DWARF indexing worker": wall 20.848, user 3.483, sys 0.224, user+sys 3.707, 17.8 % CPU Time for "DWARF indexing worker": wall 21.088, user 4.285, sys 0.295, user+sys 4.580, 21.7 % CPU Time for "DWARF indexing worker": wall 21.109, user 4.501, sys 0.274, user+sys 4.775, 22.6 % CPU Time for "DWARF indexing worker": wall 21.198, user 5.087, sys 0.319, user+sys 5.406, 25.5 % CPU Time for "DWARF skeletonless type units": wall 4.024, user 3.858, sys 0.115, user+sys 3.973, 98.7 % CPU Time for "DWARF add parent map": wall 0.092, user 0.086, sys 0.004, user+sys 0.090, 97.8 % CPU Time for "DWARF finalize worker": wall 0.278, user 0.241, sys 0.009, user+sys 0.250, 89.9 % CPU Time for "DWARF finalize worker": wall 0.307, user 0.304, sys 0.000, user+sys 0.304, 99.0 % CPU Time for "DWARF finalize worker": wall 0.727, user 0.719, sys 0.000, user+sys 0.719, 98.9 % CPU Time for "DWARF finalize worker": wall 0.913, user 0.901, sys 0.003, user+sys 0.904, 99.0 % CPU Time for "DWARF finalize worker": wall 0.776, user 0.767, sys 0.004, user+sys 0.771, 99.4 % CPU Time for "DWARF finalize worker": wall 1.897, user 1.869, sys 0.006, user+sys 1.875, 98.8 % CPU Time for "DWARF finalize worker": wall 2.534, user 2.512, sys 0.005, user+sys 2.517, 99.3 % CPU Time for "DWARF finalize worker": wall 2.607, user 2.583, sys 0.006, user+sys 2.589, 99.3 % CPU Time for "DWARF finalize worker": wall 3.142, user 3.094, sys 0.022, user+sys 3.116, 99.2 % CPU Change-Id: I9453589b9005c3226499428ae9cab9f4a8c22904 Approved-By: Tom Tromey <tom@tromey.com>
2025-04-29gdb: add scoped_time_itSimon Marchi3-1/+72
New in v2: - actually use m_enabled in the constructor and destructor - output using gdb_stdlog->write_async_safe instead of gdb_printf scoped_time_it is a small utility that measures and prints how much time a given thread spent in a given scope. Similar to the time(1) command, it prints the time spent in user mode, system mode, and the wall clock time. It also prints the CPU utilization percentage, which is: (user + sys) / wall This can help spot cases where the workload is not well balanced between workers, or the CPU utilization is not optimal (perhaps due to contention around a lock for example). To use it, just add it in some scope. For instance, a subsequent patch adds it here: workers.add_task ([this, task_count, iter, last] () { scoped_time_it time_it ("DWARF indexing worker"); process_cus (task_count, iter, last); }); On destruction, if enabled, it prints a line showing the time spent by that thread, similar to what time(1) prints. The example above prints this (one line for each worker thread): Time for "DWARF indexing worker": wall 0.173, user 0.120, sys 0.034, user+sys 0.154, 89.0 % CPU Time for "DWARF indexing worker": wall 0.211, user 0.144, sys 0.047, user+sys 0.191, 90.5 % CPU Time for "DWARF indexing worker": wall 0.368, user 0.295, sys 0.057, user+sys 0.352, 95.7 % CPU Time for "DWARF indexing worker": wall 0.445, user 0.361, sys 0.072, user+sys 0.433, 97.3 % CPU Time for "DWARF indexing worker": wall 0.592, user 0.459, sys 0.113, user+sys 0.572, 96.6 % CPU Time for "DWARF indexing worker": wall 0.739, user 0.608, sys 0.115, user+sys 0.723, 97.8 % CPU Time for "DWARF indexing worker": wall 0.831, user 0.677, sys 0.140, user+sys 0.817, 98.3 % CPU Time for "DWARF indexing worker": wall 0.949, user 0.789, sys 0.144, user+sys 0.933, 98.3 % CPU The object is only enabled if per_command_time (controlled by "maint set per-command time") is true at construction time. I wanted to avoid adding a new command for now, but eventually if there are too many scoped_time_it around the code base and we want to be able to enabled them selectively (e.g. just the ones in the DWARF reader, or in the symbol searching functions, etc), we could have a dedicated command for that. I added this functionality to GDB because it relies on gdb_printf and per_command_time, but if we ever need it in gdbsupport, I'm sure we could find a way to put it there. Change-Id: I5416ac1448f960f44d85f8449943d994198a271e Approved-By: Tom Tromey <tom@tromey.com>
2025-04-29gdbsupport: move run_time_clock::now(user, system) out of run_time_clockSimon Marchi1-1/+1
It is completely unrelated to run_time_clock, so I don't think it makes sense to have it as a static function there. Move it to be a free function named "get_run_time". Change-Id: I0c3e4d3cc44ca37e523c94d72f7cd66add95645e Approved-By: Tom Tromey <tom@tromey.com>
2025-04-29Handle base type without DW_AT_byte_sizeTom Tromey3-30/+59
DWARF says that a base type can have DW_AT_bit_size, without DW_AT_byte_size. However, gdb does not correctly handle this; in fact, it crashes, as pointed out in this LLVM merge request: https://github.com/llvm/llvm-project/pull/137123 This patch reworks the base type size logic a bit to handle this situation. Tested-by: Kevin Buettner <kevinb@redhat.com> Approved-by: Kevin Buettner <kevinb@redhat.com>
2025-04-29[gdb/contrib] Add script to license check new filesKeith Seitz1-0/+149
While reading through gdb-patches backlog after a return from PTO, I noticed that a newly added file was licensed with "MIT", and that license was not listed in Fedora's gdb.spec file. [Fedora no longer supports "effective" licenses.] That lead me to this simple script which generates a list of all the newly added files between two given commits and scans these files for licenses. Example usage: bash$ cd /path/to/binutils-gdb/gdb bash$ ./contrib/license-check-new-files.sh -s gdb-15-branchpoint gdb-16-branchpoint Scanning directories gdb*/... gdb/contrib/common-misspellings.txt: no longer in repo? gdb/contrib/spellcheck.sh: no longer in repo? gdbsupport/unordered_dense.h: MIT I don't think anything in here is Fedora- or RPM-specific, so I'd like to submit this for consideration for inclusion in contrib/. I believe other distros may find it useful. Approved-By: Tom Tromey <tom@tromey.com>
2025-04-29Change acronym BFD to Binary File Descriptor.Jeremy Bryant1-1/+1
This fixes a typo in gdb/README. Approved-By: Tom Tromey <tom@tromey.com>
2025-04-29[gdb/testsuite] Fix gdb.base/ptype.exp with gcc 15Tom de Vries1-4/+4
With test-case gdb.base/ptype.exp and gcc 15 I run into: ... (gdb) ptype old_fptr^M type = double (*)(void)^M (gdb) FAIL: $exp: ptype old_fptr (compiler doesn't emit unprototyped types) ... Since C23, non-prototype function declarations are no longer supported, so "double (*old_fptr) ()" is interpreted as "double (*old_fptr) (void)". We could try to fix this by detecting the language dialect used, and accepting the output in that case, but that feels fragile. We could try to fix this by hard-coding the language dialect, but that doesn't work for all compilers. So instead, we opt for the simplest solution: just accept this output, and produce a pass. Tested on aarch64-linux. Approved-By: Tom Tromey <tom@tromey.com> PR testsuite/32756 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32756
2025-04-29[gdb/testsuite] Fix gdb.python/py-objfile.exp with gcc 15Tom de Vries4-5/+8
When running test-case gdb.python/py-objfile.exp with gcc 15, we get: ... (gdb) p main^M $2 = {int (void)} 0x40066c <main>^M (gdb) FAIL: $exp: print main with debug info ... The source file declares main as "int main ()" ... and until C23 this meant a non-prototype function declaration and we'd have: ... (gdb) p main^M $2 = {int ()} 0x40066c <main>^M ... However, starting C23 "int main ()" is simply equivalent to "int main (void)". Fix this by: - declaring main as "int main (void)" in the test-case, and - updating the regexp to expect an "int (void)" prototype. Likewise in gdb.base/jit-bfd-name.exp. Tested on aarch64-linux. Approved-By: Tom Tromey <tom@tromey.com> PR testsuite/32756 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32756
2025-04-29[gdb/testsuite] Don't use string_to_regexp twice in gdb.base/options.expTom de Vries1-2/+1
In test-case gdb.base/options.exp, in proc test_completer_recognizes we have: ... set expected_re [string_to_regexp $input_line] test_gdb_complete_unique $input_line $expected_re ... However, the first thing we do in proc test_gdb_complete_unique is to apply string_to_regexp to the second argument: ... proc test_gdb_complete_unique { input_line complete_line {append_char " "} {max_completions false} {testname ""} } { set complete_line_re [string_to_regexp $complete_line] test_gdb_complete_unique_re \ $input_line \ $complete_line_re \ $append_char \ $max_completions\ $testname } ... This happens to not cause any FAILs at the moment, but this should be done only once. Fix this not using string_to_regexp in proc test_completer_recognizes. Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com>
2025-04-29[gdb] Handle nullptr gdb_std{err,out} in {gdbpy,ioscm}_flushTom de Vries2-5/+14
Using the trigger patch described in the previous commit, I get: ... $ gdb (gdb) <q>error detected on stdin Fatal signal: Segmentation fault ----- Backtrace ----- 0x64c7b3 gdb_internal_backtrace_1 /data/vries/gdb/src/gdb/bt-utils.c:127 0x64c937 _Z22gdb_internal_backtracev /data/vries/gdb/src/gdb/bt-utils.c:196 0x94db83 handle_fatal_signal /data/vries/gdb/src/gdb/event-top.c:1021 0x94dd48 handle_sigsegv /data/vries/gdb/src/gdb/event-top.c:1098 0x7f372be578ff ??? 0x10b7c0a _Z9gdb_flushP7ui_file /data/vries/gdb/src/gdb/utils.c:1527 0xd4b938 gdbpy_flush /data/vries/gdb/src/gdb/python/python.c:1624 0x7f372d73b276 _PyCFunction_FastCallDict Objects/methodobject.c:231 0x7f372d73b276 _PyCFunction_FastCallKeywords Objects/methodobject.c:294 0x7f372d794a09 call_function Python/ceval.c:4851 0x7f372d78e838 _PyEval_EvalFrameDefault Python/ceval.c:3351 0x7f372d796e6e PyEval_EvalFrameEx Python/ceval.c:754 0x7f372d796e6e _PyFunction_FastCall Python/ceval.c:4933 0x7f372d796e6e _PyFunction_FastCallDict Python/ceval.c:5035 0x7f372d6fefc8 _PyObject_FastCallDict Objects/abstract.c:2310 0x7f372d6fefc8 _PyObject_Call_Prepend Objects/abstract.c:2373 0x7f372d6fe162 _PyObject_FastCallDict Objects/abstract.c:2331 0x7f372d700705 callmethod Objects/abstract.c:2583 0x7f372d700705 _PyObject_CallMethodId Objects/abstract.c:2640 0x7f372d812a41 flush_std_files Python/pylifecycle.c:699 0x7f372d81281d Py_FinalizeEx Python/pylifecycle.c:768 0xd4d49b finalize_python /data/vries/gdb/src/gdb/python/python.c:2308 0x9587eb _Z17ext_lang_shutdownv /data/vries/gdb/src/gdb/extension.c:330 0xfd98df _Z10quit_forcePii /data/vries/gdb/src/gdb/top.c:1817 0x6b3080 _Z12quit_commandPKci /data/vries/gdb/src/gdb/cli/cli-cmds.c:483 0x1056577 stdin_event_handler /data/vries/gdb/src/gdb/ui.c:131 0x1986970 handle_file_event /data/vries/gdb/src/gdbsupport/event-loop.cc:551 0x1986f4b gdb_wait_for_event /data/vries/gdb/src/gdbsupport/event-loop.cc:672 0x1985e0c _Z16gdb_do_one_eventi /data/vries/gdb/src/gdbsupport/event-loop.cc:263 0xb66f2e start_event_loop /data/vries/gdb/src/gdb/main.c:402 0xb670ba captured_command_loop /data/vries/gdb/src/gdb/main.c:466 0xb68b9b captured_main /data/vries/gdb/src/gdb/main.c:1344 0xb68c44 _Z8gdb_mainP18captured_main_args /data/vries/gdb/src/gdb/main.c:1363 0x41a3b1 main /data/vries/gdb/src/gdb/gdb.c:38 --------------------- A fatal error internal to GDB has been detected, further debugging is not possible. GDB will now terminate. This is a bug, please report it. For instructions, see: <https://www.gnu.org/software/gdb/bugs/>. Segmentation fault (core dumped) $ q ... Fix this in gdbpy_flush by checking for nullptr gdb_stdout/gdb_stderr (and likewise in ioscm_flush) such that we get instead: ... $ gdb (gdb) <q>error detected on stdin $ q ... Tested on x86_64-linux. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2025-04-29[gdb] Fix sig_write for null gdb_stderrTom de Vries2-7/+16
When running test-case gdb.tui/tui-layout-asm.exp with target board dwarf5-fission-debug-types, the test-case fails and I get a core dump: ... # of unexpected core files 1 ... Looking at the backtrace of the core file, what seems to be happening is that: - gdbpy_flush attempts to flush gdb_stdout, which is nullptr - that causes a segfault - gdb intercepts this and starts to handle it using handle_fatal_signal - handle_fatal_signal calls sig_write, which attempts to write to gdb_stderr, which is nullptr, - that causes another segfault - gdb exits I managed to reproduce the problem by the following trigger patch in stdin_event_handler: ... - if (error) + if (1 || error) { current_ui = main_ui; ui->unregister_file_handler (); - if (main_ui == ui) + if (1 || main_ui == ui) { gdb_printf (gdb_stderr, _("error detected on stdin\n")); + gdb_stderr = nullptr; + gdb_stdout = nullptr; + gdb_stdlog = nullptr; quit_command ((char *) 0, 0); } ... which gives us: ... $ gdb (gdb) <q>error detected on stdin Segmentation fault (core dumped) $ q ... Fix sig_write to handle the case that gdb_stderr == nullptr, such that we get instead: ... $ gdb (gdb) <q>error detected on stdin Fatal signal: Segmentation fault ----- Backtrace ----- ... --------------------- A fatal error internal to GDB has been detected, further debugging is not possible. GDB will now terminate. This is a bug, please report it. For instructions, see: <https://www.gnu.org/software/gdb/bugs/>. Segmentation fault (core dumped) $ q ... Tested on x86_64-linux. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2025-04-29[gdb] Factor out sig_writeTom de Vries3-25/+13
Lambda function sig_write: ... const auto sig_write = [] (const char *msg) -> void { gdb_stderr->write_async_safe (msg, strlen (msg)); } ... is defined a few times. Factor this out into a regular function. Tested on x86_64-linux. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2025-04-28Fix "set debug parser"Tom Tromey5-3/+29
While debugging my longer series, I discovered that I broken "set debug parser" a couple years ago. This patch fixes it and adds a minimal test case so that it, hopefully, will not break again. This patch also adds parser debugging to the C++ name canonicalizer. Thanks to Tom de Vries for fixing the test case.
2025-04-28Regenerate more configury files for 64-bit BFD detection fixMaciej W. Rozycki1-3/+0
The fix for 64-bit BFD detection omitted the regeneration of a bunch of configury files; fix that.
2025-04-28Fix 64-bit BFD detection causing build failuresMaciej W. Rozycki3-98/+42
We have a discrepancy with 64-bit BFD handling across our component subdirectories leading to link failures such as: ld: ../opcodes/.libs/libopcodes.a(disassemble.o): in function `disassembler': disassemble.c:(.text+0x65): undefined reference to `print_insn_alpha' ld: disassemble.c:(.text+0x105): undefined reference to `print_insn_ia64' ld: disassemble.c:(.text+0x11d): undefined reference to `print_insn_loongarch' ld: disassemble.c:(.text+0x1a1): undefined reference to `print_insn_big_mips' [...] with some configurations having a 32-bit host and 64-bit BFD, such as: `--host=i386-linux-gnu --target=riscv64-linux-gnu --enable-targets=all'. This is ultimately due to how 64-bit BFD is enabled for bfd/ itself and other subdirectorses and has been a regression from commit 1d5269c994bf ("unify 64-bit bfd checks"). For bfd/ the BFD_64_BIT autoconf macro from config/bfd64.m4 is used combined with this logic in bfd/configure.ac: case ${host64}-${target64}-${want64} in *true*) wordsize=64 bfd64_libs='$(BFD64_LIBS)' all_backends='$(BFD64_BACKENDS) $(BFD32_BACKENDS)' [...] ;; false-false-false) wordsize=32 all_backends='$(BFD32_BACKENDS)' ;; esac where the value of ${wordsize} switches between 32-bit and 64-bit BFD via these pieces: #define BFD_ARCH_SIZE @wordsize@ and: #if BFD_ARCH_SIZE >= 64 #define BFD64 #endif in bfd/bfd-in.h, which ultimately becomes a part of "bfd.h". Then ${host64} is determined in bfd/configure.ac from the host's word size, via the host's pointer size: if test "x${ac_cv_sizeof_void_p}" = "x8"; then host64=true fi And ${target64} is determined in bfd/configure.ac from the target's word size: if test ${target_size} = 64; then target64=true fi Where multiple targets have been requested with `--enable-targets=all' the presence of any 64-bit target will set "true" here. Finally ${want64} is set according to `--enable-64-bit-bfd' user option with an arrangement involving BFD_64_BIT: BFD_64_BIT if test $enable_64_bit_bfd = yes ; then want64=true else want64=false fi which also, redundantly, checks and sets its result upon the host's word size. Lastly ${want64} is also selectively set by target fragments in bfd/config.bfd, which mostly if not completely overlaps with ${target64} setting as described above. Conversely other subdirectories only rely on BFD_64_BIT, so they fail to notice that BFD is 64-bit and do not enable their 64-bit handling where the host requested is 32-bit and 64-bit BFD has been enabled other than with `--enable-64-bit-bfd'. One consequence is opcodes/disassemble.c enables calls to its numerous own 64-bit backends by checking the BFD64 macro from "bfd.h", however does not actually enable said backends in its Makefile. Hence the link errors quoted above. Address the problem then by moving the `--enable-64-bit-bfd' option back to bfd/configure.ac and remove the call to BFD_64_BIT from there and then rewrite the macro in terms of checking for the presence of BFD64 macro in "bfd.h", which is the canonical way of determining whether BFD is 64-bit or not. Rather than running `grep' directly on ../bfd/bfd-in3.h as the opcodes/ fragment used to before the problematic commit: if grep '#define BFD_ARCH_SIZE 64' ../bfd/bfd-in3.h > /dev/null; then run the preprocessor on "bfd.h", which allows to invoke the macro from configure.ac files placed in subdirectories located at deeper levels, by relying on the preprocessor's search path. This requires however that the invokers rely on `all-bfd' rather than `configure-bfd' for their `configure' invocation stage, because "bfd.h" is made by `make all' rather than `configure' in bfd/. Do not cache the result of this check however, as reconfiguring a tree such as to flip `--enable-64-bit-bfd' on or to change a secondary target may affect BFD64 and we have no access to information about secondary targets in BFD_64_BIT. Also remove the ENABLE_BFD_64_BIT automake conditional, as it's not used anywhere. Last but not least remove the hack from gdb/configure.ac to fail builds for `mips*-*-*' hosts where `--enable-targets=all' has been requested, but `--enable-64-bit-bfd' has not as it's no longer needed. Such builds complete successfully now, having enabled 64-bit BFD implicitly. Tested-By: Guinevere Larsen <guinevere@redhat.com> Tested-By: Luis Machado <luis.machado@arm.com> Approved-By: Alan Modra <amodra@gmail.com> Approved-By: Luis Machado <luis.machado@arm.com>