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-02-17 16:36:27
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/gdb (Old)
 and      /work/SRC/openSUSE:Factory/.gdb.new.1977 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "gdb"

Tue Feb 17 16:36:27 2026 rev:191 rq:1333328 version:16.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/gdb/gdb.changes  2025-11-28 16:50:42.228655635 
+0100
+++ /work/SRC/openSUSE:Factory/.gdb.new.1977/gdb.changes        2026-02-17 
16:37:32.698834990 +0100
@@ -1,0 +2,25 @@
+Tue Feb 10 09:38:59 UTC 2026 - Tom de Vries <[email protected]>
+
+- Fix slow symbol lookup with dwz-compressed debuginfo (swo#33825,
+  bsc#1257111).  Patches added:
+  * gdb-symtab-fix-slow-symbol-lookup-with-dwz.patch
+- Fix failure to list source file with dwz-compressed debuginfo
+  (brc#2403580). Patches added:
+  * fix-rhbz2403580-misplaced-symtabs-due-to-dwz.patch
+  * gdb-test-for-misplaced-symtab-causing-file-not-found.patch
+  * gdb-testsuite-add-missing-require-in-gdb.debuginfod-.patch
+  * gdb-testsuite-launch-debuginfod-without-vvvv.patch
+- Fix slow symbol table reading with dwz-compressed debuginfo
+  (swo#33777).  Patches added:
+  * gdb-symtab-cache-dw2_get_file_names-result-for-dummy.patch
+- Fix heap-use-after-free, reported by TSAN.  Patches added:
+  * gdb-symtab-handle-zero-opcode_base-in-line-number-pr.patch
+- Fix backtrace through signal trampoline on s390x (swo#33708).
+  Patches added:
+  * gdb-tdep-fix-gdb.base-siginfo.exp-on-s390x-linux.patch
+- Testsuite fixes.  Patches added:
+  * gdb-testsuite-fix-another-timeout-in-gdb.mi-mi-multi.patch
+  * gdb-testsuite-remove-guile-test-byte-at-sp-before-fl.patch
+  * gdb-fix-gdb.base-inline-frame-cycle-unwind.exp-for-s.patch
+
+-------------------------------------------------------------------

New:
----
  fix-rhbz2403580-misplaced-symtabs-due-to-dwz.patch
  gdb-fix-gdb.base-inline-frame-cycle-unwind.exp-for-s.patch
  gdb-symtab-cache-dw2_get_file_names-result-for-dummy.patch
  gdb-symtab-fix-slow-symbol-lookup-with-dwz.patch
  gdb-symtab-handle-zero-opcode_base-in-line-number-pr.patch
  gdb-tdep-fix-gdb.base-siginfo.exp-on-s390x-linux.patch
  gdb-test-for-misplaced-symtab-causing-file-not-found.patch
  gdb-testsuite-add-missing-require-in-gdb.debuginfod-.patch
  gdb-testsuite-fix-another-timeout-in-gdb.mi-mi-multi.patch
  gdb-testsuite-launch-debuginfod-without-vvvv.patch
  gdb-testsuite-remove-guile-test-byte-at-sp-before-fl.patch

----------(New B)----------
  New:  (brc#2403580). Patches added:
  * fix-rhbz2403580-misplaced-symtabs-due-to-dwz.patch
  * gdb-test-for-misplaced-symtab-causing-file-not-found.patch
  New:  * gdb-testsuite-remove-guile-test-byte-at-sp-before-fl.patch
  * gdb-fix-gdb.base-inline-frame-cycle-unwind.exp-for-s.patch
  New:  (swo#33777).  Patches added:
  * gdb-symtab-cache-dw2_get_file_names-result-for-dummy.patch
- Fix heap-use-after-free, reported by TSAN.  Patches added:
  New:  bsc#1257111).  Patches added:
  * gdb-symtab-fix-slow-symbol-lookup-with-dwz.patch
- Fix failure to list source file with dwz-compressed debuginfo
  New:- Fix heap-use-after-free, reported by TSAN.  Patches added:
  * gdb-symtab-handle-zero-opcode_base-in-line-number-pr.patch
- Fix backtrace through signal trampoline on s390x (swo#33708).
  New:  Patches added:
  * gdb-tdep-fix-gdb.base-siginfo.exp-on-s390x-linux.patch
- Testsuite fixes.  Patches added:
  New:  * fix-rhbz2403580-misplaced-symtabs-due-to-dwz.patch
  * gdb-test-for-misplaced-symtab-causing-file-not-found.patch
  * gdb-testsuite-add-missing-require-in-gdb.debuginfod-.patch
  New:  * gdb-test-for-misplaced-symtab-causing-file-not-found.patch
  * gdb-testsuite-add-missing-require-in-gdb.debuginfod-.patch
  * gdb-testsuite-launch-debuginfod-without-vvvv.patch
  New:- Testsuite fixes.  Patches added:
  * gdb-testsuite-fix-another-timeout-in-gdb.mi-mi-multi.patch
  * gdb-testsuite-remove-guile-test-byte-at-sp-before-fl.patch
  New:  * gdb-testsuite-add-missing-require-in-gdb.debuginfod-.patch
  * gdb-testsuite-launch-debuginfod-without-vvvv.patch
- Fix slow symbol table reading with dwz-compressed debuginfo
  New:  * gdb-testsuite-fix-another-timeout-in-gdb.mi-mi-multi.patch
  * gdb-testsuite-remove-guile-test-byte-at-sp-before-fl.patch
  * gdb-fix-gdb.base-inline-frame-cycle-unwind.exp-for-s.patch
----------(New E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ gdb.spec ++++++
--- /var/tmp/diff_new_pack.LhdwpE/_old  2026-02-17 16:37:36.426990675 +0100
+++ /var/tmp/diff_new_pack.LhdwpE/_new  2026-02-17 16:37:36.430990842 +0100
@@ -212,6 +212,8 @@
 Patch1508:      gdb-testsuite-fix-gdb_py_module_available-for-python.patch
 # https://sourceware.org/bugzilla/show_bug.cgi?id=32850
 Patch1509:      gdb-testsuite-work-around-pr32850.patch
+# https://sourceware.org/bugzilla/show_bug.cgi?id=33901
+Patch1510:      gdb-testsuite-launch-debuginfod-without-vvvv.patch
 
 # Backports from master, available in GDB 17.
 
@@ -266,6 +268,7 @@
 Patch2151:      gdb-testsuite-fix-possible-tcl-errors-in-gdb.threads.patch
 Patch2152:      gdb-testsuite-fix-xfail-in-gdb.ada-array_of_variant..patch
 Patch2153:      gdb-testsuite-fix-gdb.mi-mi-sym-info.exp.patch
+Patch2154:      gdb-symtab-cache-dw2_get_file_names-result-for-dummy.patch
 
 # Backports from master, available in GDB 18.
 
@@ -287,6 +290,14 @@
 Patch2515:      gdb-testsuite-force-dwarf-in-gdb.pascal.patch
 Patch2516:      gdb-testsuite-fix-main-in-gdb.trace-mi-trace-frame-c.patch
 Patch2517:      mark-pascal-as-case-insensitive.patch
+Patch2518:      gdb-testsuite-fix-another-timeout-in-gdb.mi-mi-multi.patch
+Patch2519:      fix-rhbz2403580-misplaced-symtabs-due-to-dwz.patch
+Patch2520:      gdb-test-for-misplaced-symtab-causing-file-not-found.patch
+Patch2521:      gdb-symtab-handle-zero-opcode_base-in-line-number-pr.patch
+Patch2522:      gdb-testsuite-add-missing-require-in-gdb.debuginfod-.patch
+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
 
 # Backport from gdb-patches
 
@@ -330,6 +341,9 @@
 
 # Other.  Needs comment for each patch.
 
+# Backport from gdb-17-branch, not available in master.
+Patch3500:      gdb-symtab-fix-slow-symbol-lookup-with-dwz.patch
+
 # fix build failure w/ cmake-4; cf. github.com/intel/libipt/commit/fa7d42d
 Patch4001:      libipt-cmake4-patch
 
@@ -663,6 +677,7 @@
 %patch -P 1506 -p1
 %patch -P 1508 -p1
 %patch -P 1509 -p1
+%patch -P 1510 -p1
 
 %patch -P 2100 -p1
 %patch -P 2101 -p1
@@ -715,6 +730,7 @@
 %patch -P 2151 -p1
 %patch -P 2152 -p1
 %patch -P 2153 -p1
+%patch -P 2154 -p1
 
 %patch -P 2500 -p1
 %patch -P 2501 -p1
@@ -734,6 +750,14 @@
 %patch -P 2515 -p1
 %patch -P 2516 -p1
 %patch -P 2517 -p1
+%patch -P 2518 -p1
+%patch -P 2519 -p1
+%patch -P 2520 -p1
+%patch -P 2521 -p1
+%patch -P 2522 -p1
+%patch -P 2523 -p1
+%patch -P 2524 -p1
+%patch -P 2525 -p1
 
 %patch -P 3000 -p1
 %patch -P 3001 -p1
@@ -750,6 +774,8 @@
 %patch -P 3019 -p1
 %patch -P 3020 -p1
 
+%patch -P 3500 -p1
+
 #unpack libipt
 %if 0%{have_libipt}
 tar xzf %{SOURCE7}

++++++ _scmsync.obsinfo ++++++
--- /var/tmp/diff_new_pack.LhdwpE/_old  2026-02-17 16:37:36.574996856 +0100
+++ /var/tmp/diff_new_pack.LhdwpE/_new  2026-02-17 16:37:36.582997190 +0100
@@ -1,5 +1,5 @@
-mtime: 1764171409
-commit: 23d498ecd78ce78144946aaed8510ac9d4d9ecc9d4300ed26691f6235eb5da46
+mtime: 1770907926
+commit: 9fbb0c682577f632d01252fb790352de3aa480952b4452c63096afce1f53d6b1
 url: https://src.opensuse.org/gcc/gdb.git
 revision: main
 

++++++ 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-02-13 12:11:39.000000000 +0100
@@ -0,0 +1 @@
+.osc

++++++ fix-rhbz2403580-misplaced-symtabs-due-to-dwz.patch ++++++
>From 1a9251041357be4c94971113101086be025affbd Mon Sep 17 00:00:00 2001
From: Andrew Burgess <[email protected]>
Date: Tue, 10 Feb 2026 11:47:12 +0100
Subject: [PATCH 1/4] fix rhbz2403580 - misplaced symtabs due to dwz

Backport upstream commit 70b66cf338b14336 to fix RH BZ 2403580.

Bug: https://bugzilla.redhat.com/show_bug.cgi?id=2403580

Cherry-picked from fedora @ 34c5cd8.
---
 gdb/dwarf2/line-header.c | 43 ++++++++++++++++++++++++++++++++++++++++
 gdb/dwarf2/line-header.h | 13 +++++++++++-
 gdb/dwarf2/read.c        | 15 ++++++++------
 3 files changed, 64 insertions(+), 7 deletions(-)

diff --git a/gdb/dwarf2/line-header.c b/gdb/dwarf2/line-header.c
index eddb2ef7ae8..0f4407f2fb2 100644
--- a/gdb/dwarf2/line-header.c
+++ b/gdb/dwarf2/line-header.c
@@ -418,3 +418,46 @@ dwarf_decode_line_header  (sect_offset sect_off, bool 
is_dwz,
 
   return lh;
 }
+
+/* See dwarf2/line-header.h.  */
+
+struct symtab *
+file_entry::symtab (dwarf2_cu &cu)
+{
+  if (m_symtab == nullptr)
+    {
+      buildsym_compunit *builder = cu.get_builder ();
+      compunit_symtab *cust = builder->get_compunit_symtab ();
+
+      {
+       std::string filename_holder;
+       const char *filename = this->name;
+       const char *dirname = cu.line_header->include_dir_at (this->d_index);
+
+       /* In order not to lose the line information directory,
+          we concatenate it to the filename when it makes sense.
+          Note that the Dwarf3 standard says (speaking of filenames in line
+          information): ``The directory index is ignored for file names
+          that represent full path names''.  Thus ignoring dirname in the
+          `else' branch below isn't an issue.  */
+
+       if (!IS_ABSOLUTE_PATH (filename) && dirname != NULL)
+         {
+           filename_holder = path_join (dirname, filename);
+           filename = filename_holder.c_str ();
+         }
+
+       std::string filename_for_id = cu.line_header->file_file_name (*this);
+       cu.get_builder ()->start_subfile (filename, filename_for_id.c_str ());
+      }
+
+      subfile *sf = builder->get_current_subfile ();
+      if (sf->symtab == nullptr)
+       sf->symtab = allocate_symtab (cust, sf->name.c_str (),
+                                     sf->name_for_id.c_str ());
+
+      m_symtab = sf->symtab;
+    }
+
+  return m_symtab;
+}
diff --git a/gdb/dwarf2/line-header.h b/gdb/dwarf2/line-header.h
index 30809f69acc..f9b5f81eecd 100644
--- a/gdb/dwarf2/line-header.h
+++ b/gdb/dwarf2/line-header.h
@@ -23,6 +23,7 @@
 #include "dwarf2/types.h"
 
 struct dwarf2_per_objfile;
+struct dwarf2_cu;
 
 /* dir_index is 1-based in DWARF 4 and before, and is 0-based in DWARF 5 and
    later.  */
@@ -65,8 +66,18 @@ struct file_entry
 
   unsigned int length {};
 
+  /* Get the symtab for this file_entry.  If no symtab has yet been created
+     or set (see set_symtab) for this file_entry then a new one will be
+     created.  */
+  struct symtab *symtab (struct dwarf2_cu &cu);
+
+  /* Set the symtab for this file_entry.  */
+  void set_symtab (struct symtab *s)
+  { m_symtab = s; }
+
+private:
   /* The associated symbol table, if any.  */
-  struct symtab *symtab {};
+  struct symtab *m_symtab {};
 };
 
 /* The line number information for a compilation unit (found in the
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index f8f411c195a..f4a1eaf0f53 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -7669,8 +7669,8 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
              sf->symtab = allocate_symtab (cust, name, name_for_id);
            }
 
-         fe.symtab = b->get_current_subfile ()->symtab;
-         tug_unshare->symtabs[i] = fe.symtab;
+         fe.set_symtab (b->get_current_subfile ()->symtab);
+         tug_unshare->symtabs[i] = fe.symtab (*this);
        }
     }
   else
@@ -7688,7 +7688,7 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
       for (i = 0; i < file_names.size (); ++i)
        {
          file_entry &fe = file_names[i];
-         fe.symtab = tug_unshare->symtabs[i];
+         fe.set_symtab (tug_unshare->symtabs[i]);
        }
     }
 
@@ -13291,7 +13291,7 @@ process_structure_scope (struct die_info *die, struct 
dwarf2_cu *cu)
            {
              /* Any related symtab will do.  */
              symtab
-               = cu->line_header->file_names ()[0].symtab;
+               = cu->line_header->file_names ()[0].symtab (*cu);
            }
          else
            {
@@ -18968,6 +18968,9 @@ dwarf_decode_lines (struct line_header *lh, struct 
dwarf2_cu *cu,
   if (decode_mapping)
     dwarf_decode_lines_1 (lh, cu, lowpc);
 
+  if (cu->per_cu->is_dwz)
+    return;
+
   /* Make sure a symtab is created for every file, even files
      which contain only variables (i.e. no code with associated
      line numbers).  */
@@ -18983,7 +18986,7 @@ dwarf_decode_lines (struct line_header *lh, struct 
dwarf2_cu *cu,
        sf->symtab = allocate_symtab (cust, sf->name.c_str (),
                                      sf->name_for_id.c_str ());
 
-      fe.symtab = sf->symtab;
+      fe.set_symtab (sf->symtab);
     }
 }
 
@@ -19256,7 +19259,7 @@ new_symbol (struct die_info *die, struct type *type, 
struct dwarf2_cu *cu,
          if (fe == NULL)
            complaint (_("file index out of range"));
          else
-           sym->set_symtab (fe->symtab);
+           sym->set_symtab (fe->symtab (*file_cu));
        }
 
       switch (die->tag)

base-commit: 8b5dc3da60d6c07991821c447f183288c4aac69e
-- 
2.51.0


++++++ gdb-fix-gdb.base-inline-frame-cycle-unwind.exp-for-s.patch ++++++
>From a7a70544ba0f74633d4473955018fa8277382812 Mon Sep 17 00:00:00 2001
From: Andrew Burgess <[email protected]>
Date: Wed, 21 Jan 2026 13:25:43 +0100
Subject: [PATCH 4/4] gdb: fix gdb.base/inline-frame-cycle-unwind.exp for s390x

With test-case gdb.base/inline-frame-cycle-unwind.exp on s390x-linux, I run
into:

  ...
  (gdb) bt
   #0  inline_func () at inline-frame-cycle-unwind.c:49
   #1  normal_func () at inline-frame-cycle-unwind.c:32
   #2  0x000000000100065c in inline_func () at inline-frame-cycle-unwind.c:45
   #3  normal_func () at inline-frame-cycle-unwind.c:32
   Backtrace stopped: previous frame identical to this frame (corrupt stack?)
  (gdb) FAIL: $exp: bt: cycle at level 5: backtrace when the unwind is broken \
    at frame 5
  ...

In contrast, on x86_64-linux, I get:

  ...
  (gdb) bt
   #0  inline_func () at inline-frame-cycle-unwind.c:49
   #1  normal_func () at inline-frame-cycle-unwind.c:32
   #2  0x0000000000401157 in inline_func () at inline-frame-cycle-unwind.c:45
   #3  normal_func () at inline-frame-cycle-unwind.c:32
   #4  0x0000000000401157 in inline_func () at inline-frame-cycle-unwind.c:45
   #5  normal_func () at inline-frame-cycle-unwind.c:32
   Backtrace stopped: previous frame identical to this frame (corrupt stack?)
  (gdb) PASS: $exp: bt: cycle at level 5: backtrace when the unwind is broken \
    at frame 5
  ...

To understand what's going wrong here, we first need to understand
what this test was trying to do.

The test tries to create a frame-cycle using a custom Python
unwinder.  A frame-cycle occurs when a frame in the backtrace has the
same frame-id as an earlier frame.  As soon as GDB finds a frame with
a frame-id that it has seen before then the backtrace will be
terminated with the message:

   Backtrace stopped: previous frame identical to this frame (corrupt stack?)

A Python frame unwinder does two jobs:

  - It provides the frame-id for a frame #n, and

  - it provides the unwound register values for the previous (#n + 1)
    frame.

For a frame not claimed by a Python frame unwinder, GDB will compute
the frame-id based off of the register values.  Particularly, the $pc
and $sp, or $fp registers (or the architecture's equivalent).

In this test then, our frame unwinder does something a little
strange.  When we want to stop at frame #5, the frame unwinder claims
frame #5.  The frame unwinder then tries to give frame #5 its "normal"
frame-id, but, instead of unwinding the register values, we provide
frame #6 with all of the register values from frame #5 unmodified.

The frame unwinder does not claim frame #6, instead GDB uses its
"normal" logic to compute the frame-id.  As the registers in frame #6
are identical to the values in frame #5, GDB computes the same
frame-id for frame #6 as we supplied for frame #5, and thus a frame
cycle is created.

Notice I said that we try to give frame #5 its "normal" frame-id.

When this test was originally written there was no easy way to access
the frame-id for a frame.  So instead, the test was written to try and
recreate the frame-id based on the frame stack pointers, and the frame
size (difference between subsequent frames).  And this worked fine for
a bunch of common architectures, like x86-64 and AArch64.

But unfortunately this frame-id computation doesn't work on s390.

For this explanation we only care about two parts of the frame-id, the
code address, and the stack address.  The code address part is usually
the start of the function for a particular frame.  Our computation of
this was fine.

The stack address in the frame-id isn't the actual $sp value.
Instead, this is usually the Call Frame Address (CFA) as defined in
the DWARF.  How this is calculated really depends on the DWARF, but is
often influenced by the architectures ABI.

On x86-64 and AArch64 the CFA is usually the $sp immediately on entry
to a frame, before any stack adjustment is performed.  Thus, if we
take the frame size (difference between $sp in two frames), and add
this to the current $sp value, we successfully calculate the CFA,
which we can use in the frame-id.

On s390 though, this is not the case, the calculation of the CFA is
more complex as the s390 ABI requires that caller frames allocate a
160 byte Register Save Area below the stack pointer.  Because of this,
when the Python unwinder ties to calculate the real frame-id for a
frame, it gets the CFA wrong, and inadvertently ends up calculating a
frame-id which matches an earlier frame-id.  In the example above,
frame #5 ends up matching frame #3.  Because frame #4 is an inline
frame GDB ends up terminating the backtrace after frame #3.

The fix for this is actually pretty simple.  Since this test was
originally written GDB has gained the 'maint print frame-id' command.
So instead of trying to calculate the frame-id we can just capture the
frame-ids that GDB generates, and then, once the Python frame unwinder
is in use, we can repeat the previously captured frame-id back to
GDB.

This fixes the issues seen on s390, and doesn't impact testing on the
other architectures.

Tested on x86_64-linux and s390x-linux.

Co-Authored-By: Tom de Vries <[email protected]>
---
 .../gdb.base/inline-frame-cycle-unwind.exp    |  3 +
 .../gdb.base/inline-frame-cycle-unwind.py     | 76 ++++++++++++++-----
 2 files changed, 60 insertions(+), 19 deletions(-)

diff --git a/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.exp 
b/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.exp
index 46561a9c9fb..66c59ccfbae 100644
--- a/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.exp
+++ b/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.exp
@@ -72,6 +72,9 @@ gdb_continue_to_breakpoint "stop at test breakpoint"
 gdb_test_no_output "source ${pyfile}"\
     "import python scripts"
 
+# Print the captured frame IDs.
+gdb_test "python print_frame_ids()"
+
 # Test with and without filters.
 foreach bt_cmd { "bt" "bt -no-filters" } {
     with_test_prefix "$bt_cmd" {
diff --git a/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.py 
b/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.py
index 278fa857d5d..17233165d0c 100644
--- a/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.py
+++ b/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.py
@@ -13,6 +13,8 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+import re
+
 import gdb
 from gdb.unwinder import Unwinder
 
@@ -21,10 +23,17 @@ from gdb.unwinder import Unwinder
 # was written for.
 stop_at_level = None
 
-# Set this to the stack frame size of frames 1, 3, and 5.  These
-# frames will all have the same stack frame size as they are the same
-# function called recursively.
-stack_adjust = None
+# List of FrameId instances, one for each stack frame.  This list is
+# populated when this file is sourced into GDB.
+frame_ids = []
+
+
+# To aid debugging, print the captured FrameId instances.
+def print_frame_ids():
+    for level, fid in enumerate(frame_ids):
+        print(
+            "frame-id for frame #%s: {stack=0x%x,code=0x%x}" % (level, fid.sp, 
fid.pc)
+        )
 
 
 class FrameId(object):
@@ -52,17 +61,39 @@ class TestUnwinder(Unwinder):
         if stop_at_level is None or pending_frame.level() != stop_at_level:
             return None
 
-        if stack_adjust is None:
-            raise gdb.GdbError("invalid stack_adjust")
+        if len(frame_ids) < stop_at_level:
+            raise gdb.GdbError("not enough parsed frame-ids")
 
         if not stop_at_level in [1, 3, 5]:
             raise gdb.GdbError("invalid stop_at_level")
 
-        sp_desc = pending_frame.architecture().registers().find("sp")
-        sp = pending_frame.read_register(sp_desc) + stack_adjust
-        pc = (gdb.lookup_symbol("normal_func"))[0].value().address
-        unwinder = pending_frame.create_unwind_info(FrameId(sp, pc))
-
+        # Set the frame-id for this frame to its actual, expected
+        # frame-id, which we captured in the FRAME_IDS list.
+        unwinder = pending_frame.create_unwind_info(frame_ids[stop_at_level])
+
+        # Provide the register values for the caller frame, that is,
+        # the frame at 'STOP_AT_LEVEL + 1'.
+        #
+        # We forward all of the register values unchanged from this
+        # frame.
+        #
+        # What this means is that, as far as GDB is concerned, the
+        # caller frame will appear to be identical to this frame.  Of
+        # particular importance, we send $pc and $sp unchanged to the
+        # caller frame.
+        #
+        # Because the caller frame has the same $pc and $sp as this
+        # frame, GDB will compute the same frame-id for the caller
+        # frame as we just supplied for this frame (above).  This
+        # creates the artificial frame cycle which is the whole point
+        # of this test.
+        #
+        # NOTE: Forwarding all registers unchanged like this to the
+        # caller frame is not how you'd normally write a frame
+        # unwinder.  Some registers might indeed be unmodified between
+        # frames, but we'd usually expect the $sp and/or the $pc to
+        # change.  This test is deliberately doing something weird in
+        # order to force a cycle, and so test GDB.
         for reg in pending_frame.architecture().registers("general"):
             val = pending_frame.read_register(reg)
             unwinder.add_saved_register(reg, val)
@@ -75,11 +106,18 @@ gdb.unwinder.register_unwinder(None, TestUnwinder(), True)
 #
 #   main -> normal_func -> inline_func -> normal_func -> inline_func -> 
normal_func -> inline_func
 #
-# Compute the stack frame size of normal_func, which has inline_func
-# inlined within it.
-f0 = gdb.newest_frame()
-f1 = f0.older()
-f2 = f1.older()
-f0_sp = f0.read_register("sp")
-f2_sp = f2.read_register("sp")
-stack_adjust = f2_sp - f0_sp
+# Iterate through frames 0 to 6, parse their frame-id and store it
+# into the global FRAME_IDS list.
+for i in range(7):
+    # Get the frame-id in a verbose text form.
+    output = gdb.execute("maint print frame-id %d" % i, to_string=True)
+
+    # Parse the frame-id in OUTPUT, find the stack and code addresses.
+    match = re.search(r"stack=(0x[0-9a-fA-F]+).*?code=(0x[0-9a-fA-F]+)", 
output)
+    if not match:
+        raise gdb.GdbError("Could not parse frame-id for frame #%d" % i)
+
+    # Create the FrameId object.
+    sp_addr = int(match.group(1), 16)
+    pc_addr = int(match.group(2), 16)
+    frame_ids.append(FrameId(sp_addr, pc_addr))
-- 
2.51.0


++++++ gdb-symtab-cache-dw2_get_file_names-result-for-dummy.patch ++++++
>From c7e0fde828e5b2d5fb22c11ad4cf0dcfc6de0292 Mon Sep 17 00:00:00 2001
From: Tom de Vries <[email protected]>
Date: Wed, 14 Jan 2026 21:47:05 +0100
Subject: [PATCH 3/4] [gdb/symtab] Cache dw2_get_file_names result for dummy CU

Consider function dw2_get_file_names:
...
static struct quick_file_names *
dw2_get_file_names (dwarf2_per_cu *this_cu, dwarf2_per_objfile *per_objfile)
{
  /* This should never be called for TUs.  */
  gdb_assert (!this_cu->is_debug_types ());

  if (this_cu->files_read)
    return this_cu->file_names;

  cutu_reader reader (*this_cu, *per_objfile, nullptr,
                      per_objfile->get_cu (this_cu), true, language_minimal,
                      nullptr);
  if (!reader.is_dummy ())
    dw2_get_file_names_reader (reader.cu (), reader.top_level_die ());

  return this_cu->file_names;
}
...

If dw2_get_file_names_reader is called, the result is cached in
this_cu->file_names, and this fact is tracked in this_cu->files_read, allowing
subsequent calls to access the cached value.

But for dummy CUs, while the result (nullptr) is cached in
this_cu->file_names, this is not noted in this_cu->files_read, and
consequently subsequent calls will read the top-level DIE in the CU again.

Fix this by setting this_cu->files_read also for dummy CUs.

Tested on x86_64-linux.

Approved-By: Tom Tromey <[email protected]>

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33777
(cherry picked from commit 5a8351167a8b4547d6583a5d713936c1aec39565) master
(cherry picked from commit 0ac91006f95d5b8dd4c1610069628f31b252a175) 
gdb-17-branch
---
 gdb/dwarf2/read.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index f4a1eaf0f53..d6722a01376 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1957,7 +1957,12 @@ dw2_get_file_names (dwarf2_per_cu_data *this_cu,
     return this_cu->file_names;
 
   cutu_reader reader (this_cu, per_objfile);
-  if (!reader.dummy_p)
+  if (reader.dummy_p)
+    {
+      /* Make sure we don't re-read the dummy CU.  */
+      this_cu->files_read = true;
+    }
+  else
     dw2_get_file_names_reader (&reader, reader.comp_unit_die);
 
   return this_cu->file_names;
-- 
2.51.0


++++++ gdb-symtab-fix-slow-symbol-lookup-with-dwz.patch ++++++
>From 8b5dc3da60d6c07991821c447f183288c4aac69e Mon Sep 17 00:00:00 2001
From: Tom de Vries <[email protected]>
Date: Tue, 10 Feb 2026 10:30:59 +0100
Subject: [PATCH] [gdb/symtab] Fix slow symbol lookup with dwz

Consider the following setup on openSUSE Leap 16.0 x86_64:
...
$ sudo zypper install qt6-tools-assistant qt6-tools-assistant-debuginfo \
    libQt6Core6-debuginfo
$ gdb -q \
    -iex "set debuginfod enabled off" \
    -iex "set pagination off" \
    /usr/bin/assistant6 \
    -ex "break BookmarkManager::setupFinished" \
    -ex run
Reading symbols from /usr/bin/assistant6...
Reading symbols from /usr/lib/debug/usr/lib64/qt6/bin/assistant.debug...
   ...
Thread 1 "assistant6" hit Breakpoint 1, BookmarkManager::setupFinished (...)
    at .../bookmarkmanager.cpp:297
297     {
(gdb) maint time 1
(gdb)
...

[ Note that we need packages:
- qt6-tools-assistant for /usr/bin/assistant6
- qt6-tools-assistant-debuginfo to be able to set the breakpoint, and
- libQt6Core6-debuginfo to have debuginfo for shared library
  /lib64/libQt6Core.so.6. ]

This lookup is slow with an -O2 build of gdb-17-branch:
...
(gdb) print *bookmarkWidget
  ...
Command execution time: 17.712828 (cpu), 17.712880 (wall)
(gdb)
...

[ Note that a second lookup takes roughly the same time, so the slowness is
not due to symtab expansion.

Also note that the slowness is gone:
...
Command execution time: 0.091105 (cpu), 0.091100 (wall)
...
if we de-install libQt6Core6-debuginfo. ]

This is PR symtab/33825, originally reported for gdb 16.3 on openSUSE
Tumbleweed x86_64.

With current trunk, we have instead:
...
Command execution time: 0.009536 (cpu), 0.009509 (wall)
...

The slowness is gone at commit ce889924a72 ("Simplify
basic_lookup_transparent_type"), but the commit is part of a patch series of
31 patches, so the commit cannot be trivially backported to gdb-17-branch.

The slowness with the gdb-17-branch is caused by the following.

In basic_lookup_transparent_type_1, we have this bit of code:
...
   for (compunit_symtab *cust : objfile->compunits ())
     {
       bv = cust->blockvector ();
       block = bv->block (block_index);
       sym = block_find_symbol (block, name, flags, nullptr);
...
and via block_find_symbol -> block_iterator_range -> block_iterator_first ->
initialize_block_iterator we get to this code:
...
  compunit_symtab *cu = block->global_block ()->compunit ();

  /* If this is an included symtab, find the canonical includer and
     use it instead.  */
  while (cu->user != NULL)
    cu = cu->user;
...

Say we have an objfile with two cus, CU1 and CU2, where:
- CU1 represents a DWARF compilation unit, and
- CU2 represents a DWARF partial unit imported by CU1.

In symtab terms, CU2 is an "included symtab", and CU1 is its "canonical
includer", so we have:
- CU1->user == nullptr, and
- CU2->user == CU1.

In the for loop shown above, we have subsequently:
- cust == CU1: during block_find_symbol, we visit both CU1 and included symtab
  CU2.
- cust == CU2: during block_find symbol, we walk up from CU2 to its canonical
  includer CU1, and again visit CU1 and included symtab CU2.
So, instead of visiting CU1 and CU2 each once, we visited them twice.

Fix this by skipping included symtabs in the for loop, getting us instead the
faster:
...
Command execution time: 0.293385 (cpu), 0.293386 (wall)
...

The fix can be trivially backported to the gdb-16-branch.

Tested on x86_64-linux, with target boards unix, cc-with-dwz and
cc-with-dwz-m.

Approved-By: Tom Tromey <[email protected]>

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33825
(cherry picked from commit 36356c77b8969b684566c96b01cc97ace6a449bf)
---
 gdb/symtab.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/gdb/symtab.c b/gdb/symtab.c
index 106e540ca48..569fd18e5e4 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -2785,6 +2785,11 @@ basic_lookup_transparent_type_1 (struct objfile *objfile,
 
   for (compunit_symtab *cust : objfile->compunits ())
     {
+      /* Skip included compunits, to avoid searching them and their canonical
+        includers more than once.  */
+      if (cust->user != nullptr)
+       continue;
+
       bv = cust->blockvector ();
       block = bv->block (block_index);
       sym = block_find_symbol (block, name, flags, nullptr);

base-commit: 6da3492819000aa16136905bab03c312b290ab67
-- 
2.51.0


++++++ gdb-symtab-handle-zero-opcode_base-in-line-number-pr.patch ++++++
>From 7f92f322e022082e211bd8f264ec86fbd25a90ec Mon Sep 17 00:00:00 2001
From: Tom de Vries <[email protected]>
Date: Mon, 19 Jan 2026 19:14:11 +0100
Subject: [PATCH 4/4] [gdb/symtab] Handle zero opcode_base in line number
 program header

I build gdb with TSAN, and with test-case gdb.dwarf2/malformed-line-header.exp
ran into a heap-use-after-free:
...
(gdb) info line 1
==================
WARNING: ThreadSanitizer: heap-use-after-free (pid=897504)
  Write of size 1 at 0x72040000d000 by main thread:
    #0 dwarf_decode_line_header() gdb/dwarf2/line-header.c:356 (gdb+0xa0618c)
  ...

  Previous write of size 8 at 0x72040000d000 by main thread:
    #0 operator delete[](void*) <null> (libtsan.so.2+0xa6128)
    #1 std::enable_if<std::is_convertible<unsigned char (*) [], unsigned char 
(*) []>::value, void>::type std::default_delete<unsigned char 
[]>::operator()<unsigned char>(unsigned char*) const 
/usr/include/c++/15/bits/unique_ptr.h:134 (gdb+0xa08479)
    #2 std::unique_ptr<unsigned char [], std::default_delete<unsigned char []> 
>::~unique_ptr() /usr/include/c++/15/bits/unique_ptr.h:685 (gdb+0xa07324)
    #3 line_header::~line_header() gdb/dwarf2/line-header.h:86 (gdb+0xa0914a)
    #4 std::default_delete<line_header>::operator()(line_header*) const 
/usr/include/c++/15/bits/unique_ptr.h:93 (gdb+0xa091a4)
    #5 std::unique_ptr<line_header, std::default_delete<line_header> 
>::~unique_ptr() /usr/include/c++/15/bits/unique_ptr.h:399 (gdb+0xa07f18)
    #6 dw2_get_file_names_reader gdb/dwarf2/read.c:1839 (gdb+0xa648ee)
 ...

  Location is heap block of size 0 at 0x72040000d000 allocated by main thread:
    #0 operator new[](unsigned long) <null> (libtsan.so.2+0xa6b01)
    #1 dwarf_decode_line_header() gdb/dwarf2/line-header.c:354 (gdb+0xa06159)
...

This is caused by allocating a zero-sized array (lh->opcode_base == 0), and
writing to it:
...
  lh->standard_opcode_lengths.reset (new unsigned char[lh->opcode_base]);

  lh->standard_opcode_lengths[0] = 1;  /* This should never be used anyway.  */
...

Fix this by skipping this code if lh->opcode_base == 0.

Tested on x86_64-linux.

Approved-By: Simon Marchi <[email protected]>
---
 gdb/dwarf2/line-header.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/gdb/dwarf2/line-header.c b/gdb/dwarf2/line-header.c
index 0f4407f2fb2..1de709e29f0 100644
--- a/gdb/dwarf2/line-header.c
+++ b/gdb/dwarf2/line-header.c
@@ -352,13 +352,20 @@ dwarf_decode_line_header  (sect_offset sect_off, bool 
is_dwz,
   line_ptr += 1;
   lh->opcode_base = read_1_byte (abfd, line_ptr);
   line_ptr += 1;
-  lh->standard_opcode_lengths.reset (new unsigned char[lh->opcode_base]);
-
-  lh->standard_opcode_lengths[0] = 1;  /* This should never be used anyway.  */
-  for (i = 1; i < lh->opcode_base; ++i)
+  if (lh->opcode_base > 0)
     {
-      lh->standard_opcode_lengths[i] = read_1_byte (abfd, line_ptr);
-      line_ptr += 1;
+      lh->standard_opcode_lengths.reset (new unsigned char[lh->opcode_base]);
+
+      /* The first element should never be used, because there's no standard
+        opcode encoded as 0.  Give it some defined value.  */
+      lh->standard_opcode_lengths[0] = 1;
+
+      /* Read the standard_opcode_lengths array.  */
+      for (i = 1; i < lh->opcode_base; ++i)
+       {
+         lh->standard_opcode_lengths[i] = read_1_byte (abfd, line_ptr);
+         line_ptr += 1;
+       }
     }
 
   if (lh->version >= 5)
-- 
2.51.0


++++++ gdb-tdep-fix-gdb.base-siginfo.exp-on-s390x-linux.patch ++++++
>From 086e925fa1347aecc69eb674cc3a81400e4c27a7 Mon Sep 17 00:00:00 2001
From: Tom de Vries <[email protected]>
Date: Sat, 17 Jan 2026 08:44:57 +0100
Subject: [PATCH 2/4] [gdb/tdep] Fix gdb.base/siginfo.exp on s390x-linux

On s390x-linux (SLES 15 SP5), I'm running into:
...
FAIL: gdb.base/siginfo.exp: backtrace for nexti (pattern 2)
FAIL: gdb.base/siginfo.exp: step out of handler
...

The first FAIL is caused by a failure to unwind:
...
 (gdb) bt^M
 #0  handler (sig=26, info=0x3ffffffe428, context=0x3ffffffe4a8) at \
   gdb.base/siginfo.c:31^M
 Backtrace stopped: Cannot access memory at address 0x1a00000088^M
 (gdb)
...

In contrast, on x86_64-linux I get instead:
...
 (gdb) bt^M
 #0  handler (sig=26, info=0x7fffffffc170, context=0x7fffffffc040) at \
   gdb.base/siginfo.c:31^M
 #1  <signal handler called>^M
 #2  0x0000000000401201 in main () at gdb.base/siginfo.c:67^M
 (gdb)
...

The memory access error is triggered here in s390_sigtramp_frame_unwind_cache:
...
  /* Restore the previous frame's SP.  */
  prev_sp = read_memory_unsigned_integer (
                        info->saved_regs[S390_SP_REGNUM].addr (),
                        word_size, byte_order);
...
while trying to read an "Old-style RT frame" (for syscall sigreturn).

The problem is that we actually have a "New-style RT frame" (for syscall
rt_sigreturn).

[ See linux kernel source file arch/s390/kernel/signal.c for a detailed
explanation of the two. ]

The choice between the two is made earlier in that same function:
...
  /* New-style RT frame:
        retcode + alignment (8 bytes)
        siginfo (128 bytes)
        ucontext (contains sigregs at offset 5 words).  */
  if (next_ra == next_cfa)
    {
      ...
    }

  /* Old-style RT frame and all non-RT frames:
        old signal mask (8 bytes)
        pointer to sigregs.  */
  else
...

I'm not sure why the check gives the wrong result, but I noticed that
s390_sigtramp_frame_sniffer is able to distinguish between the two, so fix
this by:
- factoring out new function s390_sigtramp_p out of
  s390_sigtramp_frame_sniffer, and
- using s390_sigtramp_p in s390_sigtramp_frame_unwind_cache to distinguish
  between the "Old-style RT frame" and "New-style RT frame".

This fixes the backtrace.

The second failure is:
...
(gdb) step^M
32      } /* handler */^M
1: x/i $pc^M
=> 0x1000772 <handler+50>:      nopr^M
(gdb) step^M
0x000003fffdffe490 in __kernel_rt_sigreturn ()^M
1: x/i $pc^M
=> 0x3fffdffe490 <__kernel_rt_sigreturn>:       svc     173^M
(gdb) FAIL: gdb.base/siginfo.exp: step out of handler
...

There is some code in process_event_stop_test that is supposed to trigger:
...
  if (ecs->event_thread->control.step_range_end != 1
      && (ecs->event_thread->control.step_over_calls == STEP_OVER_UNDEBUGGABLE
          || ecs->event_thread->control.step_over_calls == STEP_OVER_ALL)
      && get_frame_type (frame) == SIGTRAMP_FRAME)
    {
      infrun_debug_printf ("stepped into signal trampoline");
      /* The inferior, while doing a "step" or "next", has ended up in
         a signal trampoline (either by a signal being delivered or by
         the signal handler returning).  Just single-step until the
         inferior leaves the trampoline (either by calling the handler
         or returning).  */
      keep_going (ecs);
      return;
    }
...
but it doesn't because frame is a NORMAL_FRAME instead of a SIGTRAMP_FRAME.

This is caused by the "dwarf2" unwinder triggering, which has higher priority
than the "s390 linux sigtramp" unwinder:
...
(gdb) maint info frame-unwinders
Name                        Type                      Class     Enabled
dummy                       DUMMY_FRAME               GDB       Y
dwarf2 tailcall             TAILCALL_FRAME            DEBUGINFO Y
inline                      INLINE_FRAME              GDB       Y
jit                         NORMAL_FRAME              EXTENSION Y
python                      NORMAL_FRAME              EXTENSION Y
dwarf2                      NORMAL_FRAME              DEBUGINFO Y
dwarf2 signal               SIGTRAMP_FRAME            DEBUGINFO Y
s390 linux sigtramp         SIGTRAMP_FRAME            ARCH      Y
s390 stub                   NORMAL_FRAME              ARCH      Y
s390 prologue               NORMAL_FRAME              ARCH      Y
...

I found some code in dwarf2_frame_sniffer:
...
  /* On some targets, signal trampolines may have unwind information.
     We need to recognize them so that we set the frame type
     correctly.  */

  if (fde->cie->signal_frame
      || dwarf2_frame_signal_frame_p (get_frame_arch (this_frame),
                                      this_frame))
    return self->type () == SIGTRAMP_FRAME;
...
and an example implementation i386_linux_dwarf_signal_frame_p, and after
copying this approach, indeed the stepping failure was fixed, but the
backtrace broken again.

Instead, fix this by giving the "s390 linux sigtramp" unwinder a higher
priority:
...
(gdb) maint info frame-unwinders
Name                        Type                      Class     Enabled
dummy                       DUMMY_FRAME               GDB       Y
dwarf2 tailcall             TAILCALL_FRAME            DEBUGINFO Y
inline                      INLINE_FRAME              GDB       Y
jit                         NORMAL_FRAME              EXTENSION Y
python                      NORMAL_FRAME              EXTENSION Y
s390 linux sigtramp         SIGTRAMP_FRAME            ARCH      Y
dwarf2                      NORMAL_FRAME              DEBUGINFO Y
dwarf2 signal               SIGTRAMP_FRAME            DEBUGINFO Y
s390 stub                   NORMAL_FRAME              ARCH      Y
s390 prologue               NORMAL_FRAME              ARCH      Y
...

Also fixes test-case gdb.base/sigaltstack.exp and gdb.base/sigbpt.exp.

Tested on s390x-linux.

Reviewed-By: Keith Seitz <[email protected]>

PR tdep/33708
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33708
---
 gdb/s390-linux-tdep.c | 50 +++++++++++++++++++++++++++----------------
 1 file changed, 32 insertions(+), 18 deletions(-)

diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c
index bc1db550d2e..90f51a47336 100644
--- a/gdb/s390-linux-tdep.c
+++ b/gdb/s390-linux-tdep.c
@@ -382,6 +382,30 @@ struct s390_sigtramp_unwind_cache {
   trad_frame_saved_reg *saved_regs;
 };
 
+/* Return true if the frame pc of THIS_FRAME points to either
+   __kernel_rt_sigreturn or __kernel_sigreturn.  Return the corresponding
+   syscall number in SYSCALL_NR.  */
+
+static bool
+s390_sigtramp_p (const frame_info_ptr &this_frame, int *syscall_nr_ptr)
+{
+  CORE_ADDR pc = get_frame_pc (this_frame);
+  bfd_byte sigreturn[2];
+
+  if (target_read_memory (pc, sigreturn, 2))
+    return false;
+
+  if (sigreturn[0] != op_svc)
+    return false;
+
+  int syscall_nr = sigreturn[1];
+  if (syscall_nr_ptr != nullptr)
+    *syscall_nr_ptr = syscall_nr;
+
+  return (syscall_nr == 119 /* sigreturn */
+         || syscall_nr == 173 /* rt_sigreturn */);
+}
+
 /* Unwind THIS_FRAME and return the corresponding unwind cache for
    s390_sigtramp_frame_unwind.  */
 
@@ -395,7 +419,7 @@ s390_sigtramp_frame_unwind_cache (const frame_info_ptr 
&this_frame,
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   struct s390_sigtramp_unwind_cache *info;
   ULONGEST this_sp, prev_sp;
-  CORE_ADDR next_ra, next_cfa, sigreg_ptr, sigreg_high_off;
+  CORE_ADDR next_cfa, sigreg_ptr, sigreg_high_off;
   int i;
 
   if (*this_prologue_cache)
@@ -406,14 +430,17 @@ s390_sigtramp_frame_unwind_cache (const frame_info_ptr 
&this_frame,
   info->saved_regs = trad_frame_alloc_saved_regs (this_frame);
 
   this_sp = get_frame_register_unsigned (this_frame, S390_SP_REGNUM);
-  next_ra = get_frame_pc (this_frame);
   next_cfa = this_sp + 16*word_size + 32;
 
+  int syscall_nr;
+  bool res = s390_sigtramp_p (this_frame, &syscall_nr);
+  gdb_assert (res);
+
   /* New-style RT frame:
        retcode + alignment (8 bytes)
        siginfo (128 bytes)
        ucontext (contains sigregs at offset 5 words).  */
-  if (next_ra == next_cfa)
+  if (syscall_nr == 173 /* rt_sigreturn */)
     {
       sigreg_ptr = next_cfa + 8 + 128 + align_up (5*word_size, 8);
       /* sigregs are followed by uc_sigmask (8 bytes), then by the
@@ -523,20 +550,7 @@ s390_sigtramp_frame_sniffer (const struct frame_unwind 
*self,
                             const frame_info_ptr &this_frame,
                             void **this_prologue_cache)
 {
-  CORE_ADDR pc = get_frame_pc (this_frame);
-  bfd_byte sigreturn[2];
-
-  if (target_read_memory (pc, sigreturn, 2))
-    return 0;
-
-  if (sigreturn[0] != op_svc)
-    return 0;
-
-  if (sigreturn[1] != 119 /* sigreturn */
-      && sigreturn[1] != 173 /* rt_sigreturn */)
-    return 0;
-
-  return 1;
+  return s390_sigtramp_p (this_frame, nullptr) ? 1 : 0;
 }
 
 /* S390 sigtramp frame unwinder.  */
@@ -1145,7 +1159,7 @@ s390_linux_init_abi_any (struct gdbarch_info info, struct 
gdbarch *gdbarch)
   set_gdbarch_get_syscall_number (gdbarch, s390_linux_get_syscall_number);
 
   /* Frame handling.  */
-  frame_unwind_append_unwinder (gdbarch, &s390_sigtramp_frame_unwind);
+  frame_unwind_prepend_unwinder (gdbarch, &s390_sigtramp_frame_unwind);
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
 
   /* Enable TLS support.  */
-- 
2.51.0


++++++ gdb-test-for-misplaced-symtab-causing-file-not-found.patch ++++++
++++ 1067 lines (skipped)

++++++ gdb-testsuite-add-missing-require-in-gdb.debuginfod-.patch ++++++
>From f7147942b6b9e9bc0736564952e1cb503a9f561e Mon Sep 17 00:00:00 2001
From: Tom de Vries <[email protected]>
Date: Thu, 8 Jan 2026 08:16:14 +0100
Subject: [PATCH 1/4] [gdb/testsuite] Add missing require in
 gdb.debuginfod/solib-with-dwz.exp

Add missing "require allow_debuginfod_tests" in test-case
gdb.debuginfod/solib-with-dwz.exp.
---
 gdb/testsuite/gdb.debuginfod/solib-with-dwz.exp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gdb/testsuite/gdb.debuginfod/solib-with-dwz.exp 
b/gdb/testsuite/gdb.debuginfod/solib-with-dwz.exp
index e26595420c5..de44aa063ed 100644
--- a/gdb/testsuite/gdb.debuginfod/solib-with-dwz.exp
+++ b/gdb/testsuite/gdb.debuginfod/solib-with-dwz.exp
@@ -81,6 +81,7 @@
 
 load_lib debuginfod-support.exp
 
+require allow_debuginfod_tests
 require allow_shlib_tests
 require {istarget "*-linux*"}
 require {!is_remote host}

base-commit: 7f92f322e022082e211bd8f264ec86fbd25a90ec
-- 
2.51.0


++++++ gdb-testsuite-fix-another-timeout-in-gdb.mi-mi-multi.patch ++++++
>From 6da3492819000aa16136905bab03c312b290ab67 Mon Sep 17 00:00:00 2001
From: Tom de Vries <[email protected]>
Date: Tue, 16 Dec 2025 10:31:33 +0100
Subject: [PATCH] [gdb/testsuite] Fix another timeout in
 gdb.mi/mi-multi-commands.exp

On aarch64-linux, with a gdb version 16.3 based package, I ran into (edited
for readability):
...
(gdb)
<LOTS-OF-SPACES>-data-evaluate-expression $a
^done,value="\"FIRST COMMAND\""
(gdb) -data-evaluate-expression $b

^done,value="\"TEST COMPLETE\""
(gdb)
PASS: $exp: look for first command output, command length $n
FAIL: $exp: look for second command output, command length $n (timeout)
...

For contrast, a passing example looks like:
...
(gdb)
<LOTS-OF-SPACES>-data-evaluate-expression $a
-data-evaluate-expression $b
^done,value="\"FIRST COMMAND\""
(gdb)
PASS: $exp: look for first command output, command length $n
^done,value="\"TEST COMPLETE\""
(gdb)
PASS: $exp: look for second command output, command length $n
...

The setup is that the test-case issues these two commands at once:
...
-data-evaluate-expression $a
-data-evaluate-expression $b
...
where the length of the first command is artificially increased by prefixing
it with spaces, show as <LOTS-OF-SPACES> above.

What happens is that gdb, after parsing the first command, executes it, which
generates output and a prompt.  Then that prompt intermixes with the echoing
of the second command, and consequently the matching of the prompt fails.

This is very similar to what was fixed in commit 59c9bc5fb6c ("[gdb/testsuite]
Fix timeout in gdb.mi/mi-multi-commands.exp").

Fix this by making the matching of the first prompt optional.

While we're at it, make the test-case more readable using {}, string_to_regexp
and multi_line_input.

PR testsuite/33671
Bug https://sourceware.org/bugzilla/show_bug.cgi?id=33671
---
 gdb/testsuite/gdb.mi/mi-multi-commands.exp | 59 +++++++++++-----------
 1 file changed, 29 insertions(+), 30 deletions(-)

diff --git a/gdb/testsuite/gdb.mi/mi-multi-commands.exp 
b/gdb/testsuite/gdb.mi/mi-multi-commands.exp
index 028e187366a..f5f86059288 100644
--- a/gdb/testsuite/gdb.mi/mi-multi-commands.exp
+++ b/gdb/testsuite/gdb.mi/mi-multi-commands.exp
@@ -45,15 +45,15 @@ proc run_test { args } {
     set start 1
     set limit 2049
 
-    mi_gdb_test "set \$a = \"FIRST COMMAND\"" ".*"
-    mi_gdb_test "set \$b = \"TEST COMPLETE\"" ".*"
+    mi_gdb_test {set $a = "FIRST COMMAND"} ".*"
+    mi_gdb_test {set $b = "TEST COMPLETE"} ".*"
 
     for { set i $start } { $i < $limit } { incr i } {
 
        set cmd ""
 
        # Create a command that is at least `i` characters long.
-       set first_cmd "-data-evaluate-expression \$a"
+       set first_cmd {-data-evaluate-expression $a}
        while { [string length $first_cmd] < $i } {
            set first_cmd " $first_cmd"
        }
@@ -68,7 +68,10 @@ proc run_test { args } {
        set i [string length $first_cmd]
        verbose -log "length of first command is $i"
 
-       set cmd "${first_cmd}\n-data-evaluate-expression \$b\n"
+       set cmd \
+           [multi_line_input \
+                $first_cmd \
+                {-data-evaluate-expression $b}]
 
        # We need to call send_gdb ourselves here as gdb_test_multiple
        # will try to send each line of the command separately (breaking
@@ -76,44 +79,40 @@ proc run_test { args } {
        # than likely mean that gdb will see and process the first command
        # before the second command arrives, this prevents the bug from
        # triggering.
-       send_gdb "$cmd"
+       send_gdb "$cmd\n"
 
        # Now check for output from the two commands.  We do this
-       # using two calls to gdb_test_multiple, this is because the
+       # using one call to gdb_test_multiple, this is because the
        # echoing of the second command can sometime get mixed
-       # unexpectedly with the command output, this is especially
-       # likely when running using the read1 technique.
-       #
-       # When using a single gdb_test_multiple we need to anchor
-       # patterns using a ^, however, this requires us to consume and
-       # discard all lines that are not part of the output that we're
-       # looking for.  However, due to the unpredictable
-       # intermingling, it's much easier if we drop the ^ anchor.
-       # However, with this gone dejagnu would sometimes match the
-       # second comand output before the first commands output.
-       #
-       # This approach just looks for the first command output, then,
-       # once that has been found, we start looking for the second
-       # command output, this seems pretty reliable.
+       # unexpectedly with the command output, or the prompt.  This is
+       # especially likely when running using the read1 technique.
+
+       # We may or may not recognize the prompt after the first command.  If
+       # so, accept it to prevent the default clause from triggering, and
+       # continue.
+
+       set re_first_message {\^done.*,value="\\\"FIRST COMMAND\\\""}
+       set re_second_message [string_to_regexp {^done,value="\"TEST 
COMPLETE\""}]
        set seen_first_message false
        set seen_second_message false
-
-       gdb_test_multiple "" "look for first command output, command length $i" 
-prompt "$mi_gdb_prompt" {
-           -re "\\^done.*,value=\"\\\\\"FIRST COMMAND\\\\\"\"" {
+       set test "look for command output, command length $i"
+       gdb_test_multiple "" $test -prompt "$mi_gdb_prompt" {
+           -re $re_first_message {
                set seen_first_message true
                exp_continue
            }
+           -re "$re_second_message\r\n$mi_gdb_prompt" {
+               set seen_second_message true
+           }
            -re "$mi_gdb_prompt" {
-               gdb_assert $seen_first_message $gdb_test_name
+               exp_continue
            }
        }
 
-       gdb_test_multiple "" "look for second command output, command length 
$i" -prompt "$mi_gdb_prompt" {
-           -re "\\^done,value=\"\\\\\"TEST COMPLETE\\\\\"\"\r\n$mi_gdb_prompt" 
{
-               pass $gdb_test_name
-               set seen_second_message true
-           }
-       }
+       gdb_assert $seen_first_message \
+           "look for first command output, command length $i"
+       gdb_assert $seen_second_message \
+           "look for second command output, command length $i"
 
        # If one of the above tests failed then lets no waste our time
        # checking different command lengths.  The actual bug this

base-commit: 58257123680969c03a46d7e877e6a7143bd134c5
-- 
2.51.0


++++++ gdb-testsuite-launch-debuginfod-without-vvvv.patch ++++++
>From ad06ed5638c51ca0213d327b6e685455c67975be Mon Sep 17 00:00:00 2001
From: Tom de Vries <[email protected]>
Date: Thu, 12 Feb 2026 15:42:19 +0100
Subject: [PATCH] [gdb/testsuite] Launch debuginfod without -vvvv

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33901
---
 gdb/testsuite/lib/debuginfod-support.exp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gdb/testsuite/lib/debuginfod-support.exp 
b/gdb/testsuite/lib/debuginfod-support.exp
index 0096448567e..93c724a7b05 100644
--- a/gdb/testsuite/lib/debuginfod-support.exp
+++ b/gdb/testsuite/lib/debuginfod-support.exp
@@ -127,7 +127,7 @@ proc start_debuginfod { db debugdir } {
            set old_spawn_id $spawn_id
        }
 
-       spawn debuginfod -vvvv -d $db -p $port -F $debugdir
+       spawn debuginfod -d $db -p $port -F $debugdir
        set debuginfod_spawn_id $spawn_id
 
        if { [info exists old_spawn_id] } {

base-commit: a7a70544ba0f74633d4473955018fa8277382812
-- 
2.51.0


++++++ gdb-testsuite-remove-guile-test-byte-at-sp-before-fl.patch ++++++
>From d74f40d50f2f10f1d211339c2dd46e91b1a59eb7 Mon Sep 17 00:00:00 2001
From: Simon Marchi <[email protected]>
Date: Thu, 8 Jan 2026 14:51:54 -0500
Subject: [PATCH 3/4] gdb/testsuite: remove guile "test byte at sp, before
 flush" test
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

When I run:

    $ while make check TESTS="gdb.guile/scm-ports.exp" 
RUNTESTFLAGS="--target_board=native-extended-gdbserver"; do done

I eventually get:

    FAIL: gdb.guile/scm-ports.exp: buffered=1: test byte at sp, before flush

I don't know why I only see this (or see this more often) with the
native-extended-gdbserver board, I guess because it changes the timing
of things.  Also, this is with a debug/ASan/UBSan build of GDB, if that
matters.  This is with guile 3.0.

This is what the test attempts to do:

 1. create a rw memory port that is supposed to be buffered
 2. write the byte at $sp with a new value, expecting that byte to only
    be in the port's buffer
 3. read the memory at $sp (using parse-and-eval, bypassing the rw
    memory port), expecting to see the old byte value
 4. flush the memory port, expecting that to write to new byte value at
    $sp
 5. read the memory at $sp (using parse-and-eval again), expecting to
    see the new value

It is step 3 that fails.  My hypothesis is that even if the memory port
we write to is buffered, the write to the underlying memory can happen
before the "before flush" test happens.  The Guile Buffering doc [1]
says this:

    If you write data to a buffered port, it probably doesn’t go out to
    the mutable store directly. (This “probably” introduces some
    indeterminism in your program: what goes to the store, and when,
    depends on how full the buffer is. It is something that the user
    needs to explicitly be aware of.) The data is written to the store
    later – when the buffer fills up due to another write, or when
    force-output is called, or when close-port is called, or when the
    program exits, or even when the garbage collector runs.

Because of the mention of the garbage collector, I tried putting some
calls to gc-disable and gc-enable around that area, but it doesn't fix
it.

Given that the flushing behavior of the buffered port seems
non-deterministic, I think that the buffering behavior can't easily be
tested.  I propose to get rid of that specific aspect of the test.

As suggested by Tom de Vries, replace the "test byte at sp, before
flush" test with a "test byte at sp, before write" one.  I think this is
useful as a sanity check to help prove that the memory write did in fact
change the state of the program.

Change-Id: I2f0afd7b2ebb7738e675f58397677f2f9a4e06bb
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29825
Reviewed-By: Thiago Jung Bauermann <[email protected]>
---
 gdb/testsuite/gdb.guile/scm-ports.exp | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/gdb/testsuite/gdb.guile/scm-ports.exp 
b/gdb/testsuite/gdb.guile/scm-ports.exp
index 2f186dddbc9..f06b0e6c6a8 100644
--- a/gdb/testsuite/gdb.guile/scm-ports.exp
+++ b/gdb/testsuite/gdb.guile/scm-ports.exp
@@ -113,20 +113,25 @@ proc test_mem_port_rw { buffered } {
        "define old-value"
     gdb_test_no_output "guile (define new-value (logxor old-value 1))" \
        "define new-value"
+
+    # Sanity check before the write.
+    gdb_test "guile (print (value=? (parse-and-eval \"*(char*) \$sp\") 
byte-at-sp))" \
+       "= #t" \
+       "test byte at sp, before write"
+
+    # Write new byte at *SP.
     gdb_test "guile (print (put-bytevector rw-mem-port (make-bytevector 1 
new-value)))" \
        "= #<unspecified>"
     if $buffered {
-       # Value shouldn't be in memory yet.
-       gdb_test "guile (print (value=? (parse-and-eval \"*(char*) \$sp\") 
byte-at-sp))" \
-           "= #t" \
-           "test byte at sp, before flush"
        gdb_test_no_output "guile (force-output rw-mem-port)" \
            "flush port"
     }
+
     # Value should be in memory now.
     gdb_test "guile (print (value=? (parse-and-eval \"*(char*) \$sp\") 
byte-at-sp))" \
        "= #f" \
-       "test byte at sp, after flush"
+       "test byte at sp, after write"
+
     # Restore the value for cleanliness sake, and to verify close-port
     # flushes the buffer.
     gdb_test "guile (print (seek rw-mem-port (value->integer sp-reg) 
SEEK_SET))" \
-- 
2.51.0

Reply via email to