Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package gdb for openSUSE:Factory checked in at 2026-03-19 17:31:33 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/gdb (Old) and /work/SRC/openSUSE:Factory/.gdb.new.8177 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "gdb" Thu Mar 19 17:31:33 2026 rev:192 rq:1340997 version:16.3 Changes: -------- --- /work/SRC/openSUSE:Factory/gdb/gdb.changes 2026-02-17 16:37:32.698834990 +0100 +++ /work/SRC/openSUSE:Factory/.gdb.new.8177/gdb.changes 2026-03-19 17:33:07.027216834 +0100 @@ -1,0 +2,50 @@ +Tue Mar 17 13:33:27 UTC 2026 - Tom de Vries <[email protected]> + +- Testsuite fixes. Patches added: + * add-proc-subst_vars.patch + * gdb-testsuite-fix-printf-regexp-for-ppc64le-with-gli.patch + +------------------------------------------------------------------- +Tue Mar 17 09:37:35 UTC 2026 - Tom de Vries <[email protected]> + +- Re-enable ptype /o for flexible array member types (swo#33966, + bsc#1249147). Patches added: + * gdb-minor-refactoring-of-is_dynamic_type_internal.patch + * gdb-factor-out-is_dynamic_type_internal_1.patch + * gdb-enable-ptype-o-for-some-dynamic-types.patch + +------------------------------------------------------------------- +Tue Mar 17 09:30:12 UTC 2026 - Tom de Vries <[email protected]> + +- Fix TUI crash when encountering a debuginfod query while entering + TUI (swo#31449, swo#33794). Patches added: + * gdb-simplify-debuginfod_is_enabled.patch + * gdb-add-debuginfod_enabled_ask_p.patch + * gdb-add-defaulted_query_auto_answers_p.patch + * gdb-tui-don-t-enter-tui-if-debuginfod-enabled-ask.patch + +------------------------------------------------------------------- +Tue Mar 17 09:18:25 UTC 2026 - Tom de Vries <[email protected]> + +- Fix a case on x86_64/-m32 where displaced stepping steps out of + the displaced stepping buffer (swo#33997). Patches added: + * gdb-tdep-fix-unrelocated-pc-in-i386_displaced_step_f.patch + +------------------------------------------------------------------- +Tue Feb 17 21:43:09 UTC 2026 - Tom de Vries <[email protected]> + +- Fix generation of core files using gcore for glibc 2.42 + (swo#33855). Patches added: + * gcore-handle-unreadable-pages-within-readable-memory.patch + * gcore-query-auxv-for-at_pagesz-in-gcore_copy_callbac.patch + Maintenance script qa.sh: + * Remove PR33054 kfails. +- Maintenance script qa.sh cleanup: + * Remove kfails for: PR30548, PR30537, PR31061, PR30519, PR31001, + PR31229, PR32678, PR29706, PR28510, PR31721, PR19436, PR30528, + PR31440, PR31806, PR31831. + * Remove kfail_s390 and kfail_sle11. + * Remove gdb.reverse/{solib-precsave,solib-reverse}.exp kfail. + * Remove gdb.base/gdb-rhbz1156192-recursive-dlopen.exp kfail. + +------------------------------------------------------------------- New: ---- add-proc-subst_vars.patch gcore-handle-unreadable-pages-within-readable-memory.patch gcore-query-auxv-for-at_pagesz-in-gcore_copy_callbac.patch gdb-add-debuginfod_enabled_ask_p.patch gdb-add-defaulted_query_auto_answers_p.patch gdb-enable-ptype-o-for-some-dynamic-types.patch gdb-factor-out-is_dynamic_type_internal_1.patch gdb-minor-refactoring-of-is_dynamic_type_internal.patch gdb-simplify-debuginfod_is_enabled.patch gdb-tdep-fix-unrelocated-pc-in-i386_displaced_step_f.patch gdb-testsuite-fix-printf-regexp-for-ppc64le-with-gli.patch gdb-tui-don-t-enter-tui-if-debuginfod-enabled-ask.patch ----------(New B)---------- New:- Testsuite fixes. Patches added: * add-proc-subst_vars.patch * gdb-testsuite-fix-printf-regexp-for-ppc64le-with-gli.patch New: (swo#33855). Patches added: * gcore-handle-unreadable-pages-within-readable-memory.patch * gcore-query-auxv-for-at_pagesz-in-gcore_copy_callbac.patch New: * gcore-handle-unreadable-pages-within-readable-memory.patch * gcore-query-auxv-for-at_pagesz-in-gcore_copy_callbac.patch Maintenance script qa.sh: New: * gdb-simplify-debuginfod_is_enabled.patch * gdb-add-debuginfod_enabled_ask_p.patch * gdb-add-defaulted_query_auto_answers_p.patch New: * gdb-add-debuginfod_enabled_ask_p.patch * gdb-add-defaulted_query_auto_answers_p.patch * gdb-tui-don-t-enter-tui-if-debuginfod-enabled-ask.patch New: * gdb-factor-out-is_dynamic_type_internal_1.patch * gdb-enable-ptype-o-for-some-dynamic-types.patch New: * gdb-minor-refactoring-of-is_dynamic_type_internal.patch * gdb-factor-out-is_dynamic_type_internal_1.patch * gdb-enable-ptype-o-for-some-dynamic-types.patch New: bsc#1249147). Patches added: * gdb-minor-refactoring-of-is_dynamic_type_internal.patch * gdb-factor-out-is_dynamic_type_internal_1.patch New: TUI (swo#31449, swo#33794). Patches added: * gdb-simplify-debuginfod_is_enabled.patch * gdb-add-debuginfod_enabled_ask_p.patch New: the displaced stepping buffer (swo#33997). Patches added: * gdb-tdep-fix-unrelocated-pc-in-i386_displaced_step_f.patch New: * add-proc-subst_vars.patch * gdb-testsuite-fix-printf-regexp-for-ppc64le-with-gli.patch New: * gdb-add-defaulted_query_auto_answers_p.patch * gdb-tui-don-t-enter-tui-if-debuginfod-enabled-ask.patch ----------(New E)---------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ gdb.spec ++++++ --- /var/tmp/diff_new_pack.jKGril/_old 2026-03-19 17:33:17.031631657 +0100 +++ /var/tmp/diff_new_pack.jKGril/_new 2026-03-19 17:33:17.031631657 +0100 @@ -298,6 +298,10 @@ Patch2523: gdb-tdep-fix-gdb.base-siginfo.exp-on-s390x-linux.patch Patch2524: gdb-testsuite-remove-guile-test-byte-at-sp-before-fl.patch Patch2525: gdb-fix-gdb.base-inline-frame-cycle-unwind.exp-for-s.patch +Patch2526: gcore-handle-unreadable-pages-within-readable-memory.patch +Patch2527: gcore-query-auxv-for-at_pagesz-in-gcore_copy_callbac.patch +Patch2528: gdb-testsuite-fix-printf-regexp-for-ppc64le-with-gli.patch +Patch2529: add-proc-subst_vars.patch # Backport from gdb-patches @@ -334,6 +338,17 @@ # https://sourceware.org/pipermail/gdb-patches/2025-November/222919.html # Todo: submit arm part. Patch3020: powerpc-mark-rtti-typeid-tests-as-expected-fail-befo.patch +# https://sourceware.org/pipermail/gdb-patches/2026-March/226050.html +Patch3021: gdb-tdep-fix-unrelocated-pc-in-i386_displaced_step_f.patch +# https://sourceware.org/pipermail/gdb-patches/2026-March/226009.html +Patch3022: gdb-simplify-debuginfod_is_enabled.patch +Patch3023: gdb-add-debuginfod_enabled_ask_p.patch +Patch3024: gdb-add-defaulted_query_auto_answers_p.patch +Patch3025: gdb-tui-don-t-enter-tui-if-debuginfod-enabled-ask.patch +# https://sourceware.org/pipermail/gdb-patches/2026-March/225792.html +Patch3026: gdb-minor-refactoring-of-is_dynamic_type_internal.patch +Patch3027: gdb-factor-out-is_dynamic_type_internal_1.patch +Patch3028: gdb-enable-ptype-o-for-some-dynamic-types.patch # Debug patches. @@ -758,6 +773,10 @@ %patch -P 2523 -p1 %patch -P 2524 -p1 %patch -P 2525 -p1 +%patch -P 2526 -p1 +%patch -P 2527 -p1 +%patch -P 2528 -p1 +%patch -P 2529 -p1 %patch -P 3000 -p1 %patch -P 3001 -p1 @@ -773,6 +792,14 @@ %patch -P 3018 -p1 %patch -P 3019 -p1 %patch -P 3020 -p1 +%patch -P 3021 -p1 +%patch -P 3022 -p1 +%patch -P 3023 -p1 +%patch -P 3024 -p1 +%patch -P 3025 -p1 +%patch -P 3026 -p1 +%patch -P 3027 -p1 +%patch -P 3028 -p1 %patch -P 3500 -p1 ++++++ _scmsync.obsinfo ++++++ --- /var/tmp/diff_new_pack.jKGril/_old 2026-03-19 17:33:17.147636467 +0100 +++ /var/tmp/diff_new_pack.jKGril/_new 2026-03-19 17:33:17.155636798 +0100 @@ -1,5 +1,5 @@ -mtime: 1770907926 -commit: 9fbb0c682577f632d01252fb790352de3aa480952b4452c63096afce1f53d6b1 +mtime: 1773764094 +commit: 26c27d968dfee4bed785b62e9d15b787d7c1faa448861a7fdc4c38dcf5d3fd44 url: https://src.opensuse.org/gcc/gdb.git revision: main ++++++ add-proc-subst_vars.patch ++++++ >From 7cf30f7f6a6358bc16d04b40524106dd6a7480e6 Mon Sep 17 00:00:00 2001 From: Tom de Vries <[email protected]> Date: Wed, 22 Oct 2025 07:36:07 +0200 Subject: [PATCH 2/2] Add proc subst_vars Add proc subst_vars, an alias of subst -nobackslashes -nocommands. I've used tailcall to implement this: ... proc subst_vars { str } { tailcall subst -nobackslashes -nocommands $str } ... but I found that this also works: ... proc subst_vars { str } { return [uplevel 1 [list subst -nobackslashes -nocommands $str]] } ... I've found other uses of subst that don't add "-nobackslashes -nocommands", but really only use subst to do variable substitution. Also use subst_vars in those cases. Tested on x86_64-linux. Approved-By: Tom Tromey <[email protected]> --- gdb/testsuite/lib/gdb-utils.exp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gdb/testsuite/lib/gdb-utils.exp b/gdb/testsuite/lib/gdb-utils.exp index 34223e654ed..1999701b0a5 100644 --- a/gdb/testsuite/lib/gdb-utils.exp +++ b/gdb/testsuite/lib/gdb-utils.exp @@ -236,3 +236,9 @@ proc with_lock { lock_file body } { return -code $code $result } } + +# Alias for subst -nobackslashes -nocommands. + +proc subst_vars { str } { + tailcall subst -nobackslashes -nocommands $str +} -- 2.51.0 ++++++ build.specials.obscpio ++++++ ++++++ build.specials.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/.gitignore new/.gitignore --- old/.gitignore 1970-01-01 01:00:00.000000000 +0100 +++ new/.gitignore 2026-03-17 17:16:07.000000000 +0100 @@ -0,0 +1 @@ +.osc ++++++ gcore-handle-unreadable-pages-within-readable-memory.patch ++++++ >From d4387f9b56295835508d5c2886d28fc73e00aa3a Mon Sep 17 00:00:00 2001 From: Kevin Buettner <[email protected]> Date: Thu, 29 Jan 2026 15:09:24 -0700 Subject: [PATCH] gcore: Handle unreadable pages within readable memory regions GLIBC 2.42 changed how thread stack guard pages are implemented [2]. In GLIBC 2.41 and earlier, guard pages were set up using mprotect() to mark guard regions with no permissions. Once configured, guard pages were visible as separate entries in /proc/PID/maps with no permissions (i.e. they're inaccessible). In GLIBC 2.42, guard pages are installed using the kernel's MADV_GUARD_INSTALL mechanism [1], which marks them at the page table entry (PTE) level within the existing mapping. As a consequence, guard pages do not appear as separate entries in /proc/PID/maps, but remain as part of the containing mapping. Moreover, thread stacks from multiple mmap() calls may be merged into a single virtual memory area (VMA) with read and write permissions since there's no guard page VMA to separate them. These guard pages cannot be distinguished by examining VMA listings but do return EIO when read from /proc/PID/mem. GDB's gcore code reads /proc/PID/smaps to discover memory regions and creates one BFD section per mapping. (On linux, this is performed in linux_find_memory_regions_full in linux-tdep.c.) With the old layout, memory areas with guard pages appeared separately with no permissions, which were filtered out. Each thread stack became its own section containing only readable data. With the new layout, using MADV_GUARD_INSTALL instead of the older mechanism, it's often the case that thread stacks created with multiple calls to mmap() are exposed as a single mapping appearing in /proc/PID/smaps with read and write permissions. Should that happen, GDB's code creates a single section covering all thread stacks and their guard pages. (Even if each thread stack appears in its own mapping, the fact remains that there will be an inaccessible portion of the mapping. When one or more thread stacks are coalesced into a single mapping, there will be several inaccessible "holes" representing the guard pages.) When gcore_copy_callback copies section contents, it reads memory in 1MB (MAX_COPY_BYTES) chunks. If any page in the chunk is a guard page, the call to target_read_memory() fails. The old code responded by breaking out of the copy loop, abandoning the entire section. This prevents correct copying of thread stack data, resulting in core files with zero-filled thread stacks, resulting in nearly empty backtraces. Fix this by falling back to page-by-page reading when a 1MB chunk read fails. Individual pages that cannot be read are filled with zeros, allowing the remaining readable memory to be captured. I also considered a simpler change using the value of FALLBACK_PAGE_SIZE (4096) as the read size instead of MAX_COPY_BYTES (1MB). This would avoid the fallback logic but would cause up to 256x more syscalls. The proposed approach also allows meaningful warnings: we warn only if an entire region is unreadable (indicating a real problem), whereas per-page reads would make it harder to distinguish guard page failures from actual errors. Since guard pages are at offset 0 for downward-growing stacks, a large target_read_memory() fails early at the first unreadable byte anyway. With this fix, I see 16 failures resolved in the following test cases: gdb.ada/task_switch_in_core.exp gdb.arch/i386-tls-regs.exp gdb.threads/threadcrash.exp gdb.threads/tls-core.exp Looking at just one of these, from gdb.log without the fix, I see: thread apply 5 backtrace Thread 5 (LWP 3414829): #0 0x00007ffff7d1d982 in __syscall_cancel_arch () from /lib64/libc.so.6 #1 0x0000000000000000 in ?? () (gdb) FAIL: gdb.threads/threadcrash.exp: test_gcore: thread apply 5 backtrace And this is what it looks like with the fix in place (some paths have been shortened): thread apply 5 backtrace Thread 5 (Thread 0x7fffeffff6c0 (LWP 1282651) "threadcrash"): #0 0x00007ffff7d1d982 in __syscall_cancel_arch () from /lib64/libc.so.6 #1 0x00007ffff7d11c3c in __internal_syscall_cancel () from /lib64/libc.so.6 #2 0x00007ffff7d61b62 in clock_nanosleep@GLIBC_2.2.5 () from /lib64/libc.so.6 #3 0x00007ffff7d6db37 in nanosleep () from /lib64/libc.so.6 #4 0x00007ffff7d8008e in sleep () from /lib64/libc.so.6 #5 0x00000000004006a8 in do_syscall_task (location=NORMAL) at threadcrash.c:158 #6 0x0000000000400885 in thread_function (arg=0x404340) at threadcrash.c:277 #7 0x00007ffff7d15464 in start_thread () from /lib64/libc.so.6 #8 0x00007ffff7d985ac in __clone3 () from /lib64/libc.so.6 (gdb) PASS: gdb.threads/threadcrash.exp: test_live_inferior: thread apply 5 backtrace Regression testing on Fedora 42 (glibc 2.41) shows no new failures. The v1 patch used SPARSE_BLOCK_SIZE as the fallback size. While it was the correct size, it's used for an entirely different purpose elsewhere in this file. This v2 commit introduces the constant FALLBACK_PAGE_SIZE instead. References: [1] Linux commit 662df3e5c376 ("mm: madvise: implement lightweight guard page mechanism") https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=662df3e5c37666d6ed75c88098699e070a4b35b5 [2] glibc commit a6fbe36b7f31 ("nptl: Add support for setup guard pages with MADV_GUARD_INSTALL") https://sourceware.org/git/?p=glibc.git;a=commit;h=a6fbe36b7f31292981422692236465ab56670ea9 Claude Opus 4.5 and GLM 4.7 assisted with the development of this commit. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33855 Approved-By: Tom de Vries <[email protected]> --- gdb/gcore.c | 52 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/gdb/gcore.c b/gdb/gcore.c index 969a8543ba2..38f6880d71c 100644 --- a/gdb/gcore.c +++ b/gdb/gcore.c @@ -744,6 +744,12 @@ sparse_bfd_set_section_contents (bfd *obfd, asection *osec, return true; } +/* Fallback page size to use when target_read_memory fails when attempting + to read MAX_COPY_BYTES in gcore_copy_callback. 4KB is the correct size + to use for x86 and most other architectures. Some may have larger pages, + but this size will still work at the cost of more syscalls. */ +#define FALLBACK_PAGE_SIZE 0x1000 + static void gcore_copy_callback (bfd *obfd, asection *osec) { @@ -766,15 +772,45 @@ gcore_copy_callback (bfd *obfd, asection *osec) if (size > total_size) size = total_size; - if (target_read_memory (bfd_section_vma (osec) + offset, - memhunk.data (), size) != 0) + CORE_ADDR vma = bfd_section_vma (osec) + offset; + + if (target_read_memory (vma, memhunk.data (), size) != 0) { - warning (_("Memory read failed for corefile " - "section, %s bytes at %s."), - plongest (size), - paddress (current_inferior ()->arch (), - bfd_section_vma (osec))); - break; + /* Large read failed. This can happen when the memory region + contains unreadable pages (such as guard pages embedded within + a larger mapping). Fall back to reading page by page, filling + unreadable pages with zeros. */ + gdb_byte *p = memhunk.data (); + bfd_size_type remaining = size; + CORE_ADDR addr = vma; + bool at_least_one_page_read = false; + + while (remaining > 0) + { + bfd_size_type chunk_size + = std::min (remaining, (bfd_size_type) FALLBACK_PAGE_SIZE); + + if (target_read_memory (addr, p, chunk_size) != 0) + { + /* Failed to read this page. Fill with zeros. This + handles guard pages and other unreadable regions + that may exist within a larger readable mapping. */ + memset (p, 0, chunk_size); + } + else + at_least_one_page_read = true; + + p += chunk_size; + addr += chunk_size; + remaining -= chunk_size; + } + /* Warn only if the entire region was unreadable - this + indicates a real problem, not just embedded guard pages. */ + if (!at_least_one_page_read) + warning (_("Memory read failed for corefile " + "section, %s bytes at %s."), + plongest (size), + paddress (current_inferior ()->arch (), vma)); } if (!sparse_bfd_set_section_contents (obfd, osec, memhunk.data (), base-commit: ad06ed5638c51ca0213d327b6e685455c67975be -- 2.51.0 ++++++ gcore-query-auxv-for-at_pagesz-in-gcore_copy_callbac.patch ++++++ >From ccc03544a6bc2f886e06d8b477a84eb8b2033e31 Mon Sep 17 00:00:00 2001 From: Kevin Buettner <[email protected]> Date: Tue, 17 Feb 2026 19:09:48 -0700 Subject: [PATCH] gcore: Query auxv for AT_PAGESZ in gcore_copy_callback This is a followup patch to commit c1da013915e, titled "gcore: Handle unreadable pages within readable memory regions". In his review of that earlier patch, Tom de Vries recommended using target_auxv_search with AT_PAGESZ to find the page size if it's available; this patch implements that suggestion. As before, a 4k fallback size is used should the search for an AT_PAGESZ value not succeed. --- gdb/gcore.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/gdb/gcore.c b/gdb/gcore.c index 38f6880d71c..6482c8913aa 100644 --- a/gdb/gcore.c +++ b/gdb/gcore.c @@ -37,6 +37,7 @@ #include "gdbsupport/gdb_unlinker.h" #include "gdbsupport/byte-vector.h" #include "gdbsupport/scope-exit.h" +#include "auxv.h" /* To generate sparse cores, we look at the data to write in chunks of this size when considering whether to skip the write. Only if we @@ -767,6 +768,11 @@ gcore_copy_callback (bfd *obfd, asection *osec) size = std::min (total_size, (bfd_size_type) MAX_COPY_BYTES); gdb::byte_vector memhunk (size); + bfd_size_type page_size = FALLBACK_PAGE_SIZE; + CORE_ADDR at_pagesz; + if (target_auxv_search (AT_PAGESZ, &at_pagesz) > 0) + page_size = (bfd_size_type) at_pagesz; + while (total_size > 0) { if (size > total_size) @@ -787,8 +793,7 @@ gcore_copy_callback (bfd *obfd, asection *osec) while (remaining > 0) { - bfd_size_type chunk_size - = std::min (remaining, (bfd_size_type) FALLBACK_PAGE_SIZE); + bfd_size_type chunk_size = std::min (remaining, page_size); if (target_read_memory (addr, p, chunk_size) != 0) { base-commit: d4387f9b56295835508d5c2886d28fc73e00aa3a -- 2.51.0 ++++++ gdb-add-debuginfod_enabled_ask_p.patch ++++++ >From 9988e69be7216b688ca3963515e0829803ab6fdf Mon Sep 17 00:00:00 2001 From: Tom de Vries <[email protected]> Date: Sat, 14 Mar 2026 15:26:42 +0100 Subject: [PATCH 3/8] [gdb] Add debuginfod_enabled_ask_p Factor out debuginfod_is_enabled_1 out of debuginfod_is_enabled, and use it to implement debuginfod_enabled_ask_p. --- gdb/debuginfod-support.c | 40 +++++++++++++++++++++++++++++++--------- gdb/debuginfod-support.h | 5 +++++ 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/gdb/debuginfod-support.c b/gdb/debuginfod-support.c index f97c1f921ab..5ced58b410e 100644 --- a/gdb/debuginfod-support.c +++ b/gdb/debuginfod-support.c @@ -222,20 +222,20 @@ get_debuginfod_client () return global_client; } -/* Check if debuginfod is enabled. If configured to do so, ask the user - whether to enable debuginfod. */ +/* Check if debuginfod is enabled. If configured to do so and ALLOW_ASK, ask + the user whether to enable debuginfod. */ -static bool -debuginfod_is_enabled () +static const char * +debuginfod_is_enabled_1 (bool allow_ask) { const char *urls = skip_spaces (getenv (DEBUGINFOD_URLS_ENV_VAR)); if (urls == nullptr || *urls == '\0') - return false; + return debuginfod_off; - if (debuginfod_enabled != debuginfod_ask) - return debuginfod_enabled == debuginfod_on; + if (debuginfod_enabled != debuginfod_ask || !allow_ask) + return debuginfod_enabled; gdb_printf (_("\nThis GDB supports auto-downloading debuginfo " \ "from the following URLs:\n")); @@ -280,8 +280,18 @@ debuginfod_is_enabled () debuginfod_enabled = debuginfod_on; } - gdb_assert (debuginfod_enabled != debuginfod_ask); - return debuginfod_enabled == debuginfod_on; + return debuginfod_enabled; +} + +/* Check if debuginfod is enabled. If configured to do so, ask the user + whether to enable debuginfod. */ + +static bool +debuginfod_is_enabled () +{ + const char *res = debuginfod_is_enabled_1 (true); + gdb_assert (res != debuginfod_ask); + return res == debuginfod_on; } /* Print the result of the most recent attempted download. */ @@ -484,6 +494,18 @@ debuginfod_section_query (const unsigned char *build_id, #endif +/* See debuginfod-support.h. */ + +bool +debuginfod_enabled_ask_p () +{ +#if defined(HAVE_LIBDEBUGINFOD) + return debuginfod_is_enabled_1 (false) == debuginfod_ask; +#else + return false; +#endif +} + /* Set callback for "set debuginfod enabled". */ static void diff --git a/gdb/debuginfod-support.h b/gdb/debuginfod-support.h index 2b396dc13c1..1db2f511925 100644 --- a/gdb/debuginfod-support.h +++ b/gdb/debuginfod-support.h @@ -105,4 +105,9 @@ extern scoped_fd debuginfod_section_query (const unsigned char *build_id, const char *section_name, gdb::unique_xmalloc_ptr<char> *destname); + +/* Check if debuginfod enabled is set to ask. */ + +extern bool debuginfod_enabled_ask_p (); + #endif /* GDB_DEBUGINFOD_SUPPORT_H */ -- 2.51.0 ++++++ gdb-add-defaulted_query_auto_answers_p.patch ++++++ >From 2698c949162a20c9ad01df9429484e6ff7185f08 Mon Sep 17 00:00:00 2001 From: Tom de Vries <[email protected]> Date: Sat, 14 Mar 2026 12:50:29 +0100 Subject: [PATCH 4/8] [gdb] Add defaulted_query_auto_answers_p Factor out "static bool defaulted_query_auto_answers_p (bool)" out of defaulted_query, and use it to implement "extern tribool defaulted_query_auto_answers_p (void)". --- gdb/utils.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++----- gdb/utils.h | 4 ++++ 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/gdb/utils.c b/gdb/utils.c index 6f2055e299d..f5222ab6023 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -743,6 +743,54 @@ class scoped_input_handler }; +/* Return true if defaulted queries should be answered: + - if VERBOSELY, automatically and verbosely + - otherwise, automatically and quietly. */ + +static bool +defaulted_query_auto_answers_p (bool verbosely) +{ + if (verbosely) + { + /* Automatically answer verbosely if input isn't coming from the user + directly. */ + return (current_ui->instream != current_ui->stdin_stream + || !current_ui->input_interactive_p () + /* Restrict queries to the main UI. */ + || current_ui != main_ui); + } + else + { + /* Automatically answer quietly if: + - the user did not want prompts, or + - the command was issued with the server prefix. */ + return !confirm || server_command; + } +} + +/* See utils.h. */ + +tribool +defaulted_query_auto_answers_p () +{ + if (defaulted_query_auto_answers_p (false) + || defaulted_query_auto_answers_p (true)) + return TRIBOOL_TRUE; + + if (deprecated_query_hook) + { + /* The only user of deprecated_query_hook in core gdb seems to be + mi_interp_query_hook, for which we could return TRIBOOL_TRUE here. + If that turns out to be required, we could accomplish this by + changing the hook interface to say: + int (*deprecated_query_hook) (const char *, va_list, + bool auto_answers_p = false) + and calling it here with auto_answers_p == true. */ + return TRIBOOL_UNKNOWN; + } + + return TRIBOOL_FALSE; +} /* This function supports the query, nquery, and yquery functions. Ask user a y-or-n question and return 0 if answer is no, 1 if @@ -790,17 +838,14 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args) /* Automatically answer the default value if the user did not want prompts or the command was issued with the server prefix. */ - if (!confirm || server_command) + if (defaulted_query_auto_answers_p (false)) return def_value; /* If input isn't coming from the user directly, just say what question we're asking, and then answer the default automatically. This way, important error messages don't get lost when talking to GDB over a pipe. */ - if (current_ui->instream != current_ui->stdin_stream - || !current_ui->input_interactive_p () - /* Restrict queries to the main UI. */ - || current_ui != main_ui) + if (defaulted_query_auto_answers_p (true)) { target_terminal::scoped_restore_terminal_state term_state; target_terminal::ours_for_output (); diff --git a/gdb/utils.h b/gdb/utils.h index b9044e680d4..7e82aba33b3 100644 --- a/gdb/utils.h +++ b/gdb/utils.h @@ -486,4 +486,8 @@ struct deferred_warnings final : public warning_hook_handler_type std::vector<string_file> m_warnings; }; +/* Whether defaulted queries are answered automatically. */ + +extern tribool defaulted_query_auto_answers_p (); + #endif /* GDB_UTILS_H */ -- 2.51.0 ++++++ gdb-enable-ptype-o-for-some-dynamic-types.patch ++++++ >From f714c56f3cd13a9216000951f4319250734fc0ae Mon Sep 17 00:00:00 2001 From: Tom de Vries <[email protected]> Date: Mon, 9 Mar 2026 17:33:47 +0100 Subject: [PATCH 8/8] [gdb] Enable ptype /o for some dynamic types Printing the offsets of a struct containing a flexible array member using "ptype /o" currently fails: ... $ cat test.c struct s { int a; int b[]; }; struct s foo; $ gcc -g test.c -c $ gdb -q -batch test.o -ex "ptype /o struct s" warning: ptype/o does not work with dynamic types; disabling '/o' type = struct s { int a; int b[]; } ... This has been the case since gdb 14, containing commit 0c1aa2a0953 ("Disable ptype/o for dynamic types"). If we revert the commit, we get instead: ... $ gdb -q -batch test.o -ex "ptype /o struct s" /* offset | size */ type = struct s { /* 0 | 4 */ int a; /* 4 | 0 */ int b[]; /* total size (bytes): 4 */ } ... which is similar to what pahole prints: ... struct s { int a; /* 0 4 */ int b[]; /* 4 0 */ /* size: 4, cachelines: 1, members: 2 */ /* last cacheline: 4 bytes */ }; ... The problem is that the commit uses is_dynamic_type: ... if (flags.print_offsets && is_dynamic_type (type)) { warning (_("ptype/o does not work with dynamic types; disabling '/o'")); flags.print_offsets = 0; } ... which is too restrictive. Fix this by using a new function cannot_print_offsets instead. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33966 --- gdb/gdbtypes.c | 39 ++++++++++++-- gdb/gdbtypes.h | 4 ++ gdb/testsuite/gdb.ada/ptype-o.exp | 2 +- gdb/testsuite/gdb.base/ptype-offsets-c.c | 37 +++++++++++++ gdb/testsuite/gdb.base/ptype-offsets-c.exp | 63 ++++++++++++++++++++++ gdb/typeprint.c | 4 +- 6 files changed, 143 insertions(+), 6 deletions(-) create mode 100644 gdb/testsuite/gdb.base/ptype-offsets-c.c create mode 100644 gdb/testsuite/gdb.base/ptype-offsets-c.exp diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 3dc2308f14e..b2660a4d1b3 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -2035,10 +2035,11 @@ array_type_has_dynamic_stride (struct type *type) return prop != nullptr && prop->is_constant (); } -/* Worker for is_dynamic_type. */ +/* Worker for is_dynamic_type/cannot_print_offsets. */ static bool -is_dynamic_type_internal_1 (struct type *type) +is_dynamic_type_internal_1 (struct type *type, + bool cannot_print_offsets_p = false) { type = check_typedef (type); @@ -2112,7 +2113,24 @@ is_dynamic_type_internal_1 (struct type *type) continue; /* If the field has dynamic type, then so does TYPE. */ if (is_dynamic_type_internal_1 (f.type ())) - return true; + { + bool last_struct_field_p + = (type->code () == TYPE_CODE_STRUCT + && i == type->num_fields () - 1); + if (cannot_print_offsets_p && last_struct_field_p) + { + if (f.type ()->code () == TYPE_CODE_STRUCT) + /* The last field is a dynamic type and a struct. Check + if we can print the offsets for the struct. */ + return is_dynamic_type_internal_1 (f.type (), true); + + /* The last field is a dynamic type, this is ok to print + offsets for. */ + return false; + } + + return true; + } /* If the field is at a fixed offset, then it is not dynamic. */ if (f.loc_kind () != FIELD_LOC_KIND_DWARF_BLOCK) @@ -2155,6 +2173,21 @@ is_dynamic_type (struct type *type) return is_dynamic_type_internal (type, true); } +/* See gdbtypes.h. */ + +bool +cannot_print_offsets (struct type *type) +{ + type = check_typedef (type); + + /* We only want to recognize references and pointers at the outermost + level. */ + if (type->is_pointer_or_reference ()) + type = check_typedef (type->target_type ()); + + return is_dynamic_type_internal_1 (type, true); +} + static struct type *resolve_dynamic_type_internal (struct type *type, struct property_addr_info *addr_stack, const frame_info_ptr &frame, bool top_level); diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index 8b00fec59a1..9a745ca3e02 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -2629,6 +2629,10 @@ extern struct type *resolve_dynamic_type "dynamic". */ extern bool is_dynamic_type (struct type *type); +/* Return true if TYPE cannot be printed using ptype /o. */ + +extern bool cannot_print_offsets (struct type *type); + extern struct type *check_typedef (struct type *); extern void check_stub_method_group (struct type *, int); diff --git a/gdb/testsuite/gdb.ada/ptype-o.exp b/gdb/testsuite/gdb.ada/ptype-o.exp index 5038ee171d2..7f3ec3ce7a3 100644 --- a/gdb/testsuite/gdb.ada/ptype-o.exp +++ b/gdb/testsuite/gdb.ada/ptype-o.exp @@ -37,7 +37,7 @@ foreach_gnat_encoding scenario flags {all minimal} { "Warning: the current language does not match this frame." if {$scenario == "minimal"} { - set exp "ptype/o does not work with dynamic types.*" + set exp "ptype/o does not work with this dynamic type.*" } else { # In "all" mode this prints nonsense, but at least does not # crash. diff --git a/gdb/testsuite/gdb.base/ptype-offsets-c.c b/gdb/testsuite/gdb.base/ptype-offsets-c.c new file mode 100644 index 00000000000..74ac9ed7b37 --- /dev/null +++ b/gdb/testsuite/gdb.base/ptype-offsets-c.c @@ -0,0 +1,37 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2026 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +struct flexible_array_member +{ + int an_int; + int fam[]; +}; + +struct nested_flexible_array_member +{ + int another_int; + struct flexible_array_member sfam; +}; + +int +main (void) +{ + struct flexible_array_member fam; + struct nested_flexible_array_member nfam; + + return 0; +} diff --git a/gdb/testsuite/gdb.base/ptype-offsets-c.exp b/gdb/testsuite/gdb.base/ptype-offsets-c.exp new file mode 100644 index 00000000000..cffcbbeb2f7 --- /dev/null +++ b/gdb/testsuite/gdb.base/ptype-offsets-c.exp @@ -0,0 +1,63 @@ +# This testcase is part of GDB, the GNU debugger. + +# Copyright 2026 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# This testcase exercises the "ptype /o" feature, which can be used to +# print the offsets and sizes of each field of a struct/union. +# +# This is similar to ptype-offsets.exp, which uses C++ instead of C. + +standard_testfile .c + +# Test only works on LP64 targets. That's how we guarantee that the +# expected holes will be present in the struct. +if { ![is_lp64_target] } { + untested "test work only on lp64 targets" + return 0 +} + +if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { + return -1 +} + +# Tests handling flexible array member. Regression tests for PR gdb/33966. +set l { + "ptype /o struct flexible_array_member" + "/* offset | size */ type = struct flexible_array_member {" + "/* 0 | 4 */ int an_int;" + "/* 4 | 0 */ int fam[];" + "" + " /* total size (bytes): 4 */" + " }" +} +gdb_test "ptype /o struct flexible_array_member" \ + [string_to_regexp [multi_line {*}$l]] + +set l { + "/* offset | size */ type = struct nested_flexible_array_member {" + "/* 0 | 4 */ int another_int;" + "/* 4 | 4 */ struct flexible_array_member {" + "/* 4 | 4 */ int an_int;" + "/* 8 | 0 */ int fam[];" + "" + " /* total size (bytes): 4 */" + " } sfam;" + "" + " /* total size (bytes): 8 */" + " }" +} +gdb_test "ptype /o struct nested_flexible_array_member" \ + [string_to_regexp [multi_line {*}$l]] diff --git a/gdb/typeprint.c b/gdb/typeprint.c index 6494103ba93..e7019a378f3 100644 --- a/gdb/typeprint.c +++ b/gdb/typeprint.c @@ -452,9 +452,9 @@ whatis_exp (const char *exp, int show) type = val->type (); } - if (flags.print_offsets && is_dynamic_type (type)) + if (flags.print_offsets && cannot_print_offsets (type)) { - warning (_("ptype/o does not work with dynamic types; disabling '/o'")); + warning (_("ptype/o does not work with this dynamic type; disabling '/o'")); flags.print_offsets = 0; } -- 2.51.0 ++++++ gdb-factor-out-is_dynamic_type_internal_1.patch ++++++ >From 265d197094ba9a17d1da62ac5ce6d935b551606c Mon Sep 17 00:00:00 2001 From: Tom de Vries <[email protected]> Date: Wed, 11 Mar 2026 09:33:23 +0100 Subject: [PATCH 7/8] [gdb] Factor out is_dynamic_type_internal_1 Simplify is_dynamic_type_internal by factoring out is_dynamic_type_internal_1, leaving only the handling of the top_level parameter in is_dynamic_type_internal. --- gdb/gdbtypes.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index e2e4b5f86bf..3dc2308f14e 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -2038,15 +2038,10 @@ array_type_has_dynamic_stride (struct type *type) /* Worker for is_dynamic_type. */ static bool -is_dynamic_type_internal (struct type *type, bool top_level) +is_dynamic_type_internal_1 (struct type *type) { type = check_typedef (type); - /* We only want to recognize references and pointers at the outermost - level. */ - if (top_level && type->is_pointer_or_reference ()) - type = check_typedef (type->target_type ()); - /* Types that have a dynamic TYPE_DATA_LOCATION are considered dynamic, even if the type itself is statically defined. From a user's point of view, this may appear counter-intuitive; @@ -2081,7 +2076,7 @@ is_dynamic_type_internal (struct type *type, bool top_level) of the range type are static. It allows us to assume that the subtype of a static range type is also static. */ return (!has_static_range (type->bounds ()) - || is_dynamic_type_internal (type->target_type (), false)); + || is_dynamic_type_internal_1 (type->target_type ())); } case TYPE_CODE_STRING: @@ -2092,10 +2087,10 @@ is_dynamic_type_internal (struct type *type, bool top_level) gdb_assert (type->num_fields () == 1); /* The array is dynamic if either the bounds are dynamic... */ - if (is_dynamic_type_internal (type->index_type (), false)) + if (is_dynamic_type_internal_1 (type->index_type ())) return true; /* ... or the elements it contains have a dynamic contents... */ - if (is_dynamic_type_internal (type->target_type (), false)) + if (is_dynamic_type_internal_1 (type->target_type ())) return true; /* ... or if it has a dynamic stride... */ if (array_type_has_dynamic_stride (type)) @@ -2116,7 +2111,7 @@ is_dynamic_type_internal (struct type *type, bool top_level) if (f.is_static ()) continue; /* If the field has dynamic type, then so does TYPE. */ - if (is_dynamic_type_internal (f.type (), false)) + if (is_dynamic_type_internal_1 (f.type ())) return true; /* If the field is at a fixed offset, then it is not dynamic. */ @@ -2136,6 +2131,22 @@ is_dynamic_type_internal (struct type *type, bool top_level) return false; } +/* Worker for is_dynamic_type. If TOP_LEVEL and TYPE is a pointer or a + reference to a dynamic type, it is also considered a dynamic type. */ + +static bool +is_dynamic_type_internal (struct type *type, bool top_level) +{ + type = check_typedef (type); + + /* We only want to recognize references and pointers at the outermost + level. */ + if (top_level && type->is_pointer_or_reference ()) + type = check_typedef (type->target_type ()); + + return is_dynamic_type_internal_1 (type); +} + /* See gdbtypes.h. */ bool -- 2.51.0 ++++++ gdb-minor-refactoring-of-is_dynamic_type_internal.patch ++++++ >From 1768d8ae64457f0c209a598d215617ebd3329843 Mon Sep 17 00:00:00 2001 From: Tom de Vries <[email protected]> Date: Tue, 10 Mar 2026 21:44:01 +0100 Subject: [PATCH 6/8] [gdb] Minor refactoring of is_dynamic_type_internal Simplify is_dynamic_type_internal by: - factoring out type->field (i) for the TYPE_CODE_STRUCT/UNION case. - merging a loop iteration variable declaration into a for statement Approved-By: Tom Tromey <[email protected]> --- gdb/gdbtypes.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 0928e244467..e2e4b5f86bf 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -2106,21 +2106,21 @@ is_dynamic_type_internal (struct type *type, bool top_level) case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: { - int i; - bool is_cplus = HAVE_CPLUS_STRUCT (type); - for (i = 0; i < type->num_fields (); ++i) + for (int i = 0; i < type->num_fields (); ++i) { + struct field &f = type->field (i); + /* Static fields can be ignored here. */ - if (type->field (i).is_static ()) + if (f.is_static ()) continue; /* If the field has dynamic type, then so does TYPE. */ - if (is_dynamic_type_internal (type->field (i).type (), false)) + if (is_dynamic_type_internal (f.type (), false)) return true; /* If the field is at a fixed offset, then it is not dynamic. */ - if (type->field (i).loc_kind () != FIELD_LOC_KIND_DWARF_BLOCK) + if (f.loc_kind () != FIELD_LOC_KIND_DWARF_BLOCK) continue; /* Do not consider C++ virtual base types to be dynamic due to the field's offset being dynamic; these are -- 2.51.0 ++++++ gdb-simplify-debuginfod_is_enabled.patch ++++++ >From 654c61f7878b63deae626da6e55cfbbd854ee4e3 Mon Sep 17 00:00:00 2001 From: Tom de Vries <[email protected]> Date: Sat, 14 Mar 2026 13:43:37 +0100 Subject: [PATCH 2/8] [gdb] Simplify debuginfod_is_enabled Simplify debuginfod_is_enabled by adding an early-exit for the debuginfod_enabled == debuginfod_on case. --- gdb/debuginfod-support.c | 81 ++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/gdb/debuginfod-support.c b/gdb/debuginfod-support.c index 2ae722858a2..f97c1f921ab 100644 --- a/gdb/debuginfod-support.c +++ b/gdb/debuginfod-support.c @@ -230,57 +230,58 @@ debuginfod_is_enabled () { const char *urls = skip_spaces (getenv (DEBUGINFOD_URLS_ENV_VAR)); - if (debuginfod_enabled == debuginfod_off - || urls == nullptr + if (urls == nullptr || *urls == '\0') return false; - if (debuginfod_enabled == debuginfod_ask) - { - gdb_printf (_("\nThis GDB supports auto-downloading debuginfo " \ - "from the following URLs:\n")); + if (debuginfod_enabled != debuginfod_ask) + return debuginfod_enabled == debuginfod_on; - std::string_view url_view (urls); - while (true) - { - size_t off = url_view.find_first_not_of (' '); - if (off == std::string_view::npos) - break; - url_view = url_view.substr (off); - /* g++ 11.2.1 on s390x, g++ 11.3.1 on ppc64le and g++ 11 on - hppa seem convinced url_view might be of SIZE_MAX length. - And so complains because the length of an array can only - be PTRDIFF_MAX. */ - DIAGNOSTIC_PUSH - DIAGNOSTIC_IGNORE_STRINGOP_OVERREAD - off = url_view.find_first_of (' '); - DIAGNOSTIC_POP - gdb_printf - (_(" <%ps>\n"), - styled_string (file_name_style.style (), - std::string (url_view.substr (0, off)).c_str ())); - if (off == std::string_view::npos) - break; - url_view = url_view.substr (off); - } + gdb_printf (_("\nThis GDB supports auto-downloading debuginfo " \ + "from the following URLs:\n")); - int resp = nquery (_("Enable debuginfod for this session? ")); - if (!resp) - { - gdb_printf (_("Debuginfod has been disabled.\nTo make this " \ - "setting permanent, add \'set debuginfod " \ - "enabled off\' to .gdbinit.\n")); - debuginfod_enabled = debuginfod_off; - return false; - } + std::string_view url_view (urls); + while (true) + { + size_t off = url_view.find_first_not_of (' '); + if (off == std::string_view::npos) + break; + url_view = url_view.substr (off); + /* g++ 11.2.1 on s390x, g++ 11.3.1 on ppc64le and g++ 11 on + hppa seem convinced url_view might be of SIZE_MAX length. + And so complains because the length of an array can only + be PTRDIFF_MAX. */ + DIAGNOSTIC_PUSH + DIAGNOSTIC_IGNORE_STRINGOP_OVERREAD + off = url_view.find_first_of (' '); + DIAGNOSTIC_POP + gdb_printf + (_(" <%ps>\n"), + styled_string (file_name_style.style (), + std::string (url_view.substr (0, off)).c_str ())); + if (off == std::string_view::npos) + break; + url_view = url_view.substr (off); + } - gdb_printf (_("Debuginfod has been enabled.\nTo make this " \ + int resp = nquery (_("Enable debuginfod for this session? ")); + if (!resp) + { + gdb_printf (_("Debuginfod has been disabled.\nTo make this " \ + "setting permanent, add \'set debuginfod " \ + "enabled off\' to .gdbinit.\n")); + debuginfod_enabled = debuginfod_off; + } + else + { + gdb_printf (_("Debuginfod has been enabled.\nTo make this " \ "setting permanent, add \'set debuginfod enabled " \ "on\' to .gdbinit.\n")); debuginfod_enabled = debuginfod_on; } - return true; + gdb_assert (debuginfod_enabled != debuginfod_ask); + return debuginfod_enabled == debuginfod_on; } /* Print the result of the most recent attempted download. */ -- 2.51.0 ++++++ gdb-tdep-fix-unrelocated-pc-in-i386_displaced_step_f.patch ++++++ >From 62f9da4e6fb357b710c763162e14a6db0ffed2e3 Mon Sep 17 00:00:00 2001 From: Tom de Vries <[email protected]> Date: Mon, 16 Mar 2026 16:30:38 +0100 Subject: [PATCH 1/8] [gdb/tdep] Fix unrelocated pc in i386_displaced_step_fixup With test-case gdb.threads/next-fork-other-thread.exp and target board unix/-m32 I run into: ... (gdb) next^M [Switching to Thread 0xf643ab40 (LWP 3267939)]^M ^M Thread 5 "next-fork-other" hit Breakpoint 1, main () at \ next-fork-other-thread.c:73^M 73 alarm (60);^M (gdb) FAIL: $exp: fork_func=fork: target-non-stop=off: non-stop=off: \ displaced-stepping=on: i=$n: next to break here ... Before we go into how this happens, let's first look at the inferior. In main, 4 threads are started with the same thread function, leaving all 5 threads in a loop: - the main thread is stuck in a loop calling sleep, and gdb steps through this loop using next - the other, non-main threads are stuck in a loop where each thread: - forks off a child process that exits immediately - waits for the child process to exit - calls sleep The FAIL happens as follows (following snippets from this gdb.log [1]). One of the non-main threads enters __syscall_cancel_arch to do a sycall ( either to sleep, or to wait). Then the non-main thread stops: ... [infrun] handle_signal_stop: [2937316.2937324.0] hit another thread's \ single-step breakpoint^M [infrun] handle_signal_stop: delayed software breakpoint trap, ignoring^M [infrun] switch_back_to_stepped_thread: need to step [2937316.2937324.0] \ over single-step breakpoint^M ... because we "hit another thread's single-step breakpoint". AFAIU, this is because of the main thread stepping through __syscall_cancel_arch. To handle this, we're going to try displaced stepping. The syscall instruction is copied: ... [displaced] displaced_step_prepare_throw: original insn 0xf7cdce69: \ cd 80 int $0x80^M [displaced] prepare: selected buffer at 0x80490d2^M ... to a buffer at _start+2: ... 080490d0 <_start>: 80490d0: 31 ed xor %ebp,%ebp 80490d2: 5e pop %esi ... and we're going to resume execution there. However, right after resuming we get a GDB_SIGNAL_CHLD for the same thread. Part of handling that is finalizing the displaced stepping: ... [displaced] finish: restored 2937316.2937324.0 0x80490d2^M [displaced] i386_displaced_step_fixup: fixup (0xf7cdce69, 0x80490d2), \ insn = 0xcd 0x80 ...^M [displaced] i386_displaced_step_fixup: syscall changed %eip; not relocating^M [infrun] handle_signal_stop: stop_pc=0x80490d2^M ... The stop pc is 0x80490d2, the address of the copied instruction. In other words, we've stopped without making progress. The problem is that the address is in the displaced stepping buffer, and needs relocating, but instead we have "syscall changed %eip; not relocating". The code in i386_displaced_step_fixup doesn't recognize this situation: ... if (i386_syscall_p (insn, &insn_len) && pc != to + (insn - insn_start) + insn_len /* GDB can get control back after the insn after the syscall. Presumably this is a kernel bug. i386_displaced_step_copy_insn ensures it's a nop, we add one to the length for it. */ && pc != to + (insn - insn_start) + insn_len + 1) displaced_debug_printf ("syscall changed %%eip; not relocating"); ... It only handles the cases where the stop pc is: - the address after the syscall insn, or - the address after the nop after the syscall insn So, instead of relocating the stop pc back to the original 0xf7cdce69, it stays 0x80490d2. After resuming at that address, the thread: - executes the syscall, - executes the rest of _start, - enters main, and - runs into the breakpoint at the start of main. Since commit cf141dd8ccd ("gdb: fix reg corruption from displaced stepping on amd64"), we do handle the "pc == to" case in amd64_displaced_step_fixup: ... if (amd64_syscall_p (insn_details, &insn_len) /* GDB can get control back after the insn after the syscall. Presumably this is a kernel bug. Fixup ensures its a nop, we add one to the length for it. */ && (pc < to || pc > (to + insn_len + 1))) displaced_debug_printf ("syscall changed %%rip; not relocating"); ... Fix this in the same way. Tested on x86_64-linux, with target board unix/-m32. On openSUSE Tumbleweed (kernel version 6.19.7), this patch fixes the test-case. On openSUSE Leap 16.0 (kernel version 6.12.0), we still run into PR29040. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33997 [1] https://sourceware.org/bugzilla/attachment.cgi?id=16660 --- gdb/i386-tdep.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index a552a2bee8f..9c9c6864e58 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -854,12 +854,11 @@ i386_displaced_step_fixup (struct gdbarch *gdbarch, it unrelocated. Goodness help us if there are PC-relative system calls. */ if (i386_syscall_p (insn, &insn_len) - && pc != to + (insn - insn_start) + insn_len /* GDB can get control back after the insn after the syscall. Presumably this is a kernel bug. i386_displaced_step_copy_insn ensures it's a nop, we add one to the length for it. */ - && pc != to + (insn - insn_start) + insn_len + 1) + && (pc < to || pc > to + (insn - insn_start) + insn_len + 1)) displaced_debug_printf ("syscall changed %%eip; not relocating"); else { base-commit: ccc03544a6bc2f886e06d8b477a84eb8b2033e31 -- 2.51.0 ++++++ gdb-testsuite-fix-printf-regexp-for-ppc64le-with-gli.patch ++++++ >From e536b8c1ae2e0212e86dd741a4fa31b4d09f9dd0 Mon Sep 17 00:00:00 2001 From: Abhay Kandpal <[email protected]> Date: Tue, 3 Mar 2026 10:25:09 -0500 Subject: [PATCH 1/2] gdb/testsuite: fix printf regexp for ppc64le with glibc ieee128 fix On ppc64le, when the compiler selects IEEE-128 long double ABI (-mabi=ieeelongdouble), calls to printf are redirected to ___ieee128_printf. This causes 'break printf' in GDB to never stop at printf: ... (gdb) break printf Breakpoint 3 at 0x7ffff7a6b880 (gdb) continue Continuing. value is 7 [Inferior 1 (process 403664) exited normally] (gdb) FAIL: gdb.base/annota1.exp: continue to printf ... glibc fixed this by adding local symbol aliases in the ieee128 compatibility files so that the original symbol names are present in the symbol table again (glibc commit f05ab7c4a99b). After the glibc fix, GDB stops at printf but the breakpoint is reported as 'Breakpoint 3.2, ___ieee128_printf' since printf now resolves to two locations. The current GDB test regexps do not match this output. ... (gdb) break printf Breakpoint 3 at 0x7ffff7a6b278: printf. (2 locations) (gdb) continue Continuing. Breakpoint 3.2, ___ieee128_printf (format=0x10000970 \"value is %d\n\") at ../sysdeps/ieee754/ldbl-128ibm-compat/ieee128-printf.c:28 (gdb) FAIL: gdb.base/annota1.exp: continue to printf ... This causes failures in gdb.base/annota1.exp and gdb.base/annota3.exp because the pattern 'Breakpoint 3, ' does not match 'Breakpoint 3.2, '. Fix this by changing 'Breakpoint 3, ' to 'Breakpoint 3.*, '. In gdb.server/sysroot.exp the pattern '(__)?printf' does not match '___ieee128_printf'. Fix this by changing '(__)?printf' to '.*printf' to match any printf variant including printf, __printf, and ___ieee128_printf, following the same approach as previous fixes for __printf on x86_64 (commit f870f78fb2d) and printf@@GLIBC_2.17 on ppc64le (commit 29004660c94). Tested on ppc64le, x86_64-linux. Approved-By: Tom de Vries <[email protected]> --- gdb/testsuite/gdb.base/annota1.exp | 2 +- gdb/testsuite/gdb.base/annota3.exp | 6 +++--- gdb/testsuite/gdb.server/sysroot.exp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gdb/testsuite/gdb.base/annota1.exp b/gdb/testsuite/gdb.base/annota1.exp index 927e8a7e579..ac8e29333ac 100644 --- a/gdb/testsuite/gdb.base/annota1.exp +++ b/gdb/testsuite/gdb.base/annota1.exp @@ -260,7 +260,7 @@ gdb_test_multiple "break printf" "break printf" { # set pat_begin "\r\n\032\032post-prompt\r\nContinuing.\r\n\r\n\032\032starting\r\n\r\n\032\032frames-invalid\r\n${breakpoints_invalid}\r\n\032\032frames-invalid\r\n" set pat_adjust "warning: Breakpoint 3 address previously adjusted from $hex to $hex.\r\n" -set pat_end "\r\n\032\032breakpoint 3\r\n\r\nBreakpoint 3, \r\n\032\032frame-begin 0 $hex\r\n\r\n(\032\032frame-address\r\n$hex\r\n\032\032frame-address-end\r\n in \r\n)*.*\032\032frame-function-name\r\n.*printf(@.*)?\r\n\032\032frame-args\r\n.*\032\032frame-end\r\n\r\n\032\032stopped\r\n$gdb_prompt$" +set pat_end "\r\n\032\032breakpoint 3\r\n\r\nBreakpoint 3(\\.$decimal)?, \r\n\032\032frame-begin 0 $hex\r\n\r\n(\032\032frame-address\r\n$hex\r\n\032\032frame-address-end\r\n in \r\n)*.*\032\032frame-function-name\r\n.*printf(@.*)?\r\n\032\032frame-args\r\n.*\032\032frame-end\r\n\r\n\032\032stopped\r\n$gdb_prompt$" gdb_test_multiple "continue" "continue to printf" { -re "${pat_begin}($pat_adjust)?$pat_end" { diff --git a/gdb/testsuite/gdb.base/annota3.exp b/gdb/testsuite/gdb.base/annota3.exp index 134a3d37c80..d5bbed735ce 100644 --- a/gdb/testsuite/gdb.base/annota3.exp +++ b/gdb/testsuite/gdb.base/annota3.exp @@ -164,15 +164,15 @@ gdb_test -prompt "$gdb_prompt$" "break printf" \ # get to printf # send_gdb "continue\n" -gdb_expect_list "continue to printf" "$gdb_prompt$" { +gdb_expect_list "continue to printf" "$gdb_prompt$" [subst_vars { "\r\n\032\032post-prompt\r\n" "Continuing.\r\n" "\r\n\032\032starting\r\n" "\r\n\032\032breakpoint 3\r\n" "\r\n" - "Breakpoint 3, \[^\r\n\]*\r\n" + "Breakpoint 3(\\.$decimal)?, \[^\r\n\]*\r\n" "\r\n\032\032stopped\r\n" -} +}] send_gdb "backtrace\n" gdb_expect_list "backtrace from shlibrary" "$gdb_prompt$" { diff --git a/gdb/testsuite/gdb.server/sysroot.exp b/gdb/testsuite/gdb.server/sysroot.exp index 7f5597d7306..e4e14b349bf 100644 --- a/gdb/testsuite/gdb.server/sysroot.exp +++ b/gdb/testsuite/gdb.server/sysroot.exp @@ -88,7 +88,7 @@ foreach_with_prefix sysroot $modes { # Test that we can stop inside a library. gdb_breakpoint printf - gdb_test "continue" "Breakpoint $decimal.* (__)?printf.*" \ + gdb_test "continue" "Breakpoint $decimal.* (__|___ieee128_)?printf.*" \ "continue to printf" } } base-commit: fbb1f8cff499031b1c9a7fbc189039e669fb1cf0 -- 2.51.0 ++++++ gdb-tui-don-t-enter-tui-if-debuginfod-enabled-ask.patch ++++++ >From 83a5d9064208d705b490bed89f37ade4da3c4a29 Mon Sep 17 00:00:00 2001 From: Tom de Vries <[email protected]> Date: Sat, 14 Mar 2026 15:29:05 +0100 Subject: [PATCH 5/8] [gdb/tui] Don't enter TUI if debuginfod enabled == ask PR tui/31449 reports a SIGFPE when the debuginfod query happens while enabling TUI using the "tui enable" command: ... Thread 1 "gdb" received signal SIGFPE, Arithmetic exception. 0x0000000001021084 in tui_inject_newline_into_command_window () at /data/vries/gdb/src/gdb/tui/tui-io.c:1096 1096 py += px / tui_cmd_win ()->width; ... due to divide-by-zero because tui_cmd_win ()->width == 0. The corresponding backtrace is: ... (gdb) bt #0 0x0000000001021084 in tui_inject_newline_into_command_window () at gdb/tui/tui-io.c:1096 #1 0x0000000000fe65fd in gdb_readline_wrapper_line (line=...) at gdb/top.c:939 #2 0x0000000000944eef in gdb_rl_callback_handler (rl=0x2cc865a0 "n") at gdb/event-top.c:288 #3 0x0000000001175779 in rl_callback_read_char () at readline/readline/callback.c:302 #4 0x0000000000944bc3 in gdb_rl_callback_read_char_wrapper_sjlj () at gdb/event-top.c:197 #5 0x0000000000944cd4 in gdb_rl_callback_read_char_wrapper_noexcept () at gdb/event-top.c:240 #6 0x0000000000944d52 in gdb_rl_callback_read_char_wrapper (...) at gdb/event-top.c:252 #7 0x0000000001062352 in stdin_event_handler (error=0, client_data=0x2c865150) at gdb/ui.c:154 #8 0x0000000001a04edf in handle_file_event (file_ptr=0x2ccf8850, ready_mask=1) at gdbsupport/event-loop.cc:551 #9 0x0000000001a05522 in gdb_wait_for_event (block=1) at gdbsupport/event-loop.cc:672 #10 0x0000000001a043ff in gdb_do_one_event (mstimeout=-1) at gdbsupport/event-loop.cc:263 #11 0x00000000006d5480 in interp::do_one_event (this=0x2cc2af20, mstimeout=-1) at gdb/interps.h:93 #12 0x0000000000fe670d in gdb_readline_wrapper ( prompt=0x2ccca4e0 "Enable debuginfod for this session? (y or [n]) ") at gdb/top.c:1033 #13 0x00000000010c6853 in defaulted_query(...) (...) at gdb/utils.c:844 #14 0x00000000010c6b8a in nquery (...) at gdb/utils.c:901 #15 0x00000000007a9324 in debuginfod_is_enabled () at gdb/debuginfod-support.c:268 #16 0x00000000007a950d in debuginfod_source_query (...) at gdb/debuginfod-support.c:311 #17 0x0000000000efc2c7 in open_source_file (s=0x2cc8f4b0) at gdb/source.c:1152 #18 0x0000000000efc619 in symtab_to_fullname (...) at gdb/source.c:1214 #19 0x0000000000f5ebb3 in find_line_symtab (...) at gdb/symtab.c:3287 #20 0x0000000000f5f0e5 in find_pc_for_line (...) at gdb/symtab.c:3391 #21 0x0000000001011f54 in tui_get_begin_asm_address (...) at gdb/tui/tui-disasm.c:404 #22 0x000000000104888d in tui_source_window_base::rerender (this=0x2cbdc570) at gdb/tui/tui-winsource.c:474 #23 0x0000000001028e81 in tui_win_info::resize (this=0x2cbdc570, height_=21, width_=127, origin_x_=0, origin_y_=0) at gdb/tui/tui-layout.c:299 #24 0x00000000010297d0 in tui_layout_window::apply (this=0x2cc50350, x_=0, y_=0, width_=127, height_=21, preserve_cmd_win_size_p=false) at gdb/tui/tui-layout.c:432 #25 0x000000000102bfea in tui_layout_split::apply (this=0x2caea920, x_=0, y_=0, width_=127, height_=33, preserve_cmd_win_size_p=false) at gdb/tui/tui-layout.c:1026 #26 0x0000000001028267 in tui_apply_current_layout (...) at gdb/tui/tui-layout.c:68 #27 0x0000000001028737 in tui_set_layout (layout=0x2c9b9e90) at gdb/tui/tui-layout.c:133 #28 0x0000000001028af5 in tui_set_initial_layout () at gdb/tui/tui-layout.c:209 #29 0x000000000104b795 in tui_enable () at gdb/tui/tui.c:496 #30 0x000000000104bab3 in tui_enable_command (args=0x0, from_tty=1) at gdb/tui/tui.c:591 #31 0x00000000006c5ffe in do_simple_func (args=0x0, from_tty=1, c=0x2c9bb2f0) at gdb/cli/cli-decode.c:94 #32 0x00000000006cc94f in cmd_func (cmd=0x2c9bb2f0, args=0x0, from_tty=1) at gdb/cli/cli-decode.c:2831 #33 0x0000000000fe53ad in execute_command (p=0x2c86699a "", from_tty=1) at gdb/top.c:563 #34 0x000000000094584d in command_handler (command=0x2c866990 "tui enable") at gdb/event-top.c:611 #35 0x0000000000945dfe in command_line_handler (rl=...) at gdb/event-top.c:844 #36 0x000000000101e916 in tui_command_line_handler (rl=...) at gdb/tui/tui-interp.c:101 #37 0x0000000000944eef in gdb_rl_callback_handler (rl=0x2cc86a30 "tui enable") at gdb/event-top.c:288 #38 0x0000000001175779 in rl_callback_read_char () at readline/readline/callback.c:302 #39 0x0000000000944bc3 in gdb_rl_callback_read_char_wrapper_sjlj () at gdb/event-top.c:197 #40 0x0000000000944cd4 in gdb_rl_callback_read_char_wrapper_noexcept () at gdb/event-top.c:240 #41 0x0000000000944d52 in gdb_rl_callback_read_char_wrapper (...) at gdb/event-top.c:252 #42 0x0000000001062352 in stdin_event_handler (error=0, client_data=0x2c865150) at gdb/ui.c:154 #43 0x0000000001a04edf in handle_file_event (file_ptr=0x2ccf8850, ready_mask=1) at gdbsupport/event-loop.cc:551 #44 0x0000000001a05522 in gdb_wait_for_event (block=1) at gdbsupport/event-loop.cc:672 #45 0x0000000001a043ff in gdb_do_one_event (mstimeout=-1) at gdbsupport/event-loop.cc:263 #46 0x00000000006d5480 in interp::do_one_event (this=0x2cc2af20, mstimeout=-1) at gdb/interps.h:93 #47 0x0000000000b77f25 in start_event_loop () at gdb/main.c:403 #48 0x0000000000b78113 in captured_command_loop () at gdb/main.c:468 #49 0x0000000000b7a07c in captured_main (context=0x7fff660b9e60) at gdb/main.c:1381 #50 0x0000000000b7a178 in gdb_main (args=0x7fff660b9e60) at gdb/main.c:1400 #51 0x0000000000419705 in main (argc=5, argv=0x7fff660b9f98) at gdb/gdb.c:38 (gdb) ... The problem is that the command window is used (during initialization of the source window) before it's properly initialized. A patch [1] was posted for this PR, which fixes the problem by calling a function that will force the debuginfod query to happen before enabling the TUI: ... static void tui_enable_command (const char *args, int from_tty) { + /* Trigger any debuginfod-related y/n prompts now to avoid having + it occur during tui initialization. Handling the prompt while + tui windows are initializing can cause crashes. */ + debuginfod_is_enabled (); + tui_enable (); } ... A review comment reported a problem when using C-x C-a to enable TUI instead of "tui enable", not fixed by the previous patch. This was filed as PR33794. Another patch [2] took the following approach: add a layout with only the command window, and activate that layout first, making sure that we finalize the initialization of the command window before we activate the initial layout. However, that approach made the debuginfod query happen in an empty screen in between the CLI and TUI interfaces, which is confusing. So yet another patch [3] took the following approach: - adding a facility defer_tui_rerender that allows deferral of calling the rerender methods (which draws everything but the window borders), and - using that facility to postpone rerendering in tui_enable until after io has been initialized. Then yet another patch [4] tried a minimal fix: add a check at the start of tui_inject_newline_into_command_window that avoids the SIGFPE. This patch handles the problem by simply bailing out if debuginfod enabled is set to ask when entering TUI, which is very similar to [1]. Unlike all other approaches, it does fix PR33794 as well. The v4 version of this patch [5] unnecessarily bailed out for: ... $ gdb -q outputs/gdb.tui/query/query -ex "set confirm off" -ex "tui enable" ... This v5 version fixes that using defaulted_query_auto_answers_p. Tested on x86_64-linux. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31449 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33794 [1] https://sourceware.org/pipermail/gdb-patches/2024-March/207224.html [2] v1 https://sourceware.org/pipermail/gdb-patches/2026-January/224038.html [3] v2 https://sourceware.org/pipermail/gdb-patches/2026-January/224103.html [4] v3 https://sourceware.org/pipermail/gdb-patches/2026-February/225210.html [5] v4 https://sourceware.org/pipermail/gdb-patches/2026-February/225351.html --- gdb/testsuite/gdb.tui/query-foo.c | 24 ++++++++ gdb/testsuite/gdb.tui/query.exp | 92 +++++++++++++++++++++++++++++++ gdb/tui/tui.c | 5 ++ 3 files changed, 121 insertions(+) create mode 100644 gdb/testsuite/gdb.tui/query-foo.c create mode 100644 gdb/testsuite/gdb.tui/query.exp diff --git a/gdb/testsuite/gdb.tui/query-foo.c b/gdb/testsuite/gdb.tui/query-foo.c new file mode 100644 index 00000000000..bf4a8766dcd --- /dev/null +++ b/gdb/testsuite/gdb.tui/query-foo.c @@ -0,0 +1,24 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2026 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +extern int foo (void); + +int +foo (void) +{ + return 0; +} diff --git a/gdb/testsuite/gdb.tui/query.exp b/gdb/testsuite/gdb.tui/query.exp new file mode 100644 index 00000000000..bc1a55a1b96 --- /dev/null +++ b/gdb/testsuite/gdb.tui/query.exp @@ -0,0 +1,92 @@ +# Copyright 2026 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Check that a debuginfod query during TUI initialization doesn't cause a +# crash. + +require allow_tui_tests + +load_lib debuginfod-support.exp +require allow_debuginfod_tests + +tuiterm_env + +standard_testfile -main.c -foo.c + +set tmpfile [standard_output_file $srcfile] +set srcfiles [list $tmpfile $srcfile2] + +set fd [open $tmpfile w] +puts $fd { + extern int foo (void); + int + main (void) + { + return foo (); + } +} +close $fd + +if { [build_executable "failed to prepare" $testfile $srcfiles] == -1 } { + return +} + +# Delete query-main.c to trigger the debuginfod query during TUI +# initialization. +file delete $tmpfile + +set l {} +lappend l "command" +lappend l "keys" + +foreach_with_prefix how $l { + save_vars { env(DEBUGINFOD_URLS) } { + setenv DEBUGINFOD_URLS "foo" + Term::clean_restart 24 80 $testfile + } + + if {![Term::prepare_for_tui]} { + return 0 + } + + Term::gen_prompt + + if { $how == "command" } { + send_gdb "tui enable\n" + } else { + send_gdb "\030\001" + } + set re \ + "Please set debuginfod enabled to on or off before enabling TUI" + gdb_assert { [Term::wait_for_region_contents 0 0 80 24 $re] } + + # Check that prompt is responsive. + gdb_assert { [Term::command "print 1"] } "responsive prompt" + + set cmd "set debuginfod enabled off" + gdb_assert { [Term::command "$cmd"] } $cmd + + with_test_prefix tui { + if { $how == "command" } { + send_gdb "tui enable\n" + } else { + send_gdb "\030\001" + } + gdb_assert { [Term::wait_for ""] } "entered" + + # Check that prompt is responsive. + gdb_assert { [Term::command "print 1"] } "responsive prompt" + } +} diff --git a/gdb/tui/tui.c b/gdb/tui/tui.c index 06a899e2418..5dabb9967ae 100644 --- a/gdb/tui/tui.c +++ b/gdb/tui/tui.c @@ -41,6 +41,7 @@ #include "top.h" #include "ui.h" #include "observable.h" +#include "debuginfod-support.h" #include <fcntl.h> @@ -392,6 +393,10 @@ tui_enable (void) if (tui_active) return; + if (debuginfod_enabled_ask_p () + && defaulted_query_auto_answers_p () != TRIBOOL_TRUE) + error (_("Please set debuginfod enabled to on or off before enabling TUI")); + /* To avoid to initialize curses when gdb starts, there is a deferred curses initialization. This initialization is made only once and the first time the curses mode is entered. */ -- 2.51.0 ++++++ qa.sh ++++++ --- /var/tmp/diff_new_pack.jKGril/_old 2026-03-19 17:33:18.235681582 +0100 +++ /var/tmp/diff_new_pack.jKGril/_new 2026-03-19 17:33:18.243681913 +0100 @@ -3,7 +3,7 @@ usage () { echo "usage: $0 <1-5>" - echo " $0 -local [ -sle11 | -sle12 | -factory | -i586 | -x86_64 | -aarch64 | -powerpc64le | -s390 | -s390x ] <dir>" + echo " $0 -local [ -sle12 | -factory | -i586 | -x86_64 | -aarch64 | -powerpc64le | -s390x ] <dir>" echo echo "Verify remote results at:" echo " ./binaries-testsuite.distro.arch/gdb-testresults" @@ -26,22 +26,17 @@ n="$1" shift -have_sle11=false have_sle12=false have_factory=false have_aarch64=false have_arm=false have_powerpc64le=false -have_s390=false have_s390x=false have_i586=false have_x86_64=false if [ "$n" = "-local" ]; then while [ $# -gt 1 ]; do case $1 in - -sle11) - have_sle11=true - ;; -sle12) have_sle12=true ;; @@ -57,9 +52,6 @@ -powerpc64le|-ppc64le) have_powerpc64le=true ;; - -s390) - have_s390=true - ;; -s390x) have_s390x=true ;; @@ -142,10 +134,6 @@ # https://sourceware.org/bugzilla/show_bug.cgi?id=32608 "FAIL: gdb.threads/step-over-thread-exit-while-stop-all-threads.exp: displaced-stepping=auto: target-non-stop=on: iter .*: continue" - # https://sourceware.org/bugzilla/show_bug.cgi?id=31721 - "FAIL: gdb.base/list-dot-nodebug.exp: debug=none: print before start" - "FAIL: gdb.base/list-dot-nodebug.exp: debug=some: print before start" - # https://sourceware.org/bugzilla/show_bug.cgi?id=26971 "FAIL: gdb.arch/amd64-init-x87-values.exp: check_x87_regs_around_init: check post FLD1 value of .fop" "FAIL: gdb.arch/amd64-init-x87-values.exp: check_x87_regs_around_init: check post FLD1 value of .fioff" @@ -154,9 +142,6 @@ "FAIL: gdb.base/step-over-syscall.exp: clone: displaced=(off|on): single step over clone" "FAIL: gdb.base/step-over-syscall.exp: clone: displaced=(off|on): continue to marker \(clone\)" - # https://sourceware.org/bugzilla/show_bug.cgi?id=19436#c1 - "FAIL: gdb.cp/no-dmgl-verbose.exp: setting breakpoint at 'f\(std::string\)'" - # https://sourceware.org/bugzilla/show_bug.cgi?id=25504 "FAIL: gdb.threads/process-dies-while-detaching.exp: single-process: continue: .*: continue" @@ -288,9 +273,6 @@ "FAIL: gdb.ada/mi_var_access.exp: Create varobj \(unexpected output\)" "FAIL: gdb.ada/mi_var_access.exp: update at stop 2 \(unexpected output\)" - # Fragile test-case, requires glibc to fail in a certain way, ignore. - "FAIL: gdb.base/gdb-rhbz1156192-recursive-dlopen.exp:" - # GDB fails to print "Thread $x stopped" message for all threads, but # subsequent info threads shows all threads stopped, and a previous # info threads show all threads running. Not harmful. @@ -305,10 +287,6 @@ # https://sourceware.org/bugzilla/show_bug.cgi?id=30521 "FAIL: gdb.base/printcmds.exp: print {unsigned char\[\]}{0xffffffff}" - # https://sourceware.org/bugzilla/show_bug.cgi?id=30528 - # Fixed in 15. Backportable to 14. - "FAIL: gdb.dwarf2/per-bfd-sharing.exp: couldn't remove files in temporary cache dir" - # https://sourceware.org/bugzilla/show_bug.cgi?id=30480 "FAIL: gdb.ada/info_auto_lang.exp: language_choice=auto: frame=0, frame_lang=c: info functions proc_in_" "FAIL: gdb.ada/info_auto_lang.exp: language_choice=auto: frame=1, frame_lang=ada: info functions proc_in_" @@ -321,17 +299,9 @@ "FAIL: gdb.ada/mi_exc_info.exp: -info-ada-exceptions task \(unexpected output\)" "FAIL: gdb.ada/mi_exc_info.exp: -info-ada-exceptions const.aint \(unexpected output\)" - # https://sourceware.org/bugzilla/show_bug.cgi?id=31440 - "FAIL: gdb.python/py-progspace-events.exp: inferior 1 \(timeout\)" - "FAIL: gdb.python/py-progspace-events.exp: step" - # https://sourceware.org/bugzilla/show_bug.cgi?id=31809 "FAIL: gdb.threads/attach-slow-waitpid.exp: attach to target \(timeout\)" - # https://sourceware.org/bugzilla/show_bug.cgi?id=31806 - "FAIL: gdb.debuginfod/fetch_src_and_symbols.exp: local_url: file corefile" - "FAIL: gdb.debuginfod/crc_mismatch.exp: local_debuginfod: debuginfod running, info downloaded, no CRC mismatch" - # https://sourceware.org/bugzilla/show_bug.cgi?id=31811 "FAIL: gdb.threads/threads-after-exec.exp:" @@ -339,10 +309,6 @@ "FAIL: gdb.server/stop-reply-no-thread.exp: to_disable=threads: continue to main \(timeout\)" "FAIL: gdb.server/stop-reply-no-thread.exp: to_disable=threads: continue until exit \(timeout\)" - # https://sourceware.org/bugzilla/show_bug.cgi?id=31831 - "FAIL: gdb.dap/log-message.exp: logging output \(checking body category\)" - - # https://sourceware.org/bugzilla/show_bug.cgi?id=32121 "FAIL: gdb.arch/i386-disp-step-self-call.exp: check return address was updated correctly" "FAIL: gdb.arch/amd64-disp-step-self-call.exp: check return address was updated correctly" @@ -460,15 +426,6 @@ ) # kfail_sle12 -kfail_sle11=( - - # FAILs for SLE-11 are not very interesting. This is with on old compiler: - # 4.3.4, and tests are likely to be broken. We're really only interested in - # segmentation faults and internal errors. - "FAIL: " - -) - kfail_factory=( # https://sourceware.org/pipermail/gdb-patches/2021-October/182449.html @@ -483,10 +440,6 @@ # https://sourceware.org/bugzilla/show_bug.cgi?id=28477 "FAIL: gdb.base/step-over-syscall.exp: clone: displaced=off: continue to marker \(clone\)" - # https://sourceware.org/bugzilla/show_bug.cgi?id=28510 - "FAIL: gdb.debuginfod/fetch_src_and_symbols.exp: local_url: br main" - "FAIL: gdb.debuginfod/fetch_src_and_symbols.exp: local_url: l" - # https://sourceware.org/bugzilla/show_bug.cgi?id=28667 "FAIL: gdb.reverse/watch-precsave.exp: watchpoint hit, fourth time \\(GDB internal error\\)" @@ -494,9 +447,6 @@ "FAIL: gdb.base/gdb11531.exp: watchpoint variable triggers at next" "FAIL: gdb.base/gdb11531.exp: watchpoint variable triggers at continue" - # https://sourceware.org/bugzilla/show_bug.cgi?id=29706 - "FAIL: gdb.base/eof-exit.exp: with non-dump terminal: with bracketed-paste-mode on: close GDB with eof \(missed the prompt\)" - # Looks like a problem with modern debug info, where stepping out of a # function takes more one step. "FAIL: gdb.base/rtld-step.exp: finish out of foo 1" @@ -513,46 +463,9 @@ # likely to cause timeouts. gdb.gdb/python-helper.exp - # Should be fixed by commit fe6356def67 ("PowerPC and aarch64: Fix reverse - # stepping failure"), available in gdb 15. - "FAIL: gdb.reverse/solib-precsave.exp: reverse-step into solib function one" - "FAIL: gdb.reverse/solib-precsave.exp: reverse-step within solib function one" - "FAIL: gdb.reverse/solib-precsave.exp: reverse-step back to main one" - "FAIL: gdb.reverse/solib-precsave.exp: reverse-step into solib function two" - "FAIL: gdb.reverse/solib-precsave.exp: reverse-step within solib function two" - "FAIL: gdb.reverse/solib-precsave.exp: reverse-step back to main two" - "FAIL: gdb.reverse/solib-precsave.exp: run until end part two" - "FAIL: gdb.reverse/solib-precsave.exp: reverse-next over solib function one" - "FAIL: gdb.reverse/solib-precsave.exp: reverse-next over solib function two" - "FAIL: gdb.reverse/solib-reverse.exp: reverse-step into solib function one" - "FAIL: gdb.reverse/solib-reverse.exp: reverse-step within solib function one" - "FAIL: gdb.reverse/solib-reverse.exp: reverse-step back to main one" - "FAIL: gdb.reverse/solib-reverse.exp: reverse-step into solib function two" - "FAIL: gdb.reverse/solib-reverse.exp: reverse-step within solib function two" - "FAIL: gdb.reverse/solib-reverse.exp: reverse-step back to main two" - "FAIL: gdb.reverse/solib-reverse.exp: run until end part two" - "FAIL: gdb.reverse/solib-reverse.exp: reverse-next over solib function one" - "FAIL: gdb.reverse/solib-reverse.exp: reverse-next over solib function two" - # https://sourceware.org/bugzilla/show_bug.cgi?id=31564 "FAIL: gdb.base/rtld-step.exp: runto: run to main" - # https://sourceware.org/bugzilla/show_bug.cgi?id=32678 - "FAIL: gdb.reverse/time-reverse.exp: mode=c:" - - # https://sourceware.org/bugzilla/show_bug.cgi?id=33054 - "FAIL: gdb.ada/task_switch_in_core.exp: info tasks after switching to task 1" - "FAIL: gdb.ada/task_switch_in_core.exp: info tasks after switching to task 2" - "FAIL: gdb.ada/task_switch_in_core.exp: task 1" - "FAIL: gdb.ada/task_switch_in_core.exp: task 2" - "FAIL: gdb.server/server-kill.exp: test_tstatus: tstatus" - "FAIL: gdb.threads/threadcrash.exp: test_gcore: \\\$thread_count == \[llength \\\$test_list\]" - "FAIL: gdb.threads/threadcrash.exp: test_gcore: thread apply 2 backtrace" - "FAIL: gdb.threads/threadcrash.exp: test_gcore: thread apply 3 backtrace" - "FAIL: gdb.threads/threadcrash.exp: test_gcore: thread apply 4 backtrace" - "FAIL: gdb.threads/threadcrash.exp: test_gcore: thread apply 5 backtrace" - "FAIL: gdb.threads/tls-core.exp: gcore: print thread-local storage variable" - ) # kfail_factory kfail_aarch64=( @@ -598,9 +511,6 @@ # Known to run into timeouts. "FAIL: gdb.gdb/python-helper.exp" - # https://sourceware.org/bugzilla/show_bug.cgi?id=30548 - "FAIL: gdb.base/inline-frame-cycle-unwind.exp: cycle at level [0-9]*: backtrace when the unwind is broken at frame [0-9]*" - # https://sourceware.org/bugzilla/show_bug.cgi?id=29815 "FAIL: gdb.reverse/finish-reverse-bkpt.exp: reverse-finish from void_func trips breakpoint at entry" "FAIL: gdb.reverse/finish-reverse-bkpt.exp: no spurious proceed after breakpoint stop" @@ -684,11 +594,6 @@ # https://bugzilla.suse.com/show_bug.cgi?id=1234665 "FAIL: gdb.ada/tasks.exp: info threads" - # https://sourceware.org/bugzilla/show_bug.cgi?id=31229 - "FAIL: gdb.linespec/explicit.exp: complete after -qualified -source: cmd complete .b -qualified -source thr." - "FAIL: gdb.linespec/explicit.exp: complete after -qualified -source: tab complete .b -qualified -source thr." - "FAIL: gdb.linespec/explicit.exp: complete after -source: cmd complete .b -source thr." - "FAIL: gdb.linespec/explicit.exp: complete after -source: tab complete .b -source thr." ) kfail_powerpc64le_sle12=( @@ -701,76 +606,11 @@ ) -kfail_s390x_s390=( - -) - -# Plain s390 or s390x/-m31. -kfail_s390=( - - "${kfail_s390x_s390[@]}" - - # https://sourceware.org/bugzilla/show_bug.cgi?id=29841 - "FAIL: gdb.reverse/.*.exp:" - - # Doesn't reproduce with trunk on SLE-12SP5. - "FAIL: gdb.guile/scm-ports.exp: buffered: test byte at sp, before flush" - - # https://sourceware.org/bugzilla/show_bug.cgi?id=29867 - "FAIL: gdb.guile/scm-lazy-string.exp: ptr: lazy string length 2 value" - "FAIL: gdb.guile/scm-lazy-string.exp: ptr: lazy string value" - "FAIL: gdb.guile/scm-lazy-string.exp: ptr: print ptr" - "FAIL: gdb.base/sym-file.exp: add-symbol-file sym-file-lib.so addr" - "FAIL: gdb.base/sym-file.exp: continue to breakpoint: gdb_add_symbol_file" - "FAIL: gdb.python/py-lazy-string.exp: ptr: lazy string length 2 value" - "FAIL: gdb.python/py-lazy-string.exp: ptr: lazy string value" - "FAIL: gdb.python/py-lazy-string.exp: ptr: print ptr" - "FAIL: gdb.python/py-nested-maps.exp: headers=on: pretty=off: exp='\*mm': depth=1: p \*mm" - "FAIL: gdb.python/py-nested-maps.exp: headers=on: pretty=off: exp='\*mm': depth=2: p \*mm" - "FAIL: gdb.python/py-nested-maps.exp: headers=on: pretty=off: exp='\*mm': depth=3: p \*mm" - "FAIL: gdb.python/py-nested-maps.exp: headers=on: pretty=off: exp='\*mm': depth=unlimited: p \*mm" - "FAIL: gdb.python/py-nested-maps.exp: pretty=off: exp='\*mm': depth=1: p \*mm" - "FAIL: gdb.python/py-nested-maps.exp: pretty=off: exp='\*mm': depth=2: p \*mm" - "FAIL: gdb.python/py-nested-maps.exp: pretty=off: exp='\*mm': depth=3: p \*mm" - "FAIL: gdb.python/py-nested-maps.exp: pretty=off: exp='\*mm': depth=unlimited: p \*mm" - "FAIL: gdb.python/py-nested-maps.exp: pretty=on: exp='\*mm': depth=1: p \*mm" - "FAIL: gdb.python/py-nested-maps.exp: pretty=on: exp='\*mm': depth=2: p \*mm" - "FAIL: gdb.python/py-nested-maps.exp: pretty=on: exp='\*mm': depth=3: p \*mm" - "FAIL: gdb.python/py-nested-maps.exp: pretty=on: exp='\*mm': depth=unlimited: p \*mm" - "FAIL: gdb.base/info-shared.exp:" - "FAIL: gdb.python/py-strfns.exp: p /d {char\[4\]} arg" - "FAIL: gdb.python/py-strfns.exp: p arg" - -) - # s390x/-m64. -kfail_s390x=( - - "${kfail_s390x_s390[@]}" - -) +kfail_s390x=() kfail_i586=( - # https://sourceware.org/bugzilla/show_bug.cgi?id=30519 - "FAIL: gdb.python/py-parameter.exp: test_integer_parameter: kind=PARAM_UINTEGER: test default value" - "FAIL: gdb.python/py-parameter.exp: test_integer_parameter: kind=PARAM_UINTEGER: test default value via gdb.parameter" - "FAIL: gdb.python/py-parameter.exp: test_integer_parameter: kind=PARAM_UINTEGER: {test set to -1}" - "FAIL: gdb.python/py-parameter.exp: test_integer_parameter: kind=PARAM_UINTEGER: test value of -1" - "FAIL: gdb.python/py-parameter.exp: test_integer_parameter: kind=PARAM_UINTEGER: test value of -1 via gdb.parameter" - "FAIL: gdb.python/py-parameter.exp: test_integer_parameter: kind=PARAM_UINTEGER: test set to 1" - "FAIL: gdb.python/py-parameter.exp: test_integer_parameter: kind=PARAM_UINTEGER: test value of 1" - "FAIL: gdb.python/py-parameter.exp: test_integer_parameter: kind=PARAM_UINTEGER: test value of 1 via gdb.parameter" - "FAIL: gdb.python/py-parameter.exp: test_integer_parameter: kind=PARAM_UINTEGER: {test set to -5}" - "FAIL: gdb.python/py-parameter.exp: test_integer_parameter: kind=PARAM_UINTEGER: test value of -5 via gdb.parameter" - "FAIL: gdb.python/py-parameter.exp: test_integer_parameter: kind=PARAM_UINTEGER: test set to 5" - "FAIL: gdb.python/py-parameter.exp: test_integer_parameter: kind=PARAM_UINTEGER: test value of 5 via gdb.parameter" - "FAIL: gdb.python/py-parameter.exp: test_integer_parameter: kind=PARAM_UINTEGER: {test set to None}" - "FAIL: gdb.python/py-parameter.exp: test_integer_parameter: kind=PARAM_UINTEGER: test value of None" - "FAIL: gdb.python/py-parameter.exp: test_integer_parameter: kind=PARAM_UINTEGER: test value of None via gdb.parameter" - "FAIL: gdb.python/py-parameter.exp: test_integer_parameter: kind=PARAM_UINTEGER: test set to 0" - "FAIL: gdb.python/py-parameter.exp: test_integer_parameter: kind=PARAM_UINTEGER: test value of 0 via gdb.parameter" - # https://sourceware.org/bugzilla/show_bug.cgi?id=32407 "FAIL: gdb.base/valgrind-bt.exp:" "FAIL: gdb.base/valgrind-disp-step.exp:" @@ -779,16 +619,7 @@ ) -kfail_arm=( - - # https://sourceware.org/bugzilla/show_bug.cgi?id=30537 - "FAIL: gdb.fortran/intrinsics.exp: p cmplx \(4,4,16\) \(GDB internal error\)" - "FAIL: gdb.fortran/intrinsics.exp: ptype cmplx \(4,4,16\) \(GDB internal error\)" - - # https://sourceware.org/bugzilla/show_bug.cgi?id=31061 - "FAIL: gdb.base/gdb-sigterm.exp: .*internal error" - -) +kfail_arm=() case $n in 1) @@ -798,8 +629,6 @@ # Todo: apply kfail_factory/kfail_sle12 only when appropriate. kfail+=("${kfail_factory[@]}") kfail+=("${kfail_sle12[@]}") - kfail+=("${kfail_sle11[@]}") - kfail+=("${kfail_s390[@]}") kfail+=("${kfail_powerpc64le[@]}") kfail+=("${kfail_arm[@]}") kfail+=("${kfail_aarch64[@]}") @@ -819,15 +648,6 @@ # Gdb runs out of virtual memory, we can expect an internal error. "UNRESOLVED: gdb.base/gcore-excessive-memory.exp: attach" "UNRESOLVED: gdb.base/gcore-excessive-memory.exp: verify we can get to main" - - # https://sourceware.org/bugzilla/show_bug.cgi?id=31001 - "UNRESOLVED: gdb.threads/async.exp: thread 1: current thread is 1" - - # https://sourceware.org/bugzilla/show_bug.cgi?id=31648 - "SLE-11.*UNRESOLVED: gdb.ada/tick_length_array_enum_idx.exp: print vars'length" - - # https://sourceware.org/bugzilla/show_bug.cgi?id=31671 - "SLE-11.*UNRESOLVED: gdb.objc/basicclass.exp: call an Objective-C method with no arguments" ) kfail_re=$(join "|" "${kfail[@]}") @@ -871,15 +691,9 @@ # https://sourceware.org/bugzilla/show_bug.cgi?id=29897 "displaced-stepping.c:[0-9]*: internal-error: prepare: Assertion \`buf.current_thread != thread' failed." - # https://sourceware.org/bugzilla/show_bug.cgi?id=30537 - "f-lang.c:[0-9]*: internal-error: eval_op_f_cmplx: Assertion \`kind_arg->code \(\) == TYPE_CODE_COMPLEX' failed." - # Test-case gdb.base/gcore-excessive-memory.exp. "utils.c:[0-9]*: internal-error: virtual memory exhausted: can't allocate [0-9]* bytes." - # https://sourceware.org/bugzilla/show_bug.cgi?id=31061 - "intrusive_list.h:[0-9]*: internal-error: erase_element: Assertion \`elem_node->prev != INTRUSIVE_LIST_UNLINKED_VALUE' failed\." - # Assumed to be variant of # https://sourceware.org/bugzilla/show_bug.cgi?id=32446 "linux-nat.c:[0-9]*: internal-error: mark_lwp_dead: Assertion .lp->status == 0. failed\." @@ -1069,20 +883,12 @@ ;; 5) - librpm=$(ls -1 binaries-testsuite*/gdb-testresults/*.sum \ - | grep -v SLE-11) - nolibrpm=$(ls -1 binaries-testsuite*/gdb-testresults/*.sum \ - | grep SLE-11) + librpm=$(ls -1 binaries-testsuite*/gdb-testresults/*.sum) if [ "$librpm" != "" ]; then grep -c "PASS: gdb.suse/zypper-hint.exp: zypper hint printed (librpm)" \ $librpm \ | grep -E -v ":1" fi - if [ "$nolibrpm" != "" ]; then - grep -c "PASS: gdb.suse/zypper-hint.exp: zypper hint printed (no librpm)" \ - $nolibrpm \ - | grep -E -v ":1" - fi ;; -local) @@ -1101,9 +907,6 @@ if $have_factory; then kfail+=("${kfail_factory[@]}") fi - if $have_sle11; then - kfail+=("${kfail_sle11[@]}") - fi if $have_sle12; then kfail+=("${kfail_sle12[@]}") fi @@ -1119,9 +922,6 @@ if $have_powerpc64le && $have_sle12; then kfail+=("${kfail_powerpc64le_sle12[@]}") fi - if $have_s390; then - kfail+=("${kfail_s390[@]}") - fi if $have_s390x; then kfail+=("${kfail_s390x[@]}") fi
