- Rebase to 14.2 release (fedora rawhide @ 779f05e).

* Replace gdb-13.2.tar.bz2 with gdb-14.2.tar.bz2.
- Maintenance script import-fedora.sh:
  * Drop patch skips:
    * gdb-6.5-BEA-testsuite.patch
- Maintenance script qa-local.sh:
  * Drop SLE-11.  GDB 14.2 requires MPFR, and the SLE-11 version
    (2.3.2) is older than required (3.1.0+).
  * Add ALP.
  * Update version to 14.2.
- Maintenance script qa.sh:
  * Add PR30480, PR31440, PR31806 kfail.
  * Add PR31810, PR31809, PR31811 kfail.
  * Expand gdb.base/rtld-step.exp kfail.
  * Add gdb.threads/thread-specific-bp.exp kfail.
- Fedora patches updated:
  * gdb-6.3-gstack-20050411.patch
  * gdb-6.5-bz185337-resolve-tls-without-debuginfo-v2.patch
  * gdb-6.6-buildid-locate-rpm.patch
  * gdb-6.6-buildid-locate-solib-missing-ids.patch
  * gdb-6.6-buildid-locate.patch
  * gdb-6.6-testsuite-timeouts.patch
  * gdb-core-open-vdso-warning.patch
  * gdb-fedora-libncursesw.patch
  * gdb-linux_perf-bundle.patch
  * gdb-rhbz-2232086-cpp-ify-mapped-symtab.patch
  * gdb-rhbz-2232086-generate-dwarf-5-index-consistently.patch
  * gdb-rhbz-2232086-generate-gdb-index-consistently.patch
- Fedora patches removed:
  * gdb-binutils29988-read_indexed_address.patch
  * gdb-bz2196395-debuginfod-legacy-openssl-crash.patch
  * gdb-bz2237392-dwarf-obstack-allocation.patch
  * gdb-bz2237515-debuginfod-double-free.patch
  * gdb-rhbz1773651-gdb-index-internal-error.patch
  * gdb-rhbz2160211-excessive-core-file-warnings.patch
  * gdb-rhbz2192105-ftbs-dangling-pointer
  * gdb-rhbz2233961-CVE-2022-4806.patch
  * gdb-rhbz2233965-memory-leak.patch
- Fedora patches added:
  *  gdb-ftbs-swapped-calloc-args.patch
  *  gdb-rhbz2250652-avoid-PyOS_ReadlineTState.patch
  *  gdb-rhbz2250652-gdbpy_gil.patch
  *  gdb-rhbz2261580-intrusive_list-assertion-fix.patch
- Fedora fixup patches added:
  * fixup-skip-tests.patch
- Fedora fixup patches updated:  
  * fixup-gdb-linux_perf-bundle.patch
- Patches updated:
  * gdb-symtab-work-around-pr-gas-29517.patch
  * gdb-symtab-work-around-gas-pr28629.patch
  * gdb-testsuite-ada-pie.patch
  * gdb-python-finishbreakpoint-update.patch
  * gdb-testsuite-prevent-compilation-fails-with-unix-fpie-pie.patch
  * gdb-fix-segfault-in-for_each_block-part-1.patch
  * gdb-fix-segfault-in-for_each_block-part-2.patch
  * gdb-symtab-don-t-defer-backward-refs-inter-cu-intra-.patch
  * gdb-symtab-factor-out-m_deferred_entries-usage.patch
  * gdb-symtab-factor-out-m_die_range_map-usage.patch
  * gdb-symtab-fix-dw_tag_inlined_subroutine-entries-in-.patch
  * gdb-symtab-handle-nullptr-parent-in-parent_map-set_p.patch
  * gdb-symtab-keep-track-of-all-parents-for-cooked-inde.patch
  * gdb-symtab-keep-track-of-processed-dies-in-shard.patch
  * gdb-symtab-recurse-into-c-dw_tag_subprogram-dies-for.patch
  * gdb-symtab-refactor-condition-in-scan_attributes.patch
  * gdb-symtab-resolve-deferred-entries-inter-shard-case.patch
  * gdb-symtab-resolve-deferred-entries-intra-shard-case.patch
- Patches added:
  * gdb-symtab-work-around-pr-gas-29517-dwarf2-case.patch
  * fix-the-gdb.ada-inline-section-gc.exp-test.patch
  * gdb-testsuite-handle-pac-marker.patch
  * change-gdb.base-examine-backwards.exp-for-aix.patch
  * gdb-testsuite-fix-spurious-fails-with-examine-backwa.patch
  * gdb-testsuite-make-gdb.base-solib-search.exp-more-ro.patch
  * gdb-testsuite-fix-regexp-in-vgdb_start.patch
  * powerpc-and-aarch64-fix-reverse-stepping-failure.patch
  * gdb-tdep-fix-gdb.base-watch-bitfields.exp-on-aarch64.patch
  * gdb-tdep-fix-gdb.base-watchpoint-unaligned.exp-on-aa.patch
  * gdb-testsuite-add-pr-gdb-26967-kfail-in-two-more-tes.patch
  * gdb-testsuite-fix-gdb.base-eh_return.exp.patch
  * fixup-powerpc-and-aarch64-fix-reverse-stepping-failu.patch
  * gdb-exp-fix-printing-of-out-of-bounds-struct-members.patch
  * gdb-fix-heap-use-after-free-in-select_event_lwp.patch
  * fix-regression-on-aarch64-linux-gdbserver.patch
  * gdb-testsuite-factor-out-proc-get_portnum.patch
  * gdb-testsuite-make-portnum-a-persistent-global.patch
  * gdb-testsuite-factor-out-proc-with_lock.patch
  * gdb-testsuite-factor-out-proc-lock_dir.patch
  * gdb-testsuite-move-gpu-parallel.lock-to-cache-dir.patch
  * gdb-testsuite-use-unique-portnum-in-parallel-testing.patch
  * gdb-testsuite-use-unique-portnum-in-parallel-testing-check-slash-slash-case.patch
  * gdb-tdep-fix-reverse-execution-of-ldr-immediate-t4.patch
  * gdb-exp-fix-cast-handling-for-indirection.patch
  * gdb-remote-fix-abort-on-remote_close_error.patch
  * gdb-testsuite-use-find_gnatmake-instead-of-gdb_find_.patch
  * gdb-testsuite-simplify-gdb.server-server-kill-python.patch
  * gdb-testsuite-fix-gdbserver-pid-in-gdb.server-server.patch
  * gdb-testsuite-add-missing-include-in-gdb.base-ctf-pt.patch
  * gdb-testsuite-fix-gdb.ada-verylong.exp-on-32-bit-tar.patch
  * gdb-testsuite-add-missing-includes-in-gdb.trace-coll.patch
  * gdb-testsuite-fix-missing-return-type-in-gdb.linespe.patch
  * gdb-testsuite-fix-gdb.base-ending-run.exp-on-manjaro.patch
  * gdb-testsuite-fix-test-case-gdb.threads-attach-stopp.patch
  * gdb-testsuite-add-missing-include-in-gdb.base-rtld-s.patch
  * gdb-testsuite-fix-valgrind-tests-on-debian.patch
  * gdb-testsuite-fix-gdb.server-server-connect.exp-for-.patch
  * gdb-testsuite-handle-core-without-build-id-in-gdb.ba.patch
  * gdb-testsuite-fix-gdb.base-list-no-debug.exp-on-debi.patch
  * gdb-testsuite-reset-errcnt-and-warncnt-in-default_gd.patch
  * gdb-testsuite-fix-test-in-gdb.python-py-finish-break.patch
  * gdb-testsuite-further-handle-long-filenames-in-gdb.b.patch
  * gdb-testsuite-fix-license-text-in-gdb.reverse-map-to.patch
  * gdb-testsuite-call-ldd-version-in-gdb.testsuite-dump.patch
  * gdb-testsuite-fix-gdb.mi-mi-dprintf.exp-with-read1.patch
  * gdb-testsuite-fix-gdb.cp-namespace.exp-with-read1.patch
  * gdb-testsuite-fix-typo-in-gdb.base-catch-syscall.exp.patch
  * gdb-testsuite-use-more-progbits-for-arm.patch
  * gdb-testsuite-fix-gdb.dwarf2-dw2-gas-workaround.exp.patch
  * gdb-testsuite-add-gdb.dwarf2-backward-spec-inter-cu..patch
  * gdb-testsuite-add-gdb.dwarf2-forward-spec-inter-cu.e.patch
  * gdb-symtab-workaround-pr-gas-31115.patch
  * gdb-arm-remove-tpidruro-register-from-non-freebsd-ta.patch
  * gdb-tdep-fix-catching-syscall-execve-exit-for-arm.patch
  * gdb-arm-fix-epilogue-frame-id.patch
  * gdb-linux-delete-all-other-lwps-immediately-on-ptrac.patch
  * add-maint-info-linux-lwps-command.patch
  * fix-gdb.threads-threads-after-exec.exp-race.patch
  * rs6000-unwind-on-each-instruction-fix.patch
  * gdb-python-make-gdb.unwindinfo.add_saved_register-mo.patch
  * gdb-arm-remove-thumb-bit-in-arm_adjust_breakpoint_ad.patch
  * gdb-testsuite-fix-error-in-gdb.server-server-kill-py.patch
- Patches dropped:
  * remove-some-unnecessary-includes-from-exp.y.patch
  * gdb-testsuite-fix-gdb.gdb-python-helper.exp-with-o2-.patch
  * gdb-testsuite-simplify-gdb.base-unwind-on-each-insn..patch
  * gdb-testsuite-handle-output-after-prompt-in-gdb.thre.patch
  * gdb-testsuite-add-xfail-in-gdb.arch-i386-pkru.exp.patch
  * gdb-testsuite-factor-out-proc-linux_kernel_version.patch
  * gdb-testsuite-add-xfail-in-gdb.python-py-record-btra.patch
  * gdb-testsuite-fix-gdb.threads-schedlock.exp-on-fast-.patch
  * gdb-testsuite-simplify-gdb.arch-amd64-disp-step-avx..patch
  * gdb-testsuite-fix-gdb.threads-schedlock.exp-for-gcc-.patch
  * gdb-testsuite-add-xfail-case-in-gdb.python-py-record.patch
  * aarch64-avoid-initializers-for-vlas.patch
  * gdb-tdep-aarch64-fix-frame-address-of-last-insn.patch
  * fix-pr30369-regression-on-aarch64-arm-pr30506.patch
  * gdb-testsuite-fix-breakpoint-regexp-in-gdb.ada-out_o.patch
  * gdb-testsuite-relax-breakpoint-count-check-in-gdb.py.patch
  * gdb-testsuite-fix-buffer-overflow-in-gdb.base-signed.patch
  * gdb-testsuite-require-syscall-time-in-gdb.reverse-ti.patch
  * gdb-testsuite-handle-missing-gdc-in-gdb.dlang-dlang-.patch
  * gdb-testsuite-add-basic-lmap-for-tcl-8.6.patch
  * gdb-testsuite-fix-gdb.rust-watch.exp-on-ppc64le.patch
  * gdb-testsuite-fix-gdb.python-py-breakpoint.exp-timeo.patch
  * powerpc-fix-for-gdb.reverse-finish-precsave.exp-and-.patch
  * powerpc-regression-fix-for-reverse-finish-command.patch
  * gdb-testsuite-don-t-use-string-cat-in-gdb.dwarf2-dw2.patch
  * move-step_until-procedure.patch
  * gdb-testsuite-fix-gdb.arch-i386-signal.exp-on-x86_64.patch
  * gdb-testsuite-fix-regexps-in-gdb.base-step-over-sysc.patch
  * gdb-testsuite-add-kfail-for-pr-ada-30908.patch
  * gdb-testsuite-fix-gdb.ada-mi_task_arg.exp-with-newer.patch
  * gdb-testsuite-fix-gdb.cp-m-static.exp-regression-on-.patch
  * gdb-symtab-fix-line-number-of-static-const-class-mem.patch
  * gdb-symtab-handle-pu-in-iterate_over_some_symtabs.patch
  * gdb-testsuite-fix-gdb.dwarf2-nullptr_t.exp-with-cc-w.patch
  * gdb-symtab-fix-too-many-symbols-in-gdbpy_lookup_stat.patch
  * gdb-support-rseq-auxvs.patch
  * gdb-testsuite-add-xfail-for-gdb-29965-in-gdb.threads.patch
  * gdb-cli-handle-pending-c-after-rl_callback_read_char.patch
  * gdb-testsuite-add-have_host_locale.patch
  * gdb-symtab-find-main-language-without-symtab-expansi.patch
  * gdb-symtab-don-t-deduplicate-variables-in-gdb-index.patch
  * xcoffread.c-fix-werror-dangling-pointer-issue-with-m.patch
  * avoid-manual-memory-management-in-go-lang.c.patch
  * gdb-go-handle-v3-go_0-mangled-prefix.patch
  * gdb-symtab-handle-self-reference-die.patch
  * gdb-symtab-handle-self-reference-in-inherit_abstract.patch
  * gdb-symtab-add-optimized-out-static-var-to-cooked-in.patch
  * gdb-testsuite-fix-gdb.python-py-breakpoint.exp-with-.patch
  * gdb-tui-fix-segfault-in-tui_find_disassembly_address.patch
  * gdb-testsuite-add-wait_for_msg-arg-to-term-resize-fi.patch
  * gdb-testsuite-fix-gdb-server-ext-run-exp-for-obs.patch  
  * gdb-testsuite-work-around-skip_prologue-problems-in-gdb.threads-process-dies-while-detaching.exp.patch

OBS-URL: https://build.opensuse.org/package/show/devel:gcc/gdb?expand=0&rev=386
This commit is contained in:
Tom de Vries 2024-05-30 21:00:48 +00:00 committed by Git OBS Bridge
parent 9bf31d3011
commit 8c12ed3178
168 changed files with 9658 additions and 7056 deletions

View File

@ -1,50 +0,0 @@
From 0f363ed540fef466f45eab4570c23853e1f14898 Mon Sep 17 00:00:00 2001
From: Roland McGrath <mcgrathr@google.com>
Date: Thu, 9 Feb 2023 10:47:17 -0800
Subject: [PATCH] [aarch64] Avoid initializers for VLAs
Clang doesn't accept initializer syntax for variable-length
arrays in C. Just use memset instead.
---
gdb/aarch64-linux-nat.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
index e4158236db2..ecb2eeb9540 100644
--- a/gdb/aarch64-linux-nat.c
+++ b/gdb/aarch64-linux-nat.c
@@ -56,6 +56,8 @@
#include "nat/aarch64-mte-linux-ptrace.h"
+#include <string.h>
+
#ifndef TRAP_HWBKPT
#define TRAP_HWBKPT 0x0004
#endif
@@ -445,7 +447,9 @@ fetch_tlsregs_from_thread (struct regcache *regcache)
gdb_assert (regno != -1);
gdb_assert (tdep->tls_register_count > 0);
- uint64_t tpidrs[tdep->tls_register_count] = { 0 };
+ uint64_t tpidrs[tdep->tls_register_count];
+ memset(tpidrs, 0, sizeof(tpidrs));
+
struct iovec iovec;
iovec.iov_base = tpidrs;
iovec.iov_len = sizeof (tpidrs);
@@ -471,7 +475,8 @@ store_tlsregs_to_thread (struct regcache *regcache)
gdb_assert (regno != -1);
gdb_assert (tdep->tls_register_count > 0);
- uint64_t tpidrs[tdep->tls_register_count] = { 0 };
+ uint64_t tpidrs[tdep->tls_register_count];
+ memset(tpidrs, 0, sizeof(tpidrs));
for (int i = 0; i < tdep->tls_register_count; i++)
{
base-commit: a39101060cdf2ee239833106fb3bdf9585f858aa
--
2.35.3

View File

@ -0,0 +1,108 @@
From ab0396671d0d5f05573837171e0f2180ab194411 Mon Sep 17 00:00:00 2001
From: Andrew Burgess <aburgess@redhat.com>
Date: Tue, 4 Apr 2023 14:50:35 +0100
Subject: [PATCH 6/7] Add "maint info linux-lwps" command
This adds a maintenance command that lets you list all the LWPs under
control of the linux-nat target.
For example:
(gdb) maint info linux-lwps
LWP Ptid Thread ID
560948.561047.0 None
560948.560948.0 1.1
This shows that "560948.561047.0" LWP doesn't map to any thread_info
object, which is bogus. We'll be using this in a testcase in a
following patch.
Co-Authored-By: Pedro Alves <pedro@palves.net>
Change-Id: Ic4e9e123385976e5cd054391990124b7a20fb3f5
---
gdb/doc/gdb.texinfo | 4 ++++
gdb/linux-nat.c | 46 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 50 insertions(+)
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index c277c16297c..ad9d89796bc 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -41208,6 +41208,10 @@ module (@pxref{Disassembly In Python}), and will only be present after
that module has been imported. To force the module to be imported do
the following:
+@kindex maint info linux-lwps
+@item maint info linux-lwps
+Print information about LWPs under control of the Linux native target.
+
@smallexample
(@value{GDBP}) python import gdb.disassembler
@end smallexample
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 2f89d283acc..a3ff6036e98 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -4522,6 +4522,49 @@ current_lwp_ptid (void)
return inferior_ptid;
}
+/* Implement 'maintenance info linux-lwps'. Displays some basic
+ information about all the current lwp_info objects. */
+
+static void
+maintenance_info_lwps (const char *arg, int from_tty)
+{
+ if (all_lwps ().size () == 0)
+ {
+ gdb_printf ("No Linux LWPs\n");
+ return;
+ }
+
+ /* Start the width at 8 to match the column heading below, then
+ figure out the widest ptid string. We'll use this to build our
+ output table below. */
+ size_t ptid_width = 8;
+ for (lwp_info *lp : all_lwps ())
+ ptid_width = std::max (ptid_width, lp->ptid.to_string ().size ());
+
+ /* Setup the table headers. */
+ struct ui_out *uiout = current_uiout;
+ ui_out_emit_table table_emitter (uiout, 2, -1, "linux-lwps");
+ uiout->table_header (ptid_width, ui_left, "lwp-ptid", _("LWP Ptid"));
+ uiout->table_header (9, ui_left, "thread-info", _("Thread ID"));
+ uiout->table_body ();
+
+ /* Display one table row for each lwp_info. */
+ for (lwp_info *lp : all_lwps ())
+ {
+ ui_out_emit_tuple tuple_emitter (uiout, "lwp-entry");
+
+ thread_info *th = linux_target->find_thread (lp->ptid);
+
+ uiout->field_string ("lwp-ptid", lp->ptid.to_string ().c_str ());
+ if (th == nullptr)
+ uiout->field_string ("thread-info", "None");
+ else
+ uiout->field_string ("thread-info", print_full_thread_id (th));
+
+ uiout->message ("\n");
+ }
+}
+
void _initialize_linux_nat ();
void
_initialize_linux_nat ()
@@ -4559,6 +4602,9 @@ Enables printf debugging output."),
sigemptyset (&blocked_mask);
lwp_lwpid_htab_create ();
+
+ add_cmd ("linux-lwps", class_maintenance, maintenance_info_lwps,
+ _("List the Linux LWPS."), &maintenanceinfolist);
}
--
2.35.3

View File

@ -1,202 +0,0 @@
From 4e0e7ff14ba271576232160bf337639662a2ea23 Mon Sep 17 00:00:00 2001
From: Tom Tromey <tom@tromey.com>
Date: Thu, 16 Feb 2023 17:36:29 -0700
Subject: [PATCH 2/3] Avoid manual memory management in go-lang.c
I noticed a couple of spots in go-lang.c that could be improved by
using unique_ptr.
Reviewed-By: Andrew Burgess <aburgess@redhat.com>
---
gdb/dwarf2/read.c | 2 +-
gdb/go-exp.c | 287 +++++++++++++++++++++++-----------------------
gdb/go-exp.y | 8 +-
gdb/go-lang.c | 40 +++----
gdb/go-lang.h | 11 +-
5 files changed, 173 insertions(+), 175 deletions(-)
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 8aa7f8c31e5..61f4bd75013 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -7890,7 +7890,7 @@ fixup_go_packaging (struct dwarf2_cu *cu)
&& sym->aclass () == LOC_BLOCK)
{
gdb::unique_xmalloc_ptr<char> this_package_name
- (go_symbol_package_name (sym));
+ = go_symbol_package_name (sym);
if (this_package_name == NULL)
continue;
diff --git a/gdb/go-exp.y b/gdb/go-exp.y
index cbaa79ee18c..542a06d06d6 100644
--- a/gdb/go-exp.y
+++ b/gdb/go-exp.y
@@ -1393,16 +1393,16 @@ classify_name (struct parser_state *par_state, const struct block *block)
current package. */
{
- char *current_package_name = go_block_package_name (block);
+ gdb::unique_xmalloc_ptr<char> current_package_name
+ = go_block_package_name (block);
if (current_package_name != NULL)
{
struct stoken sval =
- build_packaged_name (current_package_name,
- strlen (current_package_name),
+ build_packaged_name (current_package_name.get (),
+ strlen (current_package_name.get ()),
copy.c_str (), copy.size ());
- xfree (current_package_name);
sym = lookup_symbol (sval.ptr, block, VAR_DOMAIN,
&is_a_field_of_this);
if (sym.symbol)
diff --git a/gdb/go-lang.c b/gdb/go-lang.c
index 7549f14dc63..f9176ace71d 100644
--- a/gdb/go-lang.c
+++ b/gdb/go-lang.c
@@ -163,11 +163,8 @@ unpack_package_and_object (char *buf,
Space for the resulting strings is malloc'd in one buffer.
PACKAGEP,OBJECTP,METHOD_TYPE* will (typically) point into this buffer.
- [There are a few exceptions, but the caller is still responsible for
- freeing the resulting pointer.]
A pointer to this buffer is returned, or NULL if symbol isn't a
mangled Go symbol.
- The caller is responsible for freeing the result.
*METHOD_TYPE_IS_POINTERP is set to a boolean indicating if
the method type is a pointer.
@@ -180,7 +177,7 @@ unpack_package_and_object (char *buf,
If we ever need to unpack the method type, this routine should work
for that too. */
-static char *
+static gdb::unique_xmalloc_ptr<char>
unpack_mangled_go_symbol (const char *mangled_name,
const char **packagep,
const char **objectp,
@@ -209,9 +206,10 @@ unpack_mangled_go_symbol (const char *mangled_name,
/* main.init is mangled specially. */
if (strcmp (mangled_name, "__go_init_main") == 0)
{
- char *package = xstrdup ("main");
+ gdb::unique_xmalloc_ptr<char> package
+ = make_unique_xstrdup ("main");
- *packagep = package;
+ *packagep = package.get ();
*objectp = "init";
return package;
}
@@ -219,9 +217,10 @@ unpack_mangled_go_symbol (const char *mangled_name,
/* main.main is mangled specially (missing prefix). */
if (strcmp (mangled_name, "main.main") == 0)
{
- char *package = xstrdup ("main");
+ gdb::unique_xmalloc_ptr<char> package
+ = make_unique_xstrdup ("main");
- *packagep = package;
+ *packagep = package.get ();
*objectp = "main";
return package;
}
@@ -261,7 +260,8 @@ unpack_mangled_go_symbol (const char *mangled_name,
/* At this point we've decided we have a mangled Go symbol. */
- buf = xstrdup (mangled_name);
+ gdb::unique_xmalloc_ptr<char> result = make_unique_xstrdup (mangled_name);
+ buf = result.get ();
/* Search backwards looking for "N<digit(s)>". */
p = buf + len;
@@ -317,7 +317,7 @@ unpack_mangled_go_symbol (const char *mangled_name,
}
unpack_package_and_object (buf, packagep, objectp);
- return buf;
+ return result;
}
/* Implements the la_demangle language_defn routine for language Go.
@@ -381,10 +381,9 @@ go_language::demangle_symbol (const char *mangled_name, int options) const
return make_unique_xstrdup ((const char *) obstack_finish (&tempbuf));
}
-/* Given a Go symbol, return its package or NULL if unknown.
- Space for the result is malloc'd, caller must free. */
+/* See go-lang.h. */
-char *
+gdb::unique_xmalloc_ptr<char>
go_symbol_package_name (const struct symbol *sym)
{
const char *mangled_name = sym->linkage_name ();
@@ -393,8 +392,7 @@ go_symbol_package_name (const struct symbol *sym)
const char *method_type_package_name;
const char *method_type_object_name;
int method_type_is_pointer;
- char *name_buf;
- char *result;
+ gdb::unique_xmalloc_ptr<char> name_buf;
gdb_assert (sym->language () == language_go);
name_buf = unpack_mangled_go_symbol (mangled_name,
@@ -405,15 +403,12 @@ go_symbol_package_name (const struct symbol *sym)
/* Some Go symbols don't have mangled form we interpret (yet). */
if (name_buf == NULL)
return NULL;
- result = xstrdup (package_name);
- xfree (name_buf);
- return result;
+ return make_unique_xstrdup (package_name);
}
-/* Return the package that BLOCK is in, or NULL if there isn't one.
- Space for the result is malloc'd, caller must free. */
+/* See go-lang.h. */
-char *
+gdb::unique_xmalloc_ptr<char>
go_block_package_name (const struct block *block)
{
while (block != NULL)
@@ -422,7 +417,8 @@ go_block_package_name (const struct block *block)
if (function != NULL)
{
- char *package_name = go_symbol_package_name (function);
+ gdb::unique_xmalloc_ptr<char> package_name
+ = go_symbol_package_name (function);
if (package_name != NULL)
return package_name;
diff --git a/gdb/go-lang.h b/gdb/go-lang.h
index f0929cc3ac5..8edfe6ed53a 100644
--- a/gdb/go-lang.h
+++ b/gdb/go-lang.h
@@ -62,9 +62,14 @@ extern const char *go_main_name (void);
extern enum go_type go_classify_struct_type (struct type *type);
-extern char *go_symbol_package_name (const struct symbol *sym);
-
-extern char *go_block_package_name (const struct block *block);
+/* Given a Go symbol, return its package or nullptr if unknown. */
+extern gdb::unique_xmalloc_ptr<char> go_symbol_package_name
+ (const struct symbol *sym);
+
+/* Return the package that BLOCK is in, or nullptr if there isn't
+ one. */
+extern gdb::unique_xmalloc_ptr<char> go_block_package_name
+ (const struct block *block);
extern const struct builtin_go_type *builtin_go_type (struct gdbarch *);
--
2.35.3

View File

@ -0,0 +1,53 @@
From acc7b542a08819bec4aae767de547c531a7ab62e Mon Sep 17 00:00:00 2001
From: Aditya Vidyadhar Kamath <Aditya.Kamath1@ibm.com>
Date: Mon, 6 Nov 2023 07:26:24 -0600
Subject: [PATCH 03/48] Change gdb.base/examine-backwards.exp for AIX.
In AIX unused or constant variables are collected as garbage by the linker and in the dwarf dump
an address with all f's in hexadecimal are assigned. Hence the testcase fails with many failures stating
it cannot access memory.
This patch is a small change to get it working in AIX as well.
---
gdb/testsuite/gdb.base/examine-backward.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/gdb/testsuite/gdb.base/examine-backward.c b/gdb/testsuite/gdb.base/examine-backward.c
index e30b58fb005..354c2e2f323 100644
--- a/gdb/testsuite/gdb.base/examine-backward.c
+++ b/gdb/testsuite/gdb.base/examine-backward.c
@@ -36,11 +36,11 @@ literals. The content of each array is the same as followings:
TestStrings, to avoid showing garbage when we look for strings
backwards from TestStrings. */
-const unsigned char Barrier[] = {
+unsigned char Barrier[] = {
0x00,
};
-const unsigned char TestStrings[] = {
+unsigned char TestStrings[] = {
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
@@ -54,7 +54,7 @@ const unsigned char TestStrings[] = {
0x00
};
-const short TestStringsH[] = {
+short TestStringsH[] = {
0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
@@ -67,7 +67,7 @@ const short TestStringsH[] = {
0x0000
};
-const int TestStringsW[] = {
+int TestStringsW[] = {
0x00000041, 0x00000042, 0x00000043, 0x00000044,
0x00000045, 0x00000046, 0x00000047, 0x00000048,
0x00000049, 0x0000004a, 0x0000004b, 0x0000004c,
--
2.35.3

View File

@ -0,0 +1,97 @@
From 800e56a120419b457ebda18c5478ebfea99f9b3a Mon Sep 17 00:00:00 2001
From: Pedro Alves <pedro@palves.net>
Date: Tue, 14 Nov 2023 11:47:15 +0000
Subject: [PATCH 7/7] Fix gdb.threads/threads-after-exec.exp race
Simon noticed that gdb.threads/threads-after-exec.exp was racy. You
can consistenly reproduce it (at git hash
319b460545dc79280e2904dcc280057cf71fb753), with:
$ taskset -c 0 make check TESTS="gdb.threads/threads-after-exec.exp"
gdb.log shows:
(...)
Thread 3 "threads-after-e" hit Catchpoint 2 (exec'd .../gdb.threads/threads-after-exec/threads-after-exec), 0x00007ffff7fe3290
in _start () from /lib64/ld-linux-x86-64.so.2
(gdb) PASS: gdb.threads/threads-after-exec.exp: continue until exec
info threads
Id Target Id Frame
* 3 process 1443269 "threads-after-e" 0x00007ffff7fe3290 in _start () from /lib64/ld-linux-x86-64.so.2
(gdb) FAIL: gdb.threads/threads-after-exec.exp: info threads
(...)
maint info linux-lwps
LWP Ptid Thread ID
1443269.1443269.0 1.3
(gdb) FAIL: gdb.threads/threads-after-exec.exp: maint info linux-lwps
The FAILs happen because the .exp file expects that after the exec,
the only thread has GDB thread number 1, but it has instead 3.
This is yet another case of zombie leader detection making things a
bit fuzzy.
In the passing case, we have:
continue
Continuing.
[New Thread 0x7ffff7bff640 (LWP 603183)]
[Thread 0x7ffff7bff640 (LWP 603183) exited]
process 603180 is executing new program: .../gdb.threads/threads-after-exec/threads-after-exec
While in the failing case, we have (note remarks on the rhs):
continue
Continuing.
[New Thread 0x7ffff7bff640 (LWP 600205)]
[Thread 0x7ffff7f95740 (LWP 600202) exited] <<< gdb deletes leader thread, thread 1.
[New LWP 600202] <<< gdb adds it back -- this is now thread 3.
[Thread 0x7ffff7bff640 (LWP 600205) exited]
process 600202 is executing new program: .../threads-after-exec/threads-after-exec
The testcase only has two threads, yet GDB presented the exec for
thread 3. This is GDB deleting the leader (the backend detected it
was zombie, due to the exec), and then adding the leader back when it
saw the exec event.
I've recorded some thoughts about this in PR gdb/31069.
For now, this commit just makes the testcase cope with the non-one
thread number, as the number is not important for what this test is
exercising.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31069
Change-Id: Id80b5c73f09c9e0005efeb494cca5d066ac3bbae
---
gdb/testsuite/gdb.threads/threads-after-exec.exp | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/gdb/testsuite/gdb.threads/threads-after-exec.exp b/gdb/testsuite/gdb.threads/threads-after-exec.exp
index cd8adf900d9..8d5a518f7b6 100644
--- a/gdb/testsuite/gdb.threads/threads-after-exec.exp
+++ b/gdb/testsuite/gdb.threads/threads-after-exec.exp
@@ -32,14 +32,18 @@ proc do_test { } {
gdb_test "continue" "Catchpoint $::decimal .*" "continue until exec"
# Confirm we only have one thread in the thread list.
- gdb_test "info threads" "\\* 1\[ \t\]+\[^\r\n\]+.*"
+ gdb_test "p \$_inferior_thread_count" " = 1"
+
+ # Get the post-exec thread number. Due to PR gdb/31069 ("Zombie
+ # leader detection racy") this isn't always thread 1.1.
+ set cur_thr [get_integer_valueof "\$_thread" 0]
if {[istarget *-*-linux*] && [gdb_is_target_native]} {
# Confirm there's only one LWP in the list as well, and that
- # it is bound to thread 1.1.
+ # it is bound to the existing GDB thread.
set inf_pid [get_inferior_pid]
gdb_test_multiple "maint info linux-lwps" "" {
- -wrap -re "Thread ID *\r\n$inf_pid\.$inf_pid\.0\[ \t\]+1\.1 *" {
+ -wrap -re "Thread ID *\r\n$inf_pid\.$inf_pid\.0\[ \t\]+1\.$cur_thr *" {
pass $gdb_test_name
}
}
--
2.35.3

View File

@ -1,148 +0,0 @@
From 11a41bc318ba0307248eadf29bf7d4a1af31d3a8 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Tue, 16 May 2023 17:00:51 +0100
Subject: [PATCH 2/2] Fix PR30369 regression on aarch64/arm (PR30506)
The gdb.dwarf2/dw2-prologue-end-2.exp test was failing for both AArch64 and
Arm.
As Tom pointed out here (https://inbox.sourceware.org/gdb-patches/6663707c-4297-c2f2-a0bd-f3e84fc62aad@suse.de/),
there are issues with both the prologue skipper for AArch64 and Arm and an
incorrect assumption by the testcase.
This patch fixes both of AArch64's and Arm's prologue skippers to not skip past
the end of a function. It also incorporates a fix to the testcase so it
doesn't assume the prologue skipper will stop at the first instruction of the
functions/labels.
Regression-tested on aarch64-linux/arm-linux Ubuntu 20.04/22.04 and
x86_64-linux Ubuntu 20.04.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30506
Co-Authored-By: Tom de Vries <tdevries@suse.de>
Co-Authored-By: Luis Machado <luis.machado@arm.com>
---
gdb/aarch64-tdep.c | 10 +++++++--
gdb/arm-tdep.c | 21 ++++++++++++++++---
.../gdb.dwarf2/dw2-prologue-end-2.exp | 12 +++++------
3 files changed, 32 insertions(+), 11 deletions(-)
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index 499b87ef480..e21d18f5c8c 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -896,12 +896,15 @@ aarch64_analyze_prologue_test (void)
static CORE_ADDR
aarch64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
- CORE_ADDR func_addr, limit_pc;
+ CORE_ADDR func_addr, func_end_addr, limit_pc;
/* See if we can determine the end of the prologue via the symbol
table. If so, then return either PC, or the PC after the
prologue, whichever is greater. */
- if (find_pc_partial_function (pc, NULL, &func_addr, NULL))
+ bool func_addr_found
+ = find_pc_partial_function (pc, NULL, &func_addr, &func_end_addr);
+
+ if (func_addr_found)
{
CORE_ADDR post_prologue_pc
= skip_prologue_using_sal (gdbarch, func_addr);
@@ -921,6 +924,9 @@ aarch64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
if (limit_pc == 0)
limit_pc = pc + 128; /* Magic. */
+ limit_pc
+ = func_end_addr == 0? limit_pc : std::min (limit_pc, func_end_addr - 4);
+
/* Try disassembling prologue. */
return aarch64_analyze_prologue (gdbarch, pc, limit_pc, NULL);
}
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 58b9c5f4bd8..ecffb9223e1 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -1768,12 +1768,18 @@ arm_skip_stack_protector(CORE_ADDR pc, struct gdbarch *gdbarch)
static CORE_ADDR
arm_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
- CORE_ADDR func_addr, limit_pc;
+ CORE_ADDR func_addr, func_end_addr, limit_pc;
/* See if we can determine the end of the prologue via the symbol table.
If so, then return either PC, or the PC after the prologue, whichever
is greater. */
- if (find_pc_partial_function (pc, NULL, &func_addr, NULL))
+ bool func_addr_found
+ = find_pc_partial_function (pc, NULL, &func_addr, &func_end_addr);
+
+ /* Whether the function is thumb mode or not. */
+ bool func_is_thumb = false;
+
+ if (func_addr_found)
{
CORE_ADDR post_prologue_pc
= skip_prologue_using_sal (gdbarch, func_addr);
@@ -1810,7 +1816,8 @@ arm_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
associate prologue code with the opening brace; so this
lets us skip the first line if we think it is the opening
brace. */
- if (arm_pc_is_thumb (gdbarch, func_addr))
+ func_is_thumb = arm_pc_is_thumb (gdbarch, func_addr);
+ if (func_is_thumb)
analyzed_limit = thumb_analyze_prologue (gdbarch, func_addr,
post_prologue_pc, NULL);
else
@@ -1836,6 +1843,14 @@ arm_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
if (limit_pc == 0)
limit_pc = pc + 64; /* Magic. */
+ /* Set the correct adjustment based on whether the function is thumb mode or
+ not. We use it to get the address of the last instruction in the
+ function (as opposed to the first address of the next function). */
+ CORE_ADDR adjustment = func_is_thumb? 2 : 4;
+
+ limit_pc
+ = func_end_addr == 0? limit_pc : std::min (limit_pc,
+ func_end_addr - adjustment);
/* Check if this is Thumb code. */
if (arm_pc_is_thumb (gdbarch, pc))
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-prologue-end-2.exp b/gdb/testsuite/gdb.dwarf2/dw2-prologue-end-2.exp
index 642b73fe2a1..da49902c13c 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-prologue-end-2.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-prologue-end-2.exp
@@ -95,17 +95,17 @@ if { $break_addr == "" } {
return
}
-# Get the "foo_label" address.
+# Get the "bar_label" address.
-set foo_label_addr ""
-gdb_test_multiple "print /x &foo_label" "" {
+set bar_label_addr ""
+gdb_test_multiple "print /x &bar_label" "" {
-re -wrap "= ($hex)" {
- set foo_label_addr $expect_out(1,string)
+ set bar_label_addr $expect_out(1,string)
pass $gdb_test_name
}
}
-if { $foo_label_addr == "" } {
+if { $bar_label_addr == "" } {
return
}
@@ -117,4 +117,4 @@ gdb_test "print &foo_end == &bar_label" " = 1"
# Check that the breakpoint is set at the expected address. Regression test
# for PR30369.
-gdb_assert { $break_addr == $foo_label_addr }
+gdb_assert { $break_addr < $bar_label_addr }
--
2.35.3

View File

@ -0,0 +1,366 @@
From 2a7e48ca27f4c080151ce9da5a29239aa5d3b66f Mon Sep 17 00:00:00 2001
From: Tom Tromey <tromey@adacore.com>
Date: Fri, 19 Apr 2024 07:54:19 -0600
Subject: [PATCH 15/48] Fix regression on aarch64-linux gdbserver
Commit 9a03f218 ("Fix gdb.base/watchpoint-unaligned.exp on aarch64")
fixed a watchpoint bug in gdb -- but did not touch the corresponding
code in gdbserver.
This patch moves the gdb code into gdb/nat, so that it can be shared
with gdbserver, and then changes gdbserver to use it, fixing the bug.
This is yet another case where having a single back end would prevent
bugs.
I tested this using the AdaCore internal gdb testsuite.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29423
Approved-By: Luis Machado <luis.machado@arm.com>
---
gdb/aarch64-nat.c | 115 ---------------------------------
gdb/aarch64-nat.h | 8 ---
gdb/nat/aarch64-hw-point.c | 115 +++++++++++++++++++++++++++++++++
gdb/nat/aarch64-hw-point.h | 8 +++
gdbserver/linux-aarch64-low.cc | 38 +----------
5 files changed, 126 insertions(+), 158 deletions(-)
diff --git a/gdb/aarch64-nat.c b/gdb/aarch64-nat.c
index a173e4e18d5..97e3048568a 100644
--- a/gdb/aarch64-nat.c
+++ b/gdb/aarch64-nat.c
@@ -225,121 +225,6 @@ aarch64_remove_watchpoint (CORE_ADDR addr, int len, enum target_hw_bp_type type,
return ret;
}
-/* See aarch64-nat.h. */
-
-bool
-aarch64_stopped_data_address (const struct aarch64_debug_reg_state *state,
- CORE_ADDR addr_trap, CORE_ADDR *addr_p)
-{
- bool found = false;
- for (int phase = 0; phase <= 1; ++phase)
- for (int i = aarch64_num_wp_regs - 1; i >= 0; --i)
- {
- if (!(state->dr_ref_count_wp[i]
- && DR_CONTROL_ENABLED (state->dr_ctrl_wp[i])))
- {
- /* Watchpoint disabled. */
- continue;
- }
-
- const enum target_hw_bp_type type
- = aarch64_watchpoint_type (state->dr_ctrl_wp[i]);
- if (type == hw_execute)
- {
- /* Watchpoint disabled. */
- continue;
- }
-
- if (phase == 0)
- {
- /* Phase 0: No hw_write. */
- if (type == hw_write)
- continue;
- }
- else
- {
- /* Phase 1: Only hw_write. */
- if (type != hw_write)
- continue;
- }
-
- const unsigned int offset
- = aarch64_watchpoint_offset (state->dr_ctrl_wp[i]);
- const unsigned int len
- = aarch64_watchpoint_length (state->dr_ctrl_wp[i]);
- const CORE_ADDR addr_watch = state->dr_addr_wp[i] + offset;
- const CORE_ADDR addr_watch_aligned
- = align_down (state->dr_addr_wp[i], AARCH64_HWP_MAX_LEN_PER_REG);
- const CORE_ADDR addr_orig = state->dr_addr_orig_wp[i];
-
- /* ADDR_TRAP reports the first address of the memory range
- accessed by the CPU, regardless of what was the memory
- range watched. Thus, a large CPU access that straddles
- the ADDR_WATCH..ADDR_WATCH+LEN range may result in an
- ADDR_TRAP that is lower than the
- ADDR_WATCH..ADDR_WATCH+LEN range. E.g.:
-
- addr: | 4 | 5 | 6 | 7 | 8 |
- |---- range watched ----|
- |----------- range accessed ------------|
-
- In this case, ADDR_TRAP will be 4.
-
- The access size also can be larger than that of the watchpoint
- itself. For instance, the access size of an stp instruction is 16.
- So, if we use stp to store to address p, and set a watchpoint on
- address p + 8, the reported ADDR_TRAP can be p + 8 (observed on
- RK3399 SOC). But it also can be p (observed on M1 SOC). Checking
- for this situation introduces the possibility of false positives,
- so we only do this for hw_write watchpoints. */
- const CORE_ADDR max_access_size = type == hw_write ? 16 : 8;
- const CORE_ADDR addr_watch_base = addr_watch_aligned -
- (max_access_size - AARCH64_HWP_MAX_LEN_PER_REG);
- if (!(addr_trap >= addr_watch_base
- && addr_trap < addr_watch + len))
- {
- /* Not a match. */
- continue;
- }
-
- /* To match a watchpoint known to GDB core, we must never
- report *ADDR_P outside of any ADDR_WATCH..ADDR_WATCH+LEN
- range. ADDR_WATCH <= ADDR_TRAP < ADDR_ORIG is a false
- positive on kernels older than 4.10. See PR
- external/20207. */
- if (addr_p != nullptr)
- *addr_p = addr_orig;
-
- if (phase == 0)
- {
- /* Phase 0: Return first match. */
- return true;
- }
-
- /* Phase 1. */
- if (addr_p == nullptr)
- {
- /* First match, and we don't need to report an address. No need
- to look for other matches. */
- return true;
- }
-
- if (!found)
- {
- /* First match, and we need to report an address. Look for other
- matches. */
- found = true;
- continue;
- }
-
- /* More than one match, and we need to return an address. No need to
- look for further matches. */
- return false;
- }
-
- return found;
-}
-
/* Define AArch64 maintenance commands. */
static void
diff --git a/gdb/aarch64-nat.h b/gdb/aarch64-nat.h
index fee6bda2577..f95a9d745e5 100644
--- a/gdb/aarch64-nat.h
+++ b/gdb/aarch64-nat.h
@@ -45,14 +45,6 @@ struct aarch64_debug_reg_state *aarch64_get_debug_reg_state (pid_t pid);
void aarch64_remove_debug_reg_state (pid_t pid);
-/* Helper for the "stopped_data_address" target method. Returns TRUE
- if a hardware watchpoint trap at ADDR_TRAP matches a set
- watchpoint. The address of the matched watchpoint is returned in
- *ADDR_P. */
-
-bool aarch64_stopped_data_address (const struct aarch64_debug_reg_state *state,
- CORE_ADDR addr_trap, CORE_ADDR *addr_p);
-
/* Helper functions used by aarch64_nat_target below. See their
definitions. */
diff --git a/gdb/nat/aarch64-hw-point.c b/gdb/nat/aarch64-hw-point.c
index 3b8cdcba23b..9eb78923e86 100644
--- a/gdb/nat/aarch64-hw-point.c
+++ b/gdb/nat/aarch64-hw-point.c
@@ -647,3 +647,118 @@ aarch64_region_ok_for_watchpoint (CORE_ADDR addr, int len)
the checking is costly. */
return 1;
}
+
+/* See nat/aarch64-hw-point.h. */
+
+bool
+aarch64_stopped_data_address (const struct aarch64_debug_reg_state *state,
+ CORE_ADDR addr_trap, CORE_ADDR *addr_p)
+{
+ bool found = false;
+ for (int phase = 0; phase <= 1; ++phase)
+ for (int i = aarch64_num_wp_regs - 1; i >= 0; --i)
+ {
+ if (!(state->dr_ref_count_wp[i]
+ && DR_CONTROL_ENABLED (state->dr_ctrl_wp[i])))
+ {
+ /* Watchpoint disabled. */
+ continue;
+ }
+
+ const enum target_hw_bp_type type
+ = aarch64_watchpoint_type (state->dr_ctrl_wp[i]);
+ if (type == hw_execute)
+ {
+ /* Watchpoint disabled. */
+ continue;
+ }
+
+ if (phase == 0)
+ {
+ /* Phase 0: No hw_write. */
+ if (type == hw_write)
+ continue;
+ }
+ else
+ {
+ /* Phase 1: Only hw_write. */
+ if (type != hw_write)
+ continue;
+ }
+
+ const unsigned int offset
+ = aarch64_watchpoint_offset (state->dr_ctrl_wp[i]);
+ const unsigned int len
+ = aarch64_watchpoint_length (state->dr_ctrl_wp[i]);
+ const CORE_ADDR addr_watch = state->dr_addr_wp[i] + offset;
+ const CORE_ADDR addr_watch_aligned
+ = align_down (state->dr_addr_wp[i], AARCH64_HWP_MAX_LEN_PER_REG);
+ const CORE_ADDR addr_orig = state->dr_addr_orig_wp[i];
+
+ /* ADDR_TRAP reports the first address of the memory range
+ accessed by the CPU, regardless of what was the memory
+ range watched. Thus, a large CPU access that straddles
+ the ADDR_WATCH..ADDR_WATCH+LEN range may result in an
+ ADDR_TRAP that is lower than the
+ ADDR_WATCH..ADDR_WATCH+LEN range. E.g.:
+
+ addr: | 4 | 5 | 6 | 7 | 8 |
+ |---- range watched ----|
+ |----------- range accessed ------------|
+
+ In this case, ADDR_TRAP will be 4.
+
+ The access size also can be larger than that of the watchpoint
+ itself. For instance, the access size of an stp instruction is 16.
+ So, if we use stp to store to address p, and set a watchpoint on
+ address p + 8, the reported ADDR_TRAP can be p + 8 (observed on
+ RK3399 SOC). But it also can be p (observed on M1 SOC). Checking
+ for this situation introduces the possibility of false positives,
+ so we only do this for hw_write watchpoints. */
+ const CORE_ADDR max_access_size = type == hw_write ? 16 : 8;
+ const CORE_ADDR addr_watch_base = addr_watch_aligned -
+ (max_access_size - AARCH64_HWP_MAX_LEN_PER_REG);
+ if (!(addr_trap >= addr_watch_base
+ && addr_trap < addr_watch + len))
+ {
+ /* Not a match. */
+ continue;
+ }
+
+ /* To match a watchpoint known to GDB core, we must never
+ report *ADDR_P outside of any ADDR_WATCH..ADDR_WATCH+LEN
+ range. ADDR_WATCH <= ADDR_TRAP < ADDR_ORIG is a false
+ positive on kernels older than 4.10. See PR
+ external/20207. */
+ if (addr_p != nullptr)
+ *addr_p = addr_orig;
+
+ if (phase == 0)
+ {
+ /* Phase 0: Return first match. */
+ return true;
+ }
+
+ /* Phase 1. */
+ if (addr_p == nullptr)
+ {
+ /* First match, and we don't need to report an address. No need
+ to look for other matches. */
+ return true;
+ }
+
+ if (!found)
+ {
+ /* First match, and we need to report an address. Look for other
+ matches. */
+ found = true;
+ continue;
+ }
+
+ /* More than one match, and we need to return an address. No need to
+ look for further matches. */
+ return false;
+ }
+
+ return found;
+}
diff --git a/gdb/nat/aarch64-hw-point.h b/gdb/nat/aarch64-hw-point.h
index 71ae2864927..2386cf60f90 100644
--- a/gdb/nat/aarch64-hw-point.h
+++ b/gdb/nat/aarch64-hw-point.h
@@ -110,6 +110,14 @@ unsigned int aarch64_watchpoint_offset (unsigned int ctrl);
unsigned int aarch64_watchpoint_length (unsigned int ctrl);
enum target_hw_bp_type aarch64_watchpoint_type (unsigned int ctrl);
+/* Helper for the "stopped_data_address" target method. Returns TRUE
+ if a hardware watchpoint trap at ADDR_TRAP matches a set
+ watchpoint. The address of the matched watchpoint is returned in
+ *ADDR_P. */
+
+bool aarch64_stopped_data_address (const struct aarch64_debug_reg_state *state,
+ CORE_ADDR addr_trap, CORE_ADDR *addr_p);
+
int aarch64_handle_breakpoint (enum target_hw_bp_type type, CORE_ADDR addr,
int len, int is_insert, ptid_t ptid,
struct aarch64_debug_reg_state *state);
diff --git a/gdbserver/linux-aarch64-low.cc b/gdbserver/linux-aarch64-low.cc
index fcbe7bb64d7..14346b89822 100644
--- a/gdbserver/linux-aarch64-low.cc
+++ b/gdbserver/linux-aarch64-low.cc
@@ -577,41 +577,9 @@ aarch64_target::low_stopped_data_address ()
/* Check if the address matches any watched address. */
state = aarch64_get_debug_reg_state (pid_of (current_thread));
- for (i = aarch64_num_wp_regs - 1; i >= 0; --i)
- {
- const unsigned int offset
- = aarch64_watchpoint_offset (state->dr_ctrl_wp[i]);
- const unsigned int len = aarch64_watchpoint_length (state->dr_ctrl_wp[i]);
- const CORE_ADDR addr_watch = state->dr_addr_wp[i] + offset;
- const CORE_ADDR addr_watch_aligned = align_down (state->dr_addr_wp[i], 8);
- const CORE_ADDR addr_orig = state->dr_addr_orig_wp[i];
-
- if (state->dr_ref_count_wp[i]
- && DR_CONTROL_ENABLED (state->dr_ctrl_wp[i])
- && addr_trap >= addr_watch_aligned
- && addr_trap < addr_watch + len)
- {
- /* ADDR_TRAP reports the first address of the memory range
- accessed by the CPU, regardless of what was the memory
- range watched. Thus, a large CPU access that straddles
- the ADDR_WATCH..ADDR_WATCH+LEN range may result in an
- ADDR_TRAP that is lower than the
- ADDR_WATCH..ADDR_WATCH+LEN range. E.g.:
-
- addr: | 4 | 5 | 6 | 7 | 8 |
- |---- range watched ----|
- |----------- range accessed ------------|
-
- In this case, ADDR_TRAP will be 4.
-
- To match a watchpoint known to GDB core, we must never
- report *ADDR_P outside of any ADDR_WATCH..ADDR_WATCH+LEN
- range. ADDR_WATCH <= ADDR_TRAP < ADDR_ORIG is a false
- positive on kernels older than 4.10. See PR
- external/20207. */
- return addr_orig;
- }
- }
+ CORE_ADDR result;
+ if (aarch64_stopped_data_address (state, addr_trap, &result))
+ return result;
return (CORE_ADDR) 0;
}
--
2.35.3

View File

@ -0,0 +1,80 @@
From c21fd9f7d5911fce0c17af7094d8861d1195dfda Mon Sep 17 00:00:00 2001
From: Carl Love <cel@linux.ibm.com>
Date: Mon, 13 Nov 2023 14:14:08 -0500
Subject: [PATCH 01/48] Fix the gdb.ada/inline-section-gc.exp test
The original intention of the test appears to be checking to make sure
setting a breakpoint in an inlined function didn't set multiple
breakpoints where one of them was at address 0.
The gdb.ada/inline-section-gc.exp test may pass or fail depending on the
version of gnat. Per the discussion on IRC, the ada inlining appears to
have some target dependencies. In this test there are two functions,
callee and caller. Function calee is inlined into caller. The test sets
a breakpoint in function callee. The reported location where the
breakpoint is set may be at the requested location in callee or the
location in caller after callee has been inlined. The test needs to
accept either location as correct provided the breakpoint address is not
zero.
This patch checks to see if the reported breakpoint is in function callee
or function caller and fails if the breakpoint address is 0x0. The line
number where the breakpoint is set will match the requested line if the
breakpoint location is reported is callee.adb. If the breakpoint is
reported in caller.adb, the line number in caller is the breakpoint
location in callee where it is inlined into caller.
This patch fixes the single regression failure for the test on PowerPC.
It does not introduce any failures on X86-64.
---
gdb/testsuite/gdb.ada/inline-section-gc.exp | 21 ++++++++++++++++---
.../gdb.ada/inline-section-gc/caller.adb | 3 ++-
2 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/gdb/testsuite/gdb.ada/inline-section-gc.exp b/gdb/testsuite/gdb.ada/inline-section-gc.exp
index b707335eb04..4f8b8c95395 100644
--- a/gdb/testsuite/gdb.ada/inline-section-gc.exp
+++ b/gdb/testsuite/gdb.ada/inline-section-gc.exp
@@ -34,8 +34,23 @@ if {[gdb_compile_ada "${srcfile}" "${binfile}" executable $options] != ""} {
clean_restart ${testfile}
-set bp_location [gdb_get_line_number "BREAK" ${testdir}/callee.adb]
+
+# Depending on the version of gnat, the location of the set breakpoint may
+# be reported as being at the requested location in file callee.adb or in
+# file caller.adb where the callee function was inlined. Either way, only
+# one breakpoint should be reported and its address should not be at 0x0.
+set bp_location1 [gdb_get_line_number "BREAK" ${testdir}/callee.adb]
+set bp_location2 [gdb_get_line_number "CALLEE_LOC" ${testdir}/caller.adb]
+set test "break callee.adb:$bp_location1"
+set message "Breakpoint set"
+
# The bug here was that gdb would set a breakpoint with two locations,
# one of them at 0x0.
-gdb_test "break callee.adb:$bp_location" \
- "Breakpoint $decimal at $hex: file .*callee.adb, line $bp_location."
+gdb_test_multiple $test $message {
+ -re "Breakpoint $decimal at $hex: file .*callee.adb, line $bp_location1." {
+ pass $test
+ }
+ -re "Breakpoint $decimal at $hex: file .*caller.adb, line $bp_location2." {
+ pass $test
+ }
+}
diff --git a/gdb/testsuite/gdb.ada/inline-section-gc/caller.adb b/gdb/testsuite/gdb.ada/inline-section-gc/caller.adb
index 66eb2d9a910..161f3e85542 100644
--- a/gdb/testsuite/gdb.ada/inline-section-gc/caller.adb
+++ b/gdb/testsuite/gdb.ada/inline-section-gc/caller.adb
@@ -18,4 +18,5 @@ with Callee;
procedure Caller is
begin
Callee;
-end Caller;
+end Caller; -- CALLEE_LOC, this is where the inlined callee breakpoint
+ -- is located.
base-commit: 582fc35843fdf71b82d645d83d2903e2546cc21a
--
2.35.3

View File

@ -1,10 +1,19 @@
From af4a87e2b3c2ac5acae1e6f4405fc59e1218de74 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 18 Apr 2024 14:26:58 +0200
Subject: [PATCH] fixup-gdb-linux_perf-bundle
---
gdb/gdb.c | 8 --------
1 file changed, 8 deletions(-)
diff --git a/gdb/gdb.c b/gdb/gdb.c
index 82e9e6da210..b5e28445630 100644
index 41a9b70c222..6e3ff0755ab 100644
--- a/gdb/gdb.c
+++ b/gdb/gdb.c
@@ -20,19 +20,11 @@
#include "main.h"
@@ -21,10 +21,6 @@
#include "interps.h"
#include "run-on-main-thread.h"
-#ifdef PERF_ATTR_SIZE_VER5_BUNDLE
-extern "C" void __libipt_init(void);
@ -13,6 +22,8 @@ index 82e9e6da210..b5e28445630 100644
int
main (int argc, char **argv)
{
@@ -36,10 +32,6 @@ main (int argc, char **argv)
struct captured_main_args args;
-#ifdef PERF_ATTR_SIZE_VER5_BUNDLE
@ -22,3 +33,8 @@ index 82e9e6da210..b5e28445630 100644
memset (&args, 0, sizeof args);
args.argc = argc;
args.argv = argv;
base-commit: 254988c36fe592e89af5d92e1d35a6eb4b09cbb0
--
2.35.3

View File

@ -0,0 +1,70 @@
From d60b57fe1a98094a7e4f19481193b2b5a9bb1e57 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 2 May 2024 12:02:50 +0200
Subject: [PATCH 079/147] fixup PowerPC and aarch64: Fix reverse stepping
failure
---
gdb/infrun.c | 2 +-
gdb/symtab.c | 3 +--
gdb/symtab.h | 3 +--
3 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 069ef144a76..7be98cfc252 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -6897,7 +6897,7 @@ update_line_range_start (CORE_ADDR pc, struct execution_control_state *ecs)
Given the PC, check the line table and return the PC that corresponds
to the line table entry for the source line that PC is in. */
CORE_ADDR start_line_pc = ecs->event_thread->control.step_range_start;
- std::optional<CORE_ADDR> real_range_start;
+ gdb::optional<CORE_ADDR> real_range_start;
/* Call find_line_range_start to get the smallest address in the
linetable for multiple Line X entries in the line table. */
diff --git a/gdb/symtab.c b/gdb/symtab.c
index ef63ec93c5a..9a47796e5e0 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -73,7 +73,6 @@
#include "gdbsupport/gdb_string_view.h"
#include "gdbsupport/pathstuff.h"
#include "gdbsupport/common-utils.h"
-#include <optional>
/* Forward declarations for local functions. */
@@ -3328,7 +3327,7 @@ sal_line_symtab_matches_p (const symtab_and_line &sal1,
/* See symtah.h. */
-std::optional<CORE_ADDR>
+gdb::optional<CORE_ADDR>
find_line_range_start (CORE_ADDR pc)
{
struct symtab_and_line current_sal = find_pc_line (pc, 0);
diff --git a/gdb/symtab.h b/gdb/symtab.h
index e17d15c595b..6a611d42880 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -38,7 +38,6 @@
#include "gdb-demangle.h"
#include "split-name.h"
#include "frame.h"
-#include <optional>
/* Opaque declarations. */
struct ui_file;
@@ -2377,7 +2376,7 @@ extern struct symtab_and_line find_pc_sect_line (CORE_ADDR,
the starting PC of line X, and the ranges are contiguous.
*/
-extern std::optional<CORE_ADDR> find_line_range_start (CORE_ADDR pc);
+extern gdb::optional<CORE_ADDR> find_line_range_start (CORE_ADDR pc);
/* Wrapper around find_pc_line to just return the symtab. */
--
2.35.3

101
fixup-skip-tests.patch Normal file
View File

@ -0,0 +1,101 @@
From c1da0d6449415cc1fe6f863526735e4325b0b3ac Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Wed, 1 May 2024 12:43:41 +0200
Subject: [PATCH 1/2] fixup-skip-tests
---
gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib.exp | 4 +---
gdb/testsuite/gdb.base/gnu-ifunc-strstr-workaround.exp | 4 +---
gdb/testsuite/gdb.cp/cxxexec.exp | 2 +-
.../py-gdb-rhbz1007614-memleak-infpy_read_memory.exp | 4 ++--
gdb/testsuite/gdb.python/rh634108-solib_address.exp | 6 +++---
5 files changed, 8 insertions(+), 12 deletions(-)
diff --git a/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib.exp b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib.exp
index 0c46489f315..5879319f27c 100644
--- a/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib.exp
+++ b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib.exp
@@ -13,9 +13,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-if {[skip_shlib_tests]} {
- return 0
-}
+require allow_shlib_tests
set testfile "gcore-buildid-exec-but-not-solib"
set srcmainfile ${testfile}-main.c
diff --git a/gdb/testsuite/gdb.base/gnu-ifunc-strstr-workaround.exp b/gdb/testsuite/gdb.base/gnu-ifunc-strstr-workaround.exp
index 052bd84d420..73a9bb64903 100644
--- a/gdb/testsuite/gdb.base/gnu-ifunc-strstr-workaround.exp
+++ b/gdb/testsuite/gdb.base/gnu-ifunc-strstr-workaround.exp
@@ -17,9 +17,7 @@
# invalid IFUNC DW_AT_linkage_name: memmove strstr time
# http://sourceware.org/bugzilla/show_bug.cgi?id=14166
-if {[skip_shlib_tests]} {
- return 0
-}
+require allow_shlib_tests
set testfile "gnu-ifunc-strstr-workaround"
set executable ${testfile}
diff --git a/gdb/testsuite/gdb.cp/cxxexec.exp b/gdb/testsuite/gdb.cp/cxxexec.exp
index 77c85587407..089a679a1a9 100644
--- a/gdb/testsuite/gdb.cp/cxxexec.exp
+++ b/gdb/testsuite/gdb.cp/cxxexec.exp
@@ -13,7 +13,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-if { [skip_cplus_tests] } { continue }
+require allow_cplus_tests
set testfile cxxexec
if { [prepare_for_testing ${testfile}.exp ${testfile} ${testfile}.cc {c++ debug}] } {
diff --git a/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.exp b/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.exp
index 2e6786d499a..d2693cfef1d 100644
--- a/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.exp
+++ b/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.exp
@@ -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/>.
+require allow_python_tests
+
set testfile py-gdb-rhbz1007614-memleak-infpy_read_memory
set srcfile ${testfile}.c
set binfile [standard_output_file ${testfile}]
@@ -21,8 +23,6 @@ if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
return -1
}
-if { [skip_python_tests] } { continue }
-
set pid_of_gdb [exp_pid -i [board_info host fileid]]
proc memory_v_pages_get {} {
diff --git a/gdb/testsuite/gdb.python/rh634108-solib_address.exp b/gdb/testsuite/gdb.python/rh634108-solib_address.exp
index ebf00babc34..2d950b79951 100644
--- a/gdb/testsuite/gdb.python/rh634108-solib_address.exp
+++ b/gdb/testsuite/gdb.python/rh634108-solib_address.exp
@@ -15,10 +15,10 @@
# https://bugzilla.redhat.com/show_bug.cgi?id=634108
+# Skip all tests if Python scripting is not enabled.
+require allow_python_tests
+
gdb_exit
gdb_start
-# Skip all tests if Python scripting is not enabled.
-if { [skip_python_tests] } { continue }
-
gdb_test "python print (gdb.solib_name(0))" "None" "gdb.solib_name exists"
base-commit: 50ee7556c2430effed45ca542852f36368336dce
--
2.35.3

BIN
gdb-13.2.tar.bz2 (Stored with Git LFS)

Binary file not shown.

BIN
gdb-14.2.tar.bz2 (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -16,7 +16,7 @@ Subject: gdb-6.3-gstack-20050411.patch
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -2011,7 +2011,7 @@ info install-info clean-info dvi pdf install-pdf html install-html: force
@@ -2035,7 +2035,7 @@ info install-info clean-info dvi pdf install-pdf html install-html: force
install: all
@$(MAKE) $(FLAGS_TO_PASS) install-only
@ -25,7 +25,7 @@ diff --git a/gdb/Makefile.in b/gdb/Makefile.in
transformed_name=`t='$(program_transform_name)'; \
echo gdb | sed -e "$$t"` ; \
if test "x$$transformed_name" = x; then \
@@ -2061,7 +2061,25 @@ install-guile:
@@ -2085,7 +2085,25 @@ install-guile:
install-python:
$(SHELL) $(srcdir)/../mkinstalldirs $(DESTDIR)$(GDB_DATADIR)/python/gdb
@ -52,7 +52,7 @@ diff --git a/gdb/Makefile.in b/gdb/Makefile.in
transformed_name=`t='$(program_transform_name)'; \
echo gdb | sed -e $$t` ; \
if test "x$$transformed_name" = x; then \
@@ -2092,6 +2110,18 @@ uninstall: force $(CONFIG_UNINSTALL)
@@ -2116,6 +2134,18 @@ uninstall: force $(CONFIG_UNINSTALL)
rm -f $(DESTDIR)$(bindir)/$$transformed_name
@$(MAKE) DO=uninstall "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS) subdir_do

View File

@ -44,7 +44,7 @@ glibc-debuginfo-2.7-2.x86_64: /usr/lib/debug/lib64/libc.so.6.debug:
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -1300,6 +1300,10 @@ process_print_command_args (const char *args, value_print_options *print_opts,
@@ -1308,6 +1308,11 @@ process_print_command_args (const char *args, value_print_options *print_opts,
if (exp != nullptr && *exp)
{
@ -52,9 +52,10 @@ diff --git a/gdb/printcmd.c b/gdb/printcmd.c
+ function descriptors. */
+ if (target_has_execution () && strcmp (exp, "errno") == 0)
+ exp = "*(*(int *(*)(void)) __errno_location) ()";
/* VOIDPRINT is true to indicate that we do want to print a void
value, so invert it for parse_expression. */
expression_up expr = parse_expression (exp, nullptr, !voidprint);
+
/* This setting allows large arrays to be printed by limiting the
number of elements that are loaded into GDB's memory; we only
need to load as many array elements as we plan to print. */
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-errno.c b/gdb/testsuite/gdb.dwarf2/dw2-errno.c
new file mode 100644
--- /dev/null

View File

@ -235,7 +235,7 @@ diff --git a/gdb/aclocal.m4 b/gdb/aclocal.m4
diff --git a/gdb/build-id.c b/gdb/build-id.c
--- a/gdb/build-id.c
+++ b/gdb/build-id.c
@@ -771,10 +771,10 @@ missing_rpm_enlist_1 (const char *filename, int verify_vendor)
@@ -780,10 +780,10 @@ missing_rpm_enlist_1 (const char *filename, int verify_vendor)
static rpmts (*rpmtsCreate_p) (void);
extern rpmts rpmtsFree(rpmts ts);
static rpmts (*rpmtsFree_p) (rpmts ts);
@ -248,7 +248,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
const void *keyp,
size_t keylen);
#else /* !DLOPEN_LIBRPM */
@@ -829,7 +829,7 @@ missing_rpm_enlist_1 (const char *filename, int verify_vendor)
@@ -838,7 +838,7 @@ missing_rpm_enlist_1 (const char *filename, int verify_vendor)
&& (rpmdbNextIterator_p = (Header (*) (rpmdbMatchIterator mi)) dlsym (h, "rpmdbNextIterator"))
&& (rpmtsCreate_p = (rpmts (*) (void)) dlsym (h, "rpmtsCreate"))
&& (rpmtsFree_p = (rpmts (*) (rpmts ts)) dlsym (h, "rpmtsFree"))
@ -257,7 +257,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
{
warning (_("Opened library \"%s\" is incompatible (%s), "
"missing debuginfos notifications will not be displayed"),
@@ -917,7 +917,7 @@ missing_rpm_enlist_1 (const char *filename, int verify_vendor)
@@ -926,7 +926,7 @@ missing_rpm_enlist_1 (const char *filename, int verify_vendor)
/* RPMDBI_PACKAGES requires keylen == sizeof (int). */
/* RPMDBI_LABEL is an interface for NVR-based dbiFindByLabel(). */
@ -269,7 +269,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
diff --git a/gdb/config.in b/gdb/config.in
--- a/gdb/config.in
+++ b/gdb/config.in
@@ -39,6 +39,9 @@
@@ -42,6 +42,9 @@
/* Handle .ctf type-info sections */
#undef ENABLE_LIBCTF
@ -279,9 +279,9 @@ diff --git a/gdb/config.in b/gdb/config.in
/* Define to 1 if translation of program messages to the user's native
language is requested. */
#undef ENABLE_NLS
@@ -259,6 +262,9 @@
/* Define if you have the mpfr library. */
#undef HAVE_LIBMPFR
@@ -265,6 +268,9 @@
/* Define to 1 if you have the `m' library (-lm). */
#undef HAVE_LIBM
+/* Define if librpm library is being used. */
+#undef HAVE_LIBRPM
@ -292,7 +292,7 @@ diff --git a/gdb/config.in b/gdb/config.in
diff --git a/gdb/configure b/gdb/configure
--- a/gdb/configure
+++ b/gdb/configure
@@ -783,6 +783,11 @@ TARGET_OBS
@@ -778,6 +778,11 @@ AMD_DBGAPI_CFLAGS
ENABLE_BFD_64_BIT_FALSE
ENABLE_BFD_64_BIT_TRUE
subdirs
@ -304,16 +304,16 @@ diff --git a/gdb/configure b/gdb/configure
GDB_DATADIR
DEBUGDIR
MAKEINFO_EXTRA_FLAGS
@@ -912,6 +917,7 @@ with_gdb_datadir
@@ -911,6 +916,7 @@ with_gdb_datadir
with_relocated_sources
with_auto_load_dir
with_auto_load_safe_path
+with_rpm
enable_targets
enable_64_bit_bfd
enable_gdbmi
@@ -992,6 +998,8 @@ PKG_CONFIG_PATH
PKG_CONFIG_LIBDIR
with_amd_dbgapi
@@ -988,6 +994,8 @@ AMD_DBGAPI_CFLAGS
AMD_DBGAPI_LIBS
DEBUGINFOD_CFLAGS
DEBUGINFOD_LIBS
+RPM_CFLAGS
@ -321,8 +321,8 @@ diff --git a/gdb/configure b/gdb/configure
YACC
YFLAGS
ZSTD_CFLAGS
@@ -1678,6 +1686,8 @@ Optional Packages:
do not restrict auto-loaded files locations
@@ -1679,6 +1687,8 @@ Optional Packages:
--with-amd-dbgapi support for the amd-dbgapi target (yes / no / auto)
--with-debuginfod Enable debuginfo lookups with debuginfod
(auto/yes/no)
+ --with-rpm query rpm database for missing debuginfos (yes/no,
@ -330,7 +330,7 @@ diff --git a/gdb/configure b/gdb/configure
--with-libunwind-ia64 use libunwind frame unwinding for ia64 targets
--with-curses use the curses library instead of the termcap
library
@@ -1761,6 +1771,8 @@ Some influential environment variables:
@@ -1759,6 +1769,8 @@ Some influential environment variables:
C compiler flags for DEBUGINFOD, overriding pkg-config
DEBUGINFOD_LIBS
linker flags for DEBUGINFOD, overriding pkg-config
@ -339,7 +339,7 @@ diff --git a/gdb/configure b/gdb/configure
YACC The `Yet Another Compiler Compiler' implementation to use.
Defaults to the first program found out of: `bison -y', `byacc',
`yacc'.
@@ -17848,6 +17860,495 @@ _ACEOF
@@ -18039,6 +18051,495 @@ _ACEOF
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_auto_load_safe_path" >&5
$as_echo "$with_auto_load_safe_path" >&6; }
@ -838,7 +838,7 @@ diff --git a/gdb/configure b/gdb/configure
diff --git a/gdb/configure.ac b/gdb/configure.ac
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -160,6 +160,200 @@ AC_DEFINE_DIR(AUTO_LOAD_SAFE_PATH, escape_dir,
@@ -173,6 +173,200 @@ AC_DEFINE_DIR(AUTO_LOAD_SAFE_PATH, escape_dir,
[Directories safe to hold auto-loaded files.])
AC_MSG_RESULT([$with_auto_load_safe_path])
@ -1050,7 +1050,7 @@ diff --git a/gdb/event-top.c b/gdb/event-top.c
/* readline include files. */
#include "readline/readline.h"
@@ -391,6 +392,8 @@ display_gdb_prompt (const char *new_prompt)
@@ -404,6 +405,8 @@ display_gdb_prompt (const char *new_prompt)
/* Reset the nesting depth used when trace-commands is set. */
reset_command_nest_depth ();
@ -1059,7 +1059,7 @@ diff --git a/gdb/event-top.c b/gdb/event-top.c
/* Do not call the python hook on an explicit prompt change as
passed to this function, as this forms a secondary/local prompt,
IE, displayed but not set. */
@@ -852,7 +855,10 @@ command_line_handler (gdb::unique_xmalloc_ptr<char> &&rl)
@@ -788,7 +791,10 @@ command_line_handler (gdb::unique_xmalloc_ptr<char> &&rl)
command_handler (cmd);
if (ui->prompt_state != PROMPTED)
@ -1074,7 +1074,7 @@ diff --git a/gdb/event-top.c b/gdb/event-top.c
diff --git a/gdb/symfile.h b/gdb/symfile.h
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -352,6 +352,7 @@ extern void generic_load (const char *args, int from_tty);
@@ -367,6 +367,7 @@ extern void generic_load (const char *args, int from_tty);
/* build-id support. */
extern struct bfd_build_id *build_id_addr_get (CORE_ADDR addr);
extern void debug_print_missing (const char *binary, const char *debug);

View File

@ -14,7 +14,7 @@ https://bugzilla.redhat.com/show_bug.cgi?id=1339862
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -1321,14 +1321,28 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
@@ -1320,14 +1320,28 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
}
{
@ -45,7 +45,7 @@ diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
if (build_id != NULL)
{
char *name, *build_id_filename;
@@ -1343,23 +1357,7 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
@@ -1342,23 +1356,7 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
xfree (name);
}
else

View File

@ -9,7 +9,7 @@ Subject: gdb-6.6-buildid-locate.patch
diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
--- a/bfd/libbfd-in.h
+++ b/bfd/libbfd-in.h
@@ -115,7 +115,7 @@ static inline char *
@@ -110,7 +110,7 @@ static inline char *
bfd_strdup (const char *str)
{
size_t len = strlen (str) + 1;
@ -21,7 +21,7 @@ diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -121,7 +121,7 @@ static inline char *
@@ -116,7 +116,7 @@ static inline char *
bfd_strdup (const char *str)
{
size_t len = strlen (str) + 1;
@ -33,7 +33,7 @@ diff --git a/bfd/libbfd.h b/bfd/libbfd.h
diff --git a/gdb/build-id.c b/gdb/build-id.c
--- a/gdb/build-id.c
+++ b/gdb/build-id.c
@@ -24,13 +24,71 @@
@@ -24,14 +24,72 @@
#include "gdbsupport/gdb_vecs.h"
#include "symfile.h"
#include "objfiles.h"
@ -46,6 +46,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
+#include "gdb_bfd.h"
+#include "gdbcmd.h"
#include "gdbcore.h"
#include "cli/cli-style.h"
+#include "inferior.h"
+#include "objfiles.h"
+#include "observable.h"
@ -104,9 +105,9 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
-build_id_bfd_get (bfd *abfd)
+build_id_bfd_shdr_get (bfd *abfd)
{
if (!bfd_check_format (abfd, bfd_object)
&& !bfd_check_format (abfd, bfd_core))
@@ -43,6 +101,348 @@ build_id_bfd_get (bfd *abfd)
/* Dynamic objfiles such as ones created by JIT reader API
have no underlying bfd structure (that is, objfile->obfd
@@ -50,6 +108,348 @@ build_id_bfd_get (bfd *abfd)
return NULL;
}
@ -455,7 +456,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
/* See build-id.h. */
int
@@ -51,7 +451,7 @@ build_id_verify (bfd *abfd, size_t check_len, const bfd_byte *check)
@@ -58,7 +458,7 @@ build_id_verify (bfd *abfd, size_t check_len, const bfd_byte *check)
const struct bfd_build_id *found;
int retval = 0;
@ -464,7 +465,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
if (found == NULL)
warning (_("File \"%s\" has no build-id, file skipped"),
@@ -66,63 +466,166 @@ build_id_verify (bfd *abfd, size_t check_len, const bfd_byte *check)
@@ -73,63 +473,166 @@ build_id_verify (bfd *abfd, size_t check_len, const bfd_byte *check)
return retval;
}
@ -561,8 +562,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
- if (separate_debug_file_debug)
- gdb_printf (gdb_stdlog, _(" no, unable to open.\n"));
+ struct stat statbuf_trash;
- return {};
+
+ /* `access' automatically dereferences LINK. */
+ if (lstat (link.c_str (), &statbuf_trash) != 0)
+ {
@ -597,7 +597,8 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
+ {
+ if (separate_debug_file_debug)
+ gdb_printf (gdb_stdlog, _(" no, unable to open.\n"));
+
- return {};
+ continue;
+ }
+
@ -628,13 +629,13 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
+ /* If none of the real files is found report as missing file
+ always the non-.%u-suffixed file. */
+ std::string link0 = orig_link;
+
- return {};
+ /* If the symlink has target request to install the target.
+ BASE-debuginfo.rpm contains the symlink but BASE.rpm may be missing.
+ https://bugzilla.redhat.com/show_bug.cgi?id=981154 */
+ std::string link0_resolved (link_resolve (link0.c_str (), 0));
- return {};
+
+ if (link_all.empty ())
+ link_all = link0_resolved;
+ else
@ -664,7 +665,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
}
/* Common code for finding BFDs of a given build-id. This function
@@ -131,7 +634,7 @@ build_id_to_debug_bfd_1 (const std::string &link, size_t build_id_len,
@@ -138,7 +641,7 @@ build_id_to_debug_bfd_1 (const std::string &link, size_t build_id_len,
static gdb_bfd_ref_ptr
build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id,
@ -673,7 +674,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
{
/* Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will
cause "/.build-id/..." lookups. */
@@ -154,16 +657,17 @@ build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id,
@@ -161,16 +664,17 @@ build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id,
if (size > 0)
{
size--;
@ -694,7 +695,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
if (debug_bfd != NULL)
return debug_bfd;
@@ -174,7 +678,7 @@ build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id,
@@ -181,7 +685,7 @@ build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id,
if (!gdb_sysroot.empty ())
{
link = gdb_sysroot + link;
@ -703,7 +704,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
if (debug_bfd != NULL)
return debug_bfd;
}
@@ -183,30 +687,660 @@ build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id,
@@ -190,31 +694,663 @@ build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id,
return {};
}
@ -721,6 +722,8 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
+ return result;
+}
+
+void debug_flush_missing (void);
+
+#ifdef HAVE_LIBRPM
+
+#include <rpm/rpmlib.h>
@ -1220,7 +1223,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
+}
+
+static void
+debug_print_executable_changed (void)
+debug_print_executable_changed (struct program_space *pspace, bool reload_p)
+{
+#ifdef HAVE_LIBRPM
+ missing_rpm_change ();
@ -1356,9 +1359,10 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
/* See build-id.h. */
std::string
-find_separate_debug_file_by_buildid (struct objfile *objfile)
+find_separate_debug_file_by_buildid (struct objfile *objfile,
+ gdb::unique_xmalloc_ptr<char> *build_id_filename_return)
find_separate_debug_file_by_buildid (struct objfile *objfile,
- deferred_warnings *warnings)
+ deferred_warnings *warnings,
+ gdb::unique_xmalloc_ptr<char> *build_id_filename_return)
{
const struct bfd_build_id *build_id;
@ -1370,7 +1374,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
if (build_id != NULL)
{
if (separate_debug_file_debug)
@@ -214,8 +1348,21 @@ find_separate_debug_file_by_buildid (struct objfile *objfile)
@@ -222,8 +1358,21 @@ find_separate_debug_file_by_buildid (struct objfile *objfile,
_("\nLooking for separate debug info (build-id) for "
"%s\n"), objfile_name (objfile));
@ -1393,7 +1397,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
/* Prevent looping on a stripped .debug file. */
if (abfd != NULL
&& filename_cmp (bfd_get_filename (abfd.get ()),
@@ -228,3 +1375,22 @@ find_separate_debug_file_by_buildid (struct objfile *objfile)
@@ -243,3 +1392,22 @@ find_separate_debug_file_by_buildid (struct objfile *objfile,
return std::string ();
}
@ -1432,7 +1436,7 @@ diff --git a/gdb/build-id.h b/gdb/build-id.h
/* Return true if ABFD has NT_GNU_BUILD_ID matching the CHECK value.
Otherwise, issue a warning and return false. */
@@ -38,21 +39,26 @@ extern int build_id_verify (bfd *abfd,
@@ -38,14 +39,19 @@ extern int build_id_verify (bfd *abfd,
can be found, return NULL. */
extern gdb_bfd_ref_ptr build_id_to_debug_bfd (size_t build_id_len,
@ -1454,35 +1458,35 @@ diff --git a/gdb/build-id.h b/gdb/build-id.h
/* Find the separate debug file for OBJFILE, by using the build-id
associated with OBJFILE's BFD. If successful, returns the file name for the
separate debug file, otherwise, return an empty string. */
@@ -58,7 +64,8 @@ extern gdb_bfd_ref_ptr build_id_to_exec_bfd (size_t build_id_len,
will be printed. */
-extern std::string find_separate_debug_file_by_buildid
- (struct objfile *objfile);
+extern std::string find_separate_debug_file_by_buildid (struct objfile *objfile,
+ gdb::unique_xmalloc_ptr<char> *build_id_filename_return);
extern std::string find_separate_debug_file_by_buildid
- (struct objfile *objfile, deferred_warnings *warnings);
+ (struct objfile *objfile, deferred_warnings *warnings,
+ gdb::unique_xmalloc_ptr<char> *build_id_filename_return);
/* Return an hex-string representation of BUILD_ID. */
diff --git a/gdb/coffread.c b/gdb/coffread.c
--- a/gdb/coffread.c
+++ b/gdb/coffread.c
@@ -734,7 +734,8 @@ coff_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
/* Try to add separate debug file if no symbols table found. */
if (!objfile->has_partial_symbols ())
@@ -729,7 +729,7 @@ coff_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
{
- std::string debugfile = find_separate_debug_file_by_buildid (objfile);
+ std::string debugfile = find_separate_debug_file_by_buildid (objfile,
+ NULL);
deferred_warnings warnings;
std::string debugfile
- = find_separate_debug_file_by_buildid (objfile, &warnings);
+ = find_separate_debug_file_by_buildid (objfile, &warnings, NULL);
if (debugfile.empty ())
debugfile = find_separate_debug_file_by_debuglink (objfile);
debugfile
diff --git a/gdb/corelow.c b/gdb/corelow.c
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -22,6 +22,10 @@
#include <signal.h>
#include <fcntl.h>
#include "frame.h" /* required by inferior.h */
#include "frame.h"
+#include "auxv.h"
+#include "build-id.h"
+#include "elf/common.h"
@ -1490,7 +1494,7 @@ diff --git a/gdb/corelow.c b/gdb/corelow.c
#include "inferior.h"
#include "infrun.h"
#include "symtab.h"
@@ -391,6 +395,8 @@ add_to_thread_list (asection *asect, asection *reg_sect)
@@ -380,6 +384,8 @@ add_to_thread_list (asection *asect, asection *reg_sect, inferior *inf)
switch_to_thread (thr); /* Yes, make it current. */
}
@ -1499,7 +1503,7 @@ diff --git a/gdb/corelow.c b/gdb/corelow.c
/* Issue a message saying we have no core to debug, if FROM_TTY. */
static void
@@ -427,12 +433,14 @@ core_file_command (const char *filename, int from_tty)
@@ -563,12 +569,14 @@ rename_vmcore_idle_reg_sections (bfd *abfd, inferior *inf)
static void
locate_exec_from_corefile_build_id (bfd *abfd, int from_tty)
{
@ -1516,7 +1520,7 @@ diff --git a/gdb/corelow.c b/gdb/corelow.c
if (execbfd == nullptr)
{
@@ -460,7 +468,12 @@ locate_exec_from_corefile_build_id (bfd *abfd, int from_tty)
@@ -596,7 +604,12 @@ locate_exec_from_corefile_build_id (bfd *abfd, int from_tty)
exec_file_attach (bfd_get_filename (execbfd.get ()), from_tty);
symbol_file_add_main (bfd_get_filename (execbfd.get ()),
symfile_add_flag (from_tty ? SYMFILE_VERBOSE : 0));
@ -1529,7 +1533,7 @@ diff --git a/gdb/corelow.c b/gdb/corelow.c
}
/* See gdbcore.h. */
@@ -1325,4 +1338,11 @@ _initialize_corelow ()
@@ -1506,4 +1519,11 @@ _initialize_corelow ()
maintenance_print_core_file_backed_mappings,
_("Print core file's file-backed mappings."),
&maintenanceprintlist);
@ -1544,7 +1548,7 @@ diff --git a/gdb/corelow.c b/gdb/corelow.c
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -22037,6 +22037,27 @@ information files.
@@ -22296,6 +22296,27 @@ information files.
@end table
@ -1575,16 +1579,16 @@ diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
diff --git a/gdb/dwarf2/index-cache.c b/gdb/dwarf2/index-cache.c
--- a/gdb/dwarf2/index-cache.c
+++ b/gdb/dwarf2/index-cache.c
@@ -101,7 +101,7 @@ index_cache::store (dwarf2_per_objfile *per_objfile)
@@ -96,7 +96,7 @@ index_cache_store_context::index_cache_store_context (const index_cache &ic,
return;
/* Get build id of objfile. */
- const bfd_build_id *build_id = build_id_bfd_get (obj->obfd.get ());
+ const bfd_build_id *build_id = build_id_bfd_shdr_get (obj->obfd.get ());
- const bfd_build_id *build_id = build_id_bfd_get (per_bfd->obfd);
+ const bfd_build_id *build_id = build_id_bfd_shdr_get (per_bfd->obfd);
if (build_id == nullptr)
{
index_cache_debug ("objfile %s has no build id",
@@ -118,7 +118,8 @@ index_cache::store (dwarf2_per_objfile *per_objfile)
@@ -111,7 +111,8 @@ index_cache_store_context::index_cache_store_context (const index_cache &ic,
if (dwz != nullptr)
{
@ -1597,7 +1601,7 @@ diff --git a/gdb/dwarf2/index-cache.c b/gdb/dwarf2/index-cache.c
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -5328,7 +5328,7 @@ get_gdb_index_contents_from_section (objfile *obj, T *section_owner)
@@ -3355,7 +3355,7 @@ get_gdb_index_contents_from_section (objfile *obj, T *section_owner)
static gdb::array_view<const gdb_byte>
get_gdb_index_contents_from_cache (objfile *obj, dwarf2_per_bfd *dwarf2_per_bfd)
{
@ -1606,7 +1610,7 @@ diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
if (build_id == nullptr)
return {};
@@ -5341,7 +5341,7 @@ get_gdb_index_contents_from_cache (objfile *obj, dwarf2_per_bfd *dwarf2_per_bfd)
@@ -3368,7 +3368,7 @@ get_gdb_index_contents_from_cache (objfile *obj, dwarf2_per_bfd *dwarf2_per_bfd)
static gdb::array_view<const gdb_byte>
get_gdb_index_contents_from_cache_dwz (objfile *obj, dwz_file *dwz)
{
@ -1618,18 +1622,19 @@ diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
diff --git a/gdb/elfread.c b/gdb/elfread.c
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -1213,7 +1213,9 @@ elf_symfile_read_dwarf2 (struct objfile *objfile,
&& objfile->separate_debug_objfile == NULL
&& objfile->separate_debug_objfile_backlink == NULL)
@@ -1220,8 +1220,10 @@ elf_symfile_read_dwarf2 (struct objfile *objfile,
{
- std::string debugfile = find_separate_debug_file_by_buildid (objfile);
deferred_warnings warnings;
+ gdb::unique_xmalloc_ptr<char> build_id_filename;
+ std::string debugfile
+ = find_separate_debug_file_by_buildid (objfile, &build_id_filename);
std::string debugfile
- = find_separate_debug_file_by_buildid (objfile, &warnings);
+ = find_separate_debug_file_by_buildid (objfile, &warnings,
+ &build_id_filename);
if (debugfile.empty ())
debugfile = find_separate_debug_file_by_debuglink (objfile);
@@ -1229,7 +1231,7 @@ elf_symfile_read_dwarf2 (struct objfile *objfile,
debugfile = find_separate_debug_file_by_debuglink (objfile, &warnings);
@@ -1239,7 +1241,7 @@ elf_symfile_read_dwarf2 (struct objfile *objfile,
{
has_dwarf2 = false;
const struct bfd_build_id *build_id
@ -1638,7 +1643,7 @@ diff --git a/gdb/elfread.c b/gdb/elfread.c
const char *filename = bfd_get_filename (objfile->obfd.get ());
if (build_id != nullptr)
@@ -1256,6 +1258,11 @@ elf_symfile_read_dwarf2 (struct objfile *objfile,
@@ -1265,6 +1267,11 @@ elf_symfile_read_dwarf2 (struct objfile *objfile,
has_dwarf2 = true;
}
}
@ -1649,7 +1654,7 @@ diff --git a/gdb/elfread.c b/gdb/elfread.c
+ debug_print_missing (objfile_name (objfile), build_id_filename.get ());
}
}
}
/* If all the methods to collect the debuginfo failed, print the
diff --git a/gdb/exec.c b/gdb/exec.c
--- a/gdb/exec.c
+++ b/gdb/exec.c
@ -1674,8 +1679,8 @@ diff --git a/gdb/exec.c b/gdb/exec.c
diff --git a/gdb/objfiles.h b/gdb/objfiles.h
--- a/gdb/objfiles.h
+++ b/gdb/objfiles.h
@@ -786,6 +786,10 @@ struct objfile
bool skip_jit_symbol_lookup = false;
@@ -884,6 +884,10 @@ struct objfile
bool object_format_has_copy_relocs = false;
};
+/* This file was loaded according to the BUILD_ID_CORE_LOADS rules. */
@ -1709,7 +1714,7 @@ diff --git a/gdb/python/py-objfile.c b/gdb/python/py-objfile.c
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -45,6 +45,7 @@
@@ -44,6 +44,7 @@
#include "auxv.h"
#include "gdb_bfd.h"
#include "probe.h"
@ -1717,7 +1722,7 @@ diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
#include <map>
@@ -1319,9 +1320,51 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
@@ -1318,9 +1319,51 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
continue;
}
@ -1775,7 +1780,7 @@ diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
diff --git a/gdb/source.c b/gdb/source.c
--- a/gdb/source.c
+++ b/gdb/source.c
@@ -1196,7 +1196,7 @@ open_source_file (struct symtab *s)
@@ -1167,7 +1167,7 @@ open_source_file (struct symtab *s)
}
const struct bfd_build_id *build_id
@ -1787,7 +1792,7 @@ diff --git a/gdb/source.c b/gdb/source.c
diff --git a/gdb/symfile.h b/gdb/symfile.h
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -342,12 +342,18 @@ bool expand_symtabs_matching
@@ -357,12 +357,18 @@ bool expand_symtabs_matching
void map_symbol_filenames (gdb::function_view<symbol_filename_ftype> fun,
bool need_fullname);
@ -1809,7 +1814,7 @@ diff --git a/gdb/symfile.h b/gdb/symfile.h
diff --git a/gdb/testsuite/gdb.base/corefile.exp b/gdb/testsuite/gdb.base/corefile.exp
--- a/gdb/testsuite/gdb.base/corefile.exp
+++ b/gdb/testsuite/gdb.base/corefile.exp
@@ -349,3 +349,33 @@ gdb_test_multiple "core-file $corefile" $test {
@@ -347,3 +347,33 @@ gdb_test_multiple "core-file $corefile" $test {
pass $test
}
}
@ -1846,7 +1851,7 @@ diff --git a/gdb/testsuite/gdb.base/corefile.exp b/gdb/testsuite/gdb.base/corefi
diff --git a/gdb/testsuite/gdb.base/gdbinit-history.exp b/gdb/testsuite/gdb.base/gdbinit-history.exp
--- a/gdb/testsuite/gdb.base/gdbinit-history.exp
+++ b/gdb/testsuite/gdb.base/gdbinit-history.exp
@@ -185,7 +185,8 @@ proc test_empty_history_filename { } {
@@ -179,7 +179,8 @@ proc test_empty_history_filename { } {
global env
global gdb_prompt
@ -1870,17 +1875,17 @@ diff --git a/gdb/testsuite/gdb.base/new-ui-pending-input.exp b/gdb/testsuite/gdb
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -217,7 +217,8 @@ if ![info exists INTERNAL_GDBFLAGS] {
"-nw" \
@@ -226,7 +226,8 @@ if ![info exists INTERNAL_GDBFLAGS] {
"-nx" \
"-q" \
{-iex "set height 0"} \
- {-iex "set width 0"}]]
+ {-iex "set width 0"} \
+ {-iex "set build-id-verbose 0"}]]
set INTERNAL_GDBFLAGS [append_gdb_data_directory_option $INTERNAL_GDBFLAGS]
}
@@ -2349,6 +2350,17 @@ proc default_gdb_start { } {
# If DEBUGINFOD_URLS is set, gdb will try to download sources and
# debug info for f.i. system libraries. Prevent this.
@@ -2434,6 +2435,17 @@ proc default_gdb_start { } {
}
}
@ -1901,7 +1906,7 @@ diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp
--- a/gdb/testsuite/lib/mi-support.exp
+++ b/gdb/testsuite/lib/mi-support.exp
@@ -330,6 +330,16 @@ proc default_mi_gdb_start { { flags {} } } {
@@ -321,6 +321,16 @@ proc default_mi_gdb_start { { flags {} } } {
warning "Couldn't set the width to 0."
}
}

View File

@ -9,7 +9,7 @@ Subject: gdb-6.6-testsuite-timeouts.patch
diff --git a/gdb/testsuite/gdb.base/annota1.exp b/gdb/testsuite/gdb.base/annota1.exp
--- a/gdb/testsuite/gdb.base/annota1.exp
+++ b/gdb/testsuite/gdb.base/annota1.exp
@@ -39,6 +39,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb
@@ -37,6 +37,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb
clean_restart ${binfile}
@ -21,7 +21,7 @@ diff --git a/gdb/testsuite/gdb.base/annota1.exp b/gdb/testsuite/gdb.base/annota1
diff --git a/gdb/testsuite/gdb.base/annota3.exp b/gdb/testsuite/gdb.base/annota3.exp
--- a/gdb/testsuite/gdb.base/annota3.exp
+++ b/gdb/testsuite/gdb.base/annota3.exp
@@ -38,6 +38,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb
@@ -36,6 +36,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb
clean_restart ${binfile}

View File

@ -0,0 +1,47 @@
From 40b2857e42b477832ca7fc2771b6cde910e22f05 Mon Sep 17 00:00:00 2001
From: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
Date: Tue, 23 Jan 2024 14:11:33 -0300
Subject: [PATCH 4/7] gdb/arm: Fix epilogue frame id
arm_epilogue_frame_this_id has a comment saying that it fall backs to using
the current PC if the function start address can't be identified, but it
actually uses only the PC to make the frame id.
This patch makes the code match the comment. Another hint that it's what
is intended is that arm_prologue_this_id, a function almost identical to
it, does that.
The problem was found by code inspection. It fixes the following testsuite
failures:
FAIL: gdb.base/unwind-on-each-insn.exp: foo: instruction 9: check frame-id matches
FAIL: gdb.reverse/solib-reverse.exp: reverse-next third shr1
FAIL: gdb.reverse/solib-reverse.exp: reverse-next second shr1
FAIL: gdb.reverse/solib-reverse.exp: reverse-next first shr1
FAIL: gdb.reverse/solib-reverse.exp: reverse-next generic
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 into solib function two
FAIL: gdb.reverse/solib-reverse.exp: reverse-step within solib function two
Tested on arm-linux-gnueabi-hf.
---
gdb/arm-tdep.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 3b1682a2aea..21dad198dc7 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -3252,7 +3252,7 @@ arm_epilogue_frame_this_id (frame_info_ptr this_frame,
arm_gdbarch_tdep *tdep
= gdbarch_tdep<arm_gdbarch_tdep> (get_frame_arch (this_frame));
- *this_id = frame_id_build (arm_cache_get_prev_sp_value (cache, tdep), pc);
+ *this_id = frame_id_build (arm_cache_get_prev_sp_value (cache, tdep), func);
}
/* Implementation of function hook 'prev_register' in
--
2.35.3

View File

@ -0,0 +1,77 @@
From 51a5415b3313470cb62fda7ad6762fc1c41c8cbd Mon Sep 17 00:00:00 2001
From: Simon Marchi <simon.marchi@efficios.com>
Date: Tue, 7 Nov 2023 11:11:18 -0500
Subject: [PATCH] gdb/arm: remove thumb bit in arm_adjust_breakpoint_address
When compiling gdb with -fsanitize=address on ARM, I get a crash in test
gdb.arch/arm-disp-step.exp, reproduced easily with:
$ ./gdb -nx -q --data-directory=data-directory testsuite/outputs/gdb.arch/arm-disp-step/arm-disp-step -ex "break *test_call_end"
Reading symbols from testsuite/outputs/gdb.arch/arm-disp-step/arm-disp-step...
=================================================================
==23295==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xb4a14fd1 at pc 0x01a48871 bp 0xbeab8490 sp 0xbeab8494
Since it doesn't require running the program, it can be reproduced locally on a
dev machine other than ARM, after acquiring the test binary.
The length of the allocate buffer `buf` is 1, and we try to extract an
integer of size 2 from it. The length of 1 comes from the subtraction
`bpaddr - boundary`. Normally, on ARM, all instructions are aligned on
a multiple of 2, so it's weird for this subtraction to result in 1. In
this case, boundary comes from the result of find_pc_partial_function
returning 0x549:
(gdb) p/x bpaddr
$2 = 0x54a
(gdb) p/x boundary
$3 = 0x549
(gdb) p/x bpaddr - boundary
$4 = 0x1
0x549 is the address of the test_call_subr label, 0x548, with the thumb
bit enabled. Before doing some math with the address, I think we need
to strip the thumb bit, like is done elsewhere (for instance for bpaddr
earlier in the same function).
I wonder if find_pc_partial_function should do that itself, in order to
return an address that is suitable for arithmetic. In any case, that
would be a change with a broad impact, so for now just fix the issue
locally.
After the patch:
$ ./gdb -nx -q --data-directory=data-directory testsuite/outputs/gdb.arch/arm-disp-step/arm-disp-step -ex "break *test_call_end"
Reading symbols from testsuite/outputs/gdb.arch/arm-disp-step/arm-disp-step...
Breakpoint 1 at 0x54a: file /home/smarchi/src/binutils-gdb/gdb/testsuite/gdb.arch/arm-disp-step.S, line 103.
Change-Id: I74fc458dbea0d2c1e1f5eadd90755188df089288
Approved-By: Luis Machado <luis.machado@arm.com>
---
gdb/arm-tdep.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 21dad198dc7..e61342f3ccb 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -5340,9 +5340,12 @@ arm_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr)
bpaddr = gdbarch_addr_bits_remove (gdbarch, bpaddr);
- if (find_pc_partial_function (bpaddr, NULL, &func_start, NULL)
- && func_start > boundary)
- boundary = func_start;
+ if (find_pc_partial_function (bpaddr, NULL, &func_start, NULL))
+ {
+ func_start = gdbarch_addr_bits_remove (gdbarch, func_start);
+ if (func_start > boundary)
+ boundary = func_start;
+ }
/* Search for a candidate IT instruction. We have to do some fancy
footwork to distinguish a real IT instruction from the second
base-commit: eafca1ce3d589c731927e5481199db715bcbeff3
--
2.35.3

View File

@ -0,0 +1,219 @@
From 7973eaf11e33ddd405830b9bd29495991db5901d Mon Sep 17 00:00:00 2001
From: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
Date: Mon, 26 Feb 2024 19:11:45 -0300
Subject: [PATCH 2/7] gdb/arm: Remove tpidruro register from non-FreeBSD target
descriptions
Commit 92d48a1e4eac ("Add an arm-tls feature which includes the tpidruro
register from CP15.") introduced the org.gnu.gdb.arm.tls feature, which
adds the tpidruro register, and unconditionally enabled it in
aarch32_create_target_description.
In Linux, the tpidruro register isn't available via ptrace in the 32-bit
kernel but it is available for an aarch32 program running under an arm64
kernel via the ptrace compat interface. This isn't currently implemented
however, which causes GDB on arm-linux with 64-bit kernel to list the
register but show it as unavailable, as reported by Tom de Vries:
$ gdb -q -batch a.out -ex start -ex 'p $tpidruro'
Temporary breakpoint 1 at 0x512
Temporary breakpoint 1, 0xaaaaa512 in main ()
$1 = <unavailable>
Simon Marchi then clarified:
> The only time we should be seeing some "unavailable" registers or memory
> is in the context of tracepoints, for things that are not collected.
> Seeing an unavailable register here is a sign that something is not
> right.
Therefore, disable the TLS feature in aarch32 target descriptions for Linux
and NetBSD targets (the latter also doesn't seem to support accessing
tpidruro either, based on a quick look at arm-netbsd-nat.c).
This patch fixes the following tests:
Running gdb.base/inline-frame-cycle-unwind.exp ...
FAIL: gdb.base/inline-frame-cycle-unwind.exp: cycle at level 3: backtrace when the unwind is broken at frame 3
FAIL: gdb.base/inline-frame-cycle-unwind.exp: cycle at level 5: backtrace when the unwind is broken at frame 5
FAIL: gdb.base/inline-frame-cycle-unwind.exp: cycle at level 1: backtrace when the unwind is broken at frame 1
Tested with Ubuntu 22.04.3 on armv8l-linux-gnueabihf in native,
native-gdbserver and native-extended-gdbserver targets with no regressions.
PR tdep/31418
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31418
Approved-By: John Baldwin <jhb@FreeBSD.org>
---
gdb/aarch32-tdep.c | 15 ++++++++++-----
gdb/aarch32-tdep.h | 2 +-
gdb/aarch64-linux-nat.c | 2 +-
gdb/arch/aarch32.c | 5 +++--
gdb/arch/aarch32.h | 2 +-
gdb/arm-fbsd-tdep.c | 2 +-
gdb/arm-linux-nat.c | 2 +-
gdb/arm-linux-tdep.c | 2 +-
gdb/arm-netbsd-nat.c | 2 +-
gdbserver/linux-aarch32-tdesc.cc | 2 +-
10 files changed, 21 insertions(+), 15 deletions(-)
diff --git a/gdb/aarch32-tdep.c b/gdb/aarch32-tdep.c
index bfa88a96522..395328936e4 100644
--- a/gdb/aarch32-tdep.c
+++ b/gdb/aarch32-tdep.c
@@ -22,15 +22,20 @@
#include "gdbsupport/common-regcache.h"
#include "arch/aarch32.h"
-static struct target_desc *tdesc_aarch32;
+static struct target_desc *tdesc_aarch32_list[2];
/* See aarch32-tdep.h. */
const target_desc *
-aarch32_read_description ()
+aarch32_read_description (bool tls)
{
- if (tdesc_aarch32 == nullptr)
- tdesc_aarch32 = aarch32_create_target_description ();
+ struct target_desc *tdesc = tdesc_aarch32_list[tls];
- return tdesc_aarch32;
+ if (tdesc == nullptr)
+ {
+ tdesc = aarch32_create_target_description (tls);
+ tdesc_aarch32_list[tls] = tdesc;
+ }
+
+ return tdesc;
}
diff --git a/gdb/aarch32-tdep.h b/gdb/aarch32-tdep.h
index bee4d4e9fc0..efc93351298 100644
--- a/gdb/aarch32-tdep.h
+++ b/gdb/aarch32-tdep.h
@@ -22,6 +22,6 @@ struct target_desc;
/* Get the AArch32 target description. */
-const target_desc *aarch32_read_description ();
+const target_desc *aarch32_read_description (bool tls);
#endif /* aarch32-tdep.h. */
diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
index 768748a20db..c680d6de0c9 100644
--- a/gdb/aarch64-linux-nat.c
+++ b/gdb/aarch64-linux-nat.c
@@ -887,7 +887,7 @@ aarch64_linux_nat_target::read_description ()
ret = ptrace (PTRACE_GETREGSET, tid, NT_ARM_VFP, &iovec);
if (ret == 0)
- return aarch32_read_description ();
+ return aarch32_read_description (false);
CORE_ADDR hwcap = linux_get_hwcap ();
CORE_ADDR hwcap2 = linux_get_hwcap2 ();
diff --git a/gdb/arch/aarch32.c b/gdb/arch/aarch32.c
index 5be2cc0156e..b7510ee41e9 100644
--- a/gdb/arch/aarch32.c
+++ b/gdb/arch/aarch32.c
@@ -25,7 +25,7 @@
/* See aarch32.h. */
target_desc *
-aarch32_create_target_description ()
+aarch32_create_target_description (bool tls)
{
target_desc_up tdesc = allocate_target_description ();
@@ -39,7 +39,8 @@ aarch32_create_target_description ()
/* Create a vfpv3 feature, then a blank NEON feature. */
regnum = create_feature_arm_arm_vfpv3 (tdesc.get (), regnum);
tdesc_create_feature (tdesc.get (), "org.gnu.gdb.arm.neon");
- regnum = create_feature_arm_arm_tls (tdesc.get (), regnum);
+ if (tls)
+ regnum = create_feature_arm_arm_tls (tdesc.get (), regnum);
return tdesc.release ();
}
diff --git a/gdb/arch/aarch32.h b/gdb/arch/aarch32.h
index 6b24ae94335..e06e260e370 100644
--- a/gdb/arch/aarch32.h
+++ b/gdb/arch/aarch32.h
@@ -22,6 +22,6 @@
/* Create the AArch32 target description. */
-target_desc *aarch32_create_target_description ();
+target_desc *aarch32_create_target_description (bool tls);
#endif /* aarch32.h. */
diff --git a/gdb/arm-fbsd-tdep.c b/gdb/arm-fbsd-tdep.c
index b46fa91d0a0..a4cea77f388 100644
--- a/gdb/arm-fbsd-tdep.c
+++ b/gdb/arm-fbsd-tdep.c
@@ -228,7 +228,7 @@ arm_fbsd_read_description_auxv (const gdb::optional<gdb::byte_vector> &auxv,
if (arm_hwcap & HWCAP_VFP)
{
if (arm_hwcap & HWCAP_NEON)
- return aarch32_read_description ();
+ return aarch32_read_description (tls);
else if ((arm_hwcap & (HWCAP_VFPv3 | HWCAP_VFPD32))
== (HWCAP_VFPv3 | HWCAP_VFPD32))
return arm_read_description (ARM_FP_TYPE_VFPV3, tls);
diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c
index 70c6bc684fa..07af23d3881 100644
--- a/gdb/arm-linux-nat.c
+++ b/gdb/arm-linux-nat.c
@@ -568,7 +568,7 @@ arm_linux_nat_target::read_description ()
/* NEON implies VFPv3-D32 or no-VFP unit. Say that we only support
Neon with VFPv3-D32. */
if (arm_hwcap & HWCAP_NEON)
- return aarch32_read_description ();
+ return aarch32_read_description (false);
else if ((arm_hwcap & (HWCAP_VFPv3 | HWCAP_VFPv3D16)) == HWCAP_VFPv3)
return arm_read_description (ARM_FP_TYPE_VFPV3, false);
diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c
index dfa816990ff..33748731cfd 100644
--- a/gdb/arm-linux-tdep.c
+++ b/gdb/arm-linux-tdep.c
@@ -740,7 +740,7 @@ arm_linux_core_read_description (struct gdbarch *gdbarch,
/* NEON implies VFPv3-D32 or no-VFP unit. Say that we only support
Neon with VFPv3-D32. */
if (arm_hwcap & HWCAP_NEON)
- return aarch32_read_description ();
+ return aarch32_read_description (false);
else if ((arm_hwcap & (HWCAP_VFPv3 | HWCAP_VFPv3D16)) == HWCAP_VFPv3)
return arm_read_description (ARM_FP_TYPE_VFPV3, false);
diff --git a/gdb/arm-netbsd-nat.c b/gdb/arm-netbsd-nat.c
index d83714a46c3..018964b010d 100644
--- a/gdb/arm-netbsd-nat.c
+++ b/gdb/arm-netbsd-nat.c
@@ -350,7 +350,7 @@ arm_netbsd_nat_target::read_description ()
len = sizeof(flag);
if (sysctlbyname("machdep.neon_present", &flag, &len, NULL, 0) == 0 && flag)
- return aarch32_read_description ();
+ return aarch32_read_description (false);
return arm_read_description (ARM_FP_TYPE_VFPV3, false);
}
diff --git a/gdbserver/linux-aarch32-tdesc.cc b/gdbserver/linux-aarch32-tdesc.cc
index e1380fa2a40..443f91e3585 100644
--- a/gdbserver/linux-aarch32-tdesc.cc
+++ b/gdbserver/linux-aarch32-tdesc.cc
@@ -32,7 +32,7 @@ aarch32_linux_read_description ()
{
if (tdesc_aarch32 == nullptr)
{
- tdesc_aarch32 = aarch32_create_target_description ();
+ tdesc_aarch32 = aarch32_create_target_description (false);
static const char *expedite_regs[] = { "r11", "sp", "pc", 0 };
init_target_desc (tdesc_aarch32, expedite_regs);
--
2.35.3

View File

@ -1,24 +0,0 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Nick Clifton <nickc@redhat.com>
Date: Wed, 11 Jan 2023 12:13:46 +0000
Subject: gdb-binutils29988-read_indexed_address.patch
;; Backport "Fix a potential illegal memory access in the BFD library..."
;; (Nick Clifton, binutils/29988)
PR 29988
* dwarf2.c (read_indexed_address): Fix check for an out of range
offset.
diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c
--- a/bfd/dwarf2.c
+++ b/bfd/dwarf2.c
@@ -1412,7 +1412,7 @@ read_indexed_address (uint64_t idx, struct comp_unit *unit)
offset += unit->dwarf_addr_offset;
if (offset < unit->dwarf_addr_offset
|| offset > file->dwarf_addr_size
- || file->dwarf_addr_size - offset < unit->offset_size)
+ || file->dwarf_addr_size - offset < unit->addr_size)
return 0;
info_ptr = file->dwarf_addr_buffer + offset;

View File

@ -1,188 +0,0 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Andrew Burgess <aburgess@redhat.com>
Date: Tue, 20 Jun 2023 09:46:35 +0100
Subject: gdb-bz2196395-debuginfod-legacy-openssl-crash.patch
;; Backport upstream commit f3eee5861743d635 to fix a crash triggered
;; when debuginfod makes use of particular openssl settings.
gdb/debuginfod: cleanup debuginfod earlier
A GDB crash was discovered on Fedora GDB that was tracked back to an
issue with the way that debuginfod is cleaned up.
The bug was reported on Fedora 37, 38, and 39. Here are the steps to
reproduce:
1. The file /etc/ssl/openssl.cnf contains the following lines:
[provider_sect]
default = default_sect
##legacy = legacy_sect
##
[default_sect]
activate = 1
##[legacy_sect]
##activate = 1
The bug will occur when the '##' characters are removed so that the
lines in question look like this:
[provider_sect]
default = default_sect
legacy = legacy_sect
[default_sect]
activate = 1
[legacy_sect]
activate = 1
2. Clean up any existing debuginfod cache data:
> rm -rf $HOME/.cache/debuginfod_client
3. Run GDB:
> gdb -nx -q -iex 'set trace-commands on' \
-iex 'set debuginfod enabled on' \
-iex 'set confirm off' \
-ex 'start' -ex 'quit' /bin/ls
+set debuginfod enabled on
+set confirm off
Reading symbols from /bin/ls...
Downloading separate debug info for /usr/bin/ls
... snip ...
Temporary breakpoint 1, main (argc=1, argv=0x7fffffffde38) at ../src/ls.c:1646
1646 {
+quit
Fatal signal: Segmentation fault
----- Backtrace -----
... snip ...
So GDB ends up crashing during exit.
What's happening is that when debuginfod is initialised
debuginfod_begin is called (this is in the debuginfod library), this
in turn sets up libcurl, which makes use of openssl. Somewhere during
this setup process an at_exit function is registered to cleanup some
state.
Back in GDB the debuginfod_client object is managed using this code:
/* Deleter for a debuginfod_client. */
struct debuginfod_client_deleter
{
void operator() (debuginfod_client *c)
{
debuginfod_end (c);
}
};
using debuginfod_client_up
= std::unique_ptr<debuginfod_client, debuginfod_client_deleter>;
And then a global debuginfod_client_up is created to hold a pointer to
the debuginfod_client object. As a global this will be cleaned up
using the standard C++ global object destructor mechanism, which is
run after the at_exit handlers.
However, it is expected that when debuginfod_end is called the
debuginfod_client object will still be in a usable state, that is, we
don't expect the at_exit handlers to have run and started cleaning up
the library state.
To fix this issue we need to ensure that debuginfod_end is called
before the at_exit handlers have a chance to run.
This commit removes the debuginfod_client_up type, and instead has GDB
hold a raw pointer to the debuginfod_client object. We then make use
of GDB's make_final_cleanup to register a function that will call
debuginfod_end.
As GDB's final cleanups are called before exit is called, this means
that debuginfod_end will be called before the at_exit handlers are
called, and the crash identified above is resolved.
It's not obvious how this issue can easily be tested for. The bug does
not appear to manifest when using a local debuginfod server, so we'd
need to setup something more involved. For now I'm proposing this
patch without any associated tests.
diff --git a/gdb/debuginfod-support.c b/gdb/debuginfod-support.c
--- a/gdb/debuginfod-support.c
+++ b/gdb/debuginfod-support.c
@@ -96,20 +96,6 @@ struct user_data
ui_out::progress_update progress;
};
-/* Deleter for a debuginfod_client. */
-
-struct debuginfod_client_deleter
-{
- void operator() (debuginfod_client *c)
- {
- debuginfod_end (c);
- }
-};
-
-using debuginfod_client_up
- = std::unique_ptr<debuginfod_client, debuginfod_client_deleter>;
-
-
/* Convert SIZE into a unit suitable for use with progress updates.
SIZE should in given in bytes and will be converted into KB, MB, GB
or remain unchanged. UNIT will be set to "B", "KB", "MB" or "GB"
@@ -180,20 +166,45 @@ progressfn (debuginfod_client *c, long cur, long total)
return 0;
}
+/* Cleanup ARG, which is a debuginfod_client pointer. */
+
+static void
+cleanup_debuginfod_client (void *arg)
+{
+ debuginfod_client *client = static_cast<debuginfod_client *> (arg);
+ debuginfod_end (client);
+}
+
+/* Return a pointer to the single global debuginfod_client, initialising it
+ first if needed. */
+
static debuginfod_client *
get_debuginfod_client ()
{
- static debuginfod_client_up global_client;
+ static debuginfod_client *global_client = nullptr;
if (global_client == nullptr)
{
- global_client.reset (debuginfod_begin ());
+ global_client = debuginfod_begin ();
if (global_client != nullptr)
- debuginfod_set_progressfn (global_client.get (), progressfn);
+ {
+ /* It is important that we cleanup the debuginfod_client object
+ before calling exit. Some of the libraries used by debuginfod
+ make use of at_exit handlers to perform cleanup.
+
+ If we wrapped the debuginfod_client in a unique_ptr and relied
+ on its destructor to cleanup then this would be run as part of
+ the global C++ object destructors, which is after the at_exit
+ handlers, which is too late.
+
+ So instead, we make use of GDB's final cleanup mechanism. */
+ make_final_cleanup (cleanup_debuginfod_client, global_client);
+ debuginfod_set_progressfn (global_client, progressfn);
+ }
}
- return global_client.get ();
+ return global_client;
}
/* Check if debuginfod is enabled. If configured to do so, ask the user

View File

@ -1,68 +0,0 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Andrew Burgess <aburgess@redhat.com>
Date: Thu, 14 Sep 2023 13:06:26 +0100
Subject: gdb-bz2237392-dwarf-obstack-allocation.patch
;; Backport upstream commit 54392c4df604f20 to fix an incorrect
;; obstack allocation that wold lead to memory corruption.
gdb: fix buffer overflow in DWARF reader
In this commit:
commit 48ac197b0c209ccf1f2de9704eb6cdf7c5c73a8e
Date: Fri Nov 19 10:12:44 2021 -0700
Handle multiple addresses in call_site_target
a buffer overflow bug was introduced when the following code was
added:
CORE_ADDR *saved = XOBNEWVAR (&objfile->objfile_obstack, CORE_ADDR,
addresses.size ());
std::copy (addresses.begin (), addresses.end (), saved);
The definition of XOBNEWVAR is (from libiberty.h):
#define XOBNEWVAR(O, T, S) ((T *) obstack_alloc ((O), (S)))
So 'saved' is going to point to addresses.size () bytes of memory,
however, the std::copy will write addresses.size () number of
CORE_ADDR sized entries to the address pointed to by 'saved', this is
going to result in memory corruption.
The mistake is that we should have used XOBNEWVEC, which allocates a
vector of entries, the definition of XOBNEWVEC is:
#define XOBNEWVEC(O, T, N) \
((T *) obstack_alloc ((O), sizeof (T) * (N)))
Which means we will have set aside enough space to create a copy of
the contents of the addresses vector.
I'm not sure how to create a test for this problem, this issue cropped
up when debugging a particular i686 built binary, which just happened
to trigger a glibc assertion (likely due to random memory corruption),
debugging the same binary built for x86-64 appeared to work just fine.
Using valgrind on the failing GDB binary pointed straight to the cause
of the problem, and with this patch in place there are no longer
valgrind errors in this area.
If anyone has ideas for a test I'm happy to work on something.
Co-Authored-By: Keith Seitz <keiths@redhat.com>
Approved-By: Tom Tromey <tom@tromey.com>
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -12506,7 +12506,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
std::vector<CORE_ADDR> addresses;
dwarf2_ranges_read_low_addrs (ranges_offset, target_cu,
target_die->tag, addresses);
- CORE_ADDR *saved = XOBNEWVAR (&objfile->objfile_obstack, CORE_ADDR,
+ CORE_ADDR *saved = XOBNEWVEC (&objfile->objfile_obstack, CORE_ADDR,
addresses.size ());
std::copy (addresses.begin (), addresses.end (), saved);
call_site->target.set_loc_array (addresses.size (), saved);

View File

@ -1,102 +0,0 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Tom Tromey <tromey@adacore.com>
Date: Tue, 6 Dec 2022 12:07:12 -0700
Subject: gdb-bz2237515-debuginfod-double-free.patch
;; Backport upstream commit f96328accde1e63 to fix a potential double
;; free issue in the debuginfod code.
Avoid double-free with debuginfod
PR gdb/29257 points out a possible double free when debuginfod is in
use. Aside from some ugly warts in the symbol code (an ongoing
issue), the underlying issue in this particular case is that elfread.c
seems to assume that symfile_bfd_open will return NULL on error,
whereas in reality it throws an exception. As this code isn't
prepared for an exception, bad things result.
This patch fixes the problem by introducing a non-throwing variant of
symfile_bfd_open and using it in the affected places.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29257
diff --git a/gdb/elfread.c b/gdb/elfread.c
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -1222,10 +1222,12 @@ elf_symfile_read_dwarf2 (struct objfile *objfile,
if (!debugfile.empty ())
{
- gdb_bfd_ref_ptr debug_bfd (symfile_bfd_open (debugfile.c_str ()));
+ gdb_bfd_ref_ptr debug_bfd
+ (symfile_bfd_open_no_error (debugfile.c_str ()));
- symbol_file_add_separate (debug_bfd, debugfile.c_str (),
- symfile_flags, objfile);
+ if (debug_bfd != nullptr)
+ symbol_file_add_separate (debug_bfd, debugfile.c_str (),
+ symfile_flags, objfile);
}
else
{
@@ -1245,13 +1247,12 @@ elf_symfile_read_dwarf2 (struct objfile *objfile,
if (fd.get () >= 0)
{
/* File successfully retrieved from server. */
- gdb_bfd_ref_ptr debug_bfd (symfile_bfd_open (symfile_path.get ()));
+ gdb_bfd_ref_ptr debug_bfd
+ (symfile_bfd_open_no_error (symfile_path.get ()));
- if (debug_bfd == nullptr)
- warning (_("File \"%s\" from debuginfod cannot be opened as bfd"),
- filename);
- else if (build_id_verify (debug_bfd.get (), build_id->size,
- build_id->data))
+ if (debug_bfd != nullptr
+ && build_id_verify (debug_bfd.get (), build_id->size,
+ build_id->data))
{
symbol_file_add_separate (debug_bfd, symfile_path.get (),
symfile_flags, objfile);
diff --git a/gdb/symfile.c b/gdb/symfile.c
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -1744,6 +1744,23 @@ symfile_bfd_open (const char *name)
return sym_bfd;
}
+/* See symfile.h. */
+
+gdb_bfd_ref_ptr
+symfile_bfd_open_no_error (const char *name) noexcept
+{
+ try
+ {
+ return symfile_bfd_open (name);
+ }
+ catch (const gdb_exception_error &err)
+ {
+ warning ("%s", err.what ());
+ }
+
+ return nullptr;
+}
+
/* Return the section index for SECTION_NAME on OBJFILE. Return -1 if
the section was not found. */
diff --git a/gdb/symfile.h b/gdb/symfile.h
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -269,6 +269,11 @@ extern void set_initial_language (void);
extern gdb_bfd_ref_ptr symfile_bfd_open (const char *);
+/* Like symfile_bfd_open, but will not throw an exception on error.
+ Instead, it issues a warning and returns nullptr. */
+
+extern gdb_bfd_ref_ptr symfile_bfd_open_no_error (const char *) noexcept;
+
extern int get_section_index (struct objfile *, const char *);
extern int print_symbol_loading_p (int from_tty, int mainline, int full);

View File

@ -1,3 +1,8 @@
From 0bb6f49bb9ad577667075550ca2ad4cb49931078 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 18 Apr 2024 14:27:04 +0200
Subject: [PATCH 2/2] gdb-cli-add-ignore-errors-command
[gdb/cli] Add ignore-errors command
While trying to reproduce a failing test-case from the testsuite on the
@ -60,28 +65,29 @@ gdb/testsuite/ChangeLog:
* gdb.base/ignore-errors.exp: New test.
* gdb.base/ignore-errors.gdb: New command file.
---
gdb/cli/cli-cmds.c | 35 ++++++++++++++++++++++++++++++++
gdb/doc/gdb.texinfo | 8 +++++++-
gdb/testsuite/gdb.base/ignore-errors.exp | 24 ++++++++++++++++++++++
gdb/cli/cli-cmds.c | 35 ++++++++++++++++++++++++
gdb/doc/gdb.texinfo | 8 +++++-
gdb/testsuite/gdb.base/ignore-errors.exp | 24 ++++++++++++++++
gdb/testsuite/gdb.base/ignore-errors.gdb | 2 ++
4 files changed, 68 insertions(+), 1 deletion(-)
create mode 100644 gdb/testsuite/gdb.base/ignore-errors.exp
create mode 100644 gdb/testsuite/gdb.base/ignore-errors.gdb
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index 31d398cb13b..4eff591b3df 100644
index cfe7b71b0b7..0ae5530c558 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -39,6 +39,7 @@
#include "gdbsupport/filestuff.h"
@@ -40,6 +40,7 @@
#include "location.h"
#include "block.h"
#include "valprint.h"
+#include "event-top.h"
#include "ui-out.h"
#include "interps.h"
@@ -2399,6 +2400,34 @@ gdb_maint_setting_str_internal_fn (struct gdbarch *gdbarch,
return str_value_from_setting (*show_cmd->var, gdbarch);
@@ -2544,6 +2545,34 @@ shell_internal_fn (struct gdbarch *gdbarch,
return value::allocate_optimized_out (int_type);
}
+/* Completer for "ignore-errors". */
@ -115,7 +121,7 @@ index 31d398cb13b..4eff591b3df 100644
void _initialize_cli_cmds ();
void
_initialize_cli_cmds ()
@@ -2786,4 +2815,10 @@ when GDB is started."), GDBINIT).release ();
@@ -2942,4 +2971,10 @@ when GDB is started."), GDBINIT).release ();
c = add_cmd ("source", class_support, source_command,
source_help_text, &cmdlist);
set_cmd_completer (c, filename_completer);
@ -127,10 +133,10 @@ index 31d398cb13b..4eff591b3df 100644
+ set_cmd_completer (c, ignore_errors_command_completer);
}
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 1cf3550885e..68e11585942 100644
index 1abf91c4470..c277c16297c 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -27680,7 +27680,8 @@ The lines in a command file are generally executed sequentially,
@@ -29250,7 +29250,8 @@ The lines in a command file are generally executed sequentially,
unless the order of execution is changed by one of the
@emph{flow-control commands} described below. The commands are not
printed as they are executed. An error in any command terminates
@ -140,7 +146,7 @@ index 1cf3550885e..68e11585942 100644
@value{GDBN} first searches for @var{filename} in the current directory.
If the file is not found there, and @var{filename} does not specify a
@@ -27775,6 +27776,11 @@ the controlling expression.
@@ -29345,6 +29346,11 @@ the controlling expression.
@item end
Terminate the block of commands that are the body of @code{if},
@code{else}, or @code{while} flow-control commands.
@ -190,3 +196,6 @@ index 00000000000..5962ff49b11
@@ -0,0 +1,2 @@
+ignore-errors run
+echo here\n
--
2.35.3

View File

@ -1,69 +0,0 @@
From 3f5ef7bf512c7565279832bad3d5c743e9d8ae4b Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Wed, 24 May 2023 10:53:02 +0200
Subject: [PATCH 1/4] [gdb/cli] Handle pending ^C after rl_callback_read_char
for readline 7
In commit faf01aee1d0 ("[gdb] Handle pending ^C after rl_callback_read_char")
we handled a problem (described in detail in that commit) for readline >= 8
using public readline functions rl_pending_signal and rl_check_signals.
For readline 7 (note that we require at least readline 7 so there's no need to
worry about readline 6), there was no fix though, because rl_check_signals was
not available.
Fix this by instead using the private readline function _rl_signal_handler.
There is precedent for using private readline variables and functions, but
it's something we want to get rid of (PR build/10723). Nevertheless, I think
we can allow this specific instance because it's not used when building
against readline >= 8.
[ In the meanwhile, a fix was committed in the devel branch of the readline
repo, contained in commit 8d0c439 ("rollup of changes since readline-8.2"),
first proposed here (
https://lists.gnu.org/archive/html/bug-readline/2022-10/msg00008.html ). ]
Tested on x86_64-linux, against system readline 7.0 on openSUSE Leap 15.4.
PR cli/27813
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=27813
---
gdb/event-top.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/gdb/event-top.c b/gdb/event-top.c
index 9181e4bdcff..399582698c1 100644
--- a/gdb/event-top.c
+++ b/gdb/event-top.c
@@ -134,6 +134,9 @@ static struct async_signal_handler *async_sigterm_token;
character is processed. */
void (*after_char_processing_hook) (void);
+#if RL_VERSION_MAJOR == 7
+EXTERN_C void _rl_signal_handler (int);
+#endif
/* Wrapper function for calling into the readline library. This takes
care of a couple things:
@@ -200,8 +203,14 @@ gdb_rl_callback_read_char_wrapper_noexcept () noexcept
pending signal. I'm not sure if that's possible, but it seems
better to handle the scenario than to assert. */
rl_check_signals ();
+#elif RL_VERSION_MAJOR == 7
+ /* Unfortunately, rl_check_signals is not available. Use private
+ function _rl_signal_handler instead. */
+
+ while (rl_pending_signal () != 0)
+ _rl_signal_handler (rl_pending_signal ());
#else
- /* Unfortunately, rl_check_signals is not available. */
+#error "Readline major version >= 7 expected"
#endif
if (after_char_processing_hook)
(*after_char_processing_hook) ();
base-commit: 7f7fcd7031430953f41b284069d1ed0cf3c8734a
--
2.35.3

View File

@ -19,7 +19,7 @@ Date: Wed Sep 25 11:52:50 2013 +0000
diff --git a/gdb/testsuite/gdb.base/solib-symbol.exp b/gdb/testsuite/gdb.base/solib-symbol.exp
--- a/gdb/testsuite/gdb.base/solib-symbol.exp
+++ b/gdb/testsuite/gdb.base/solib-symbol.exp
@@ -29,6 +29,7 @@ set testfile "solib-symbol-main"
@@ -27,6 +27,7 @@ set testfile "solib-symbol-main"
set srcfile ${srcdir}/${subdir}/${testfile}.c
set binfile [standard_output_file ${testfile}]
set bin_flags [list debug shlib=${binfile_lib}]
@ -27,16 +27,14 @@ diff --git a/gdb/testsuite/gdb.base/solib-symbol.exp b/gdb/testsuite/gdb.base/so
if { [gdb_compile_shlib ${srcfile_lib} ${binfile_lib} $lib_flags] != ""
|| [gdb_compile ${srcfile} ${binfile} executable $bin_flags] != "" } {
@@ -66,8 +67,26 @@ gdb_test "br foo2" \
@@ -61,4 +62,28 @@ gdb_test "br foo2" \
"Breakpoint.*: foo2. .2 locations..*" \
"foo2 in mdlib"
-gdb_exit
+# Test GDB warns for shared libraris which have not been found.
-return 0
+
+gdb_test "info sharedlibrary" "/${libname}.*"
+
+clean_restart ${executable}
+gdb_breakpoint "main"
+gdb_run_cmd
@ -49,10 +47,12 @@ diff --git a/gdb/testsuite/gdb.base/solib-symbol.exp b/gdb/testsuite/gdb.base/so
+ pass $test
+ }
+}
+
+clean_restart ${executable}
+gdb_test_no_output "set solib-absolute-prefix /doESnotEXIST"
+gdb_breakpoint "main"
+gdb_run_cmd
+gdb_test "" "warning: Could not load shared library symbols for \[0-9\]+ libraries,.*\r\nBreakpoint \[0-9\]+, main .*" \
+ "warning for missing libraries"
+
gdb_exit

View File

@ -0,0 +1,150 @@
From b96d3adafdb636898913710ec40ee86647665ae8 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Fri, 3 May 2024 09:37:19 +0200
Subject: [PATCH 24/48] [gdb/exp] Fix cast handling for indirection
Consider a test-case compiled without debug info, containing:
...
char a = 'a';
char *
a_loc (void)
{
return &a;
}
...
We get:
...
(gdb) p (char)*a_loc ()
Cannot access memory at address 0x10
...
There's a bug in unop_ind_base_operation::evaluate that evaluates
"(char)*a_loc ()" the same as:
...
(gdb) p (char)*(char)a_loc ()
Cannot access memory at address 0x10
...
Fix this by instead doing:
...
(gdb) p (char)*a_loc ()
'a_loc' has unknown return type; cast the call to its declared return type
...
Tested on x86_64-linux.
PR exp/31693
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31693
---
gdb/expop.h | 5 +--
gdb/testsuite/gdb.base/cast-indirection.c | 31 ++++++++++++++++
gdb/testsuite/gdb.base/cast-indirection.exp | 41 +++++++++++++++++++++
3 files changed, 74 insertions(+), 3 deletions(-)
create mode 100644 gdb/testsuite/gdb.base/cast-indirection.c
create mode 100644 gdb/testsuite/gdb.base/cast-indirection.exp
diff --git a/gdb/expop.h b/gdb/expop.h
index 25769d5b810..25d50fe00d0 100644
--- a/gdb/expop.h
+++ b/gdb/expop.h
@@ -1513,9 +1513,8 @@ class unop_ind_base_operation
struct expression *exp,
enum noside noside) override
{
- if (expect_type != nullptr && expect_type->code () == TYPE_CODE_PTR)
- expect_type = check_typedef (expect_type)->target_type ();
- value *val = std::get<0> (m_storage)->evaluate (expect_type, exp, noside);
+ value *val
+ = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
return eval_op_ind (expect_type, exp, noside, val);
}
diff --git a/gdb/testsuite/gdb.base/cast-indirection.c b/gdb/testsuite/gdb.base/cast-indirection.c
new file mode 100644
index 00000000000..d59c66ead35
--- /dev/null
+++ b/gdb/testsuite/gdb.base/cast-indirection.c
@@ -0,0 +1,31 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2024 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/>. */
+
+char a = 'a';
+
+char *
+a_loc (void)
+{
+ return &a;
+}
+
+int
+main (void)
+{
+ int res = *a_loc () == 'a';
+ return !res;
+}
diff --git a/gdb/testsuite/gdb.base/cast-indirection.exp b/gdb/testsuite/gdb.base/cast-indirection.exp
new file mode 100644
index 00000000000..f1fe4302d27
--- /dev/null
+++ b/gdb/testsuite/gdb.base/cast-indirection.exp
@@ -0,0 +1,41 @@
+# Copyright (C) 2024 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 "p (char)*a_loc ()" is handled as "p (char)*(char *)a_loc ()".
+
+standard_testfile
+
+if { [prepare_for_testing "failed to prepare" $testfile $srcfile \
+ {nodebug}] == -1} {
+ return -1
+}
+
+if ![runto_main] {
+ return -1
+}
+
+gdb_test "p a_loc ()" \
+ "'a_loc' has unknown return type; cast the call to its declared return type"
+
+gdb_test "p *a_loc ()" \
+ "'a_loc' has unknown return type; cast the call to its declared return type"
+
+gdb_test "p *(char *)a_loc ()" " = 97 'a'"
+
+gdb_test "p (char)*(char *)a_loc ()" " = 97 'a'"
+
+# Regression test for PR31693.
+gdb_test "p (char)*a_loc ()" \
+ "'a_loc' has unknown return type; cast the call to its declared return type"
--
2.35.3

View File

@ -0,0 +1,365 @@
From 86e379aa22ba5e77ba0c6fa26588c5fd1d9e6abe Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Mon, 19 Feb 2024 09:59:15 +0100
Subject: [PATCH 13/48] [gdb/exp] Fix printing of out of bounds struct members
When building gdb with -O0 -fsanitize=address, and running test-case
gdb.ada/uninitialized_vars.exp, I run into:
...
(gdb) info locals
a = 0
z = (a => 1, b => false, c => 2.0)
=================================================================
==66372==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000097f58 at pc 0xffff52c0da1c bp 0xffffc90a1d40 sp 0xffffc90a1d80
READ of size 4 at 0x602000097f58 thread T0
#0 0xffff52c0da18 in memmove (/lib64/libasan.so.8+0x6da18)
#1 0xbcab24 in unsigned char* std::__copy_move_backward<false, true, std::random_access_iterator_tag>::__copy_move_b<unsigned char const, unsigned char>(unsigned char const*, unsigned char const*, unsigned char*) /usr/include/c++/13/bits/stl_algobase.h:748
#2 0xbc9bf4 in unsigned char* std::__copy_move_backward_a2<false, unsigned char const*, unsigned char*>(unsigned char const*, unsigned char const*, unsigned char*) /usr/include/c++/13/bits/stl_algobase.h:769
#3 0xbc898c in unsigned char* std::__copy_move_backward_a1<false, unsigned char const*, unsigned char*>(unsigned char const*, unsigned char const*, unsigned char*) /usr/include/c++/13/bits/stl_algobase.h:778
#4 0xbc715c in unsigned char* std::__copy_move_backward_a<false, unsigned char const*, unsigned char*>(unsigned char const*, unsigned char const*, unsigned char*) /usr/include/c++/13/bits/stl_algobase.h:807
#5 0xbc4e6c in unsigned char* std::copy_backward<unsigned char const*, unsigned char*>(unsigned char const*, unsigned char const*, unsigned char*) /usr/include/c++/13/bits/stl_algobase.h:867
#6 0xbc2934 in void gdb::copy<unsigned char const, unsigned char>(gdb::array_view<unsigned char const>, gdb::array_view<unsigned char>) gdb/../gdbsupport/array-view.h:223
#7 0x20e0100 in value::contents_copy_raw(value*, long, long, long) gdb/value.c:1239
#8 0x20e9830 in value::primitive_field(long, int, type*) gdb/value.c:3078
#9 0x20e98f8 in value_field(value*, int) gdb/value.c:3095
#10 0xcafd64 in print_field_values gdb/ada-valprint.c:658
#11 0xcb0fa0 in ada_val_print_struct_union gdb/ada-valprint.c:857
#12 0xcb1bb4 in ada_value_print_inner(value*, ui_file*, int, value_print_options const*) gdb/ada-valprint.c:1042
#13 0xc66e04 in ada_language::value_print_inner(value*, ui_file*, int, value_print_options const*) const (/home/vries/gdb/build/gdb/gdb+0xc66e04)
#14 0x20ca1e8 in common_val_print(value*, ui_file*, int, value_print_options const*, language_defn const*) gdb/valprint.c:1092
#15 0x20caabc in common_val_print_checked(value*, ui_file*, int, value_print_options const*, language_defn const*) gdb/valprint.c:1184
#16 0x196c524 in print_variable_and_value(char const*, symbol*, frame_info_ptr, ui_file*, int) gdb/printcmd.c:2355
#17 0x1d99ca0 in print_variable_and_value_data::operator()(char const*, symbol*) gdb/stack.c:2308
#18 0x1dabca0 in gdb::function_view<void (char const*, symbol*)>::bind<print_variable_and_value_data>(print_variable_and_value_data&)::{lambda(gdb::fv_detail::erased_callable, char const*, symbol*)#1}::operator()(gdb::fv_detail::erased_callable, char const*, symbol*) const gdb/../gdbsupport/function-view.h:305
#19 0x1dabd14 in gdb::function_view<void (char const*, symbol*)>::bind<print_variable_and_value_data>(print_variable_and_value_data&)::{lambda(gdb::fv_detail::erased_callable, char const*, symbol*)#1}::_FUN(gdb::fv_detail::erased_callable, char const*, symbol*) gdb/../gdbsupport/function-view.h:299
#20 0x1dab34c in gdb::function_view<void (char const*, symbol*)>::operator()(char const*, symbol*) const gdb/../gdbsupport/function-view.h:289
#21 0x1d9963c in iterate_over_block_locals gdb/stack.c:2240
#22 0x1d99790 in iterate_over_block_local_vars(block const*, gdb::function_view<void (char const*, symbol*)>) gdb/stack.c:2259
#23 0x1d9a598 in print_frame_local_vars gdb/stack.c:2380
#24 0x1d9afac in info_locals_command(char const*, int) gdb/stack.c:2458
#25 0xfd7b30 in do_simple_func gdb/cli/cli-decode.c:95
#26 0xfe5a2c in cmd_func(cmd_list_element*, char const*, int) gdb/cli/cli-decode.c:2735
#27 0x1f03790 in execute_command(char const*, int) gdb/top.c:575
#28 0x1384080 in command_handler(char const*) gdb/event-top.c:566
#29 0x1384e2c in command_line_handler(std::unique_ptr<char, gdb::xfree_deleter<char> >&&) gdb/event-top.c:802
#30 0x1f731e4 in tui_command_line_handler gdb/tui/tui-interp.c:104
#31 0x1382a58 in gdb_rl_callback_handler gdb/event-top.c:259
#32 0x21dbb80 in rl_callback_read_char readline/readline/callback.c:290
#33 0x1382510 in gdb_rl_callback_read_char_wrapper_noexcept gdb/event-top.c:195
#34 0x138277c in gdb_rl_callback_read_char_wrapper gdb/event-top.c:234
#35 0x1fe9b40 in stdin_event_handler gdb/ui.c:155
#36 0x35ff1bc in handle_file_event gdbsupport/event-loop.cc:573
#37 0x35ff9d8 in gdb_wait_for_event gdbsupport/event-loop.cc:694
#38 0x35fd284 in gdb_do_one_event(int) gdbsupport/event-loop.cc:264
#39 0x1768080 in start_event_loop gdb/main.c:408
#40 0x17684c4 in captured_command_loop gdb/main.c:472
#41 0x176cfc8 in captured_main gdb/main.c:1342
#42 0x176d088 in gdb_main(captured_main_args*) gdb/main.c:1361
#43 0xb73edc in main gdb/gdb.c:39
#44 0xffff519b09d8 in __libc_start_call_main (/lib64/libc.so.6+0x309d8)
#45 0xffff519b0aac in __libc_start_main@@GLIBC_2.34 (/lib64/libc.so.6+0x30aac)
#46 0xb73c2c in _start (/home/vries/gdb/build/gdb/gdb+0xb73c2c)
0x602000097f58 is located 0 bytes after 8-byte region [0x602000097f50,0x602000097f58)
allocated by thread T0 here:
#0 0xffff52c65218 in calloc (/lib64/libasan.so.8+0xc5218)
#1 0xcbc278 in xcalloc gdb/alloc.c:97
#2 0x35f21e8 in xzalloc(unsigned long) gdbsupport/common-utils.cc:29
#3 0x20de270 in value::allocate_contents(bool) gdb/value.c:937
#4 0x20edc08 in value::fetch_lazy() gdb/value.c:4033
#5 0x20dadc0 in value::entirely_covered_by_range_vector(std::vector<range, std::allocator<range> > const&) gdb/value.c:229
#6 0xcb2298 in value::entirely_optimized_out() gdb/value.h:560
#7 0x20ca6fc in value_check_printable gdb/valprint.c:1133
#8 0x20caa8c in common_val_print_checked(value*, ui_file*, int, value_print_options const*, language_defn const*) gdb/valprint.c:1182
#9 0x196c524 in print_variable_and_value(char const*, symbol*, frame_info_ptr, ui_file*, int) gdb/printcmd.c:2355
#10 0x1d99ca0 in print_variable_and_value_data::operator()(char const*, symbol*) gdb/stack.c:2308
#11 0x1dabca0 in gdb::function_view<void (char const*, symbol*)>::bind<print_variable_and_value_data>(print_variable_and_value_data&)::{lambda(gdb::fv_detail::erased_callable, char const*, symbol*)#1}::operator()(gdb::fv_detail::erased_callable, char const*, symbol*) const gdb/../gdbsupport/function-view.h:305
#12 0x1dabd14 in gdb::function_view<void (char const*, symbol*)>::bind<print_variable_and_value_data>(print_variable_and_value_data&)::{lambda(gdb::fv_detail::erased_callable, char const*, symbol*)#1}::_FUN(gdb::fv_detail::erased_callable, char const*, symbol*) gdb/../gdbsupport/function-view.h:299
#13 0x1dab34c in gdb::function_view<void (char const*, symbol*)>::operator()(char const*, symbol*) const gdb/../gdbsupport/function-view.h:289
#14 0x1d9963c in iterate_over_block_locals gdb/stack.c:2240
#15 0x1d99790 in iterate_over_block_local_vars(block const*, gdb::function_view<void (char const*, symbol*)>) gdb/stack.c:2259
#16 0x1d9a598 in print_frame_local_vars gdb/stack.c:2380
#17 0x1d9afac in info_locals_command(char const*, int) gdb/stack.c:2458
#18 0xfd7b30 in do_simple_func gdb/cli/cli-decode.c:95
#19 0xfe5a2c in cmd_func(cmd_list_element*, char const*, int) gdb/cli/cli-decode.c:2735
#20 0x1f03790 in execute_command(char const*, int) gdb/top.c:575
#21 0x1384080 in command_handler(char const*) gdb/event-top.c:566
#22 0x1384e2c in command_line_handler(std::unique_ptr<char, gdb::xfree_deleter<char> >&&) gdb/event-top.c:802
#23 0x1f731e4 in tui_command_line_handler gdb/tui/tui-interp.c:104
#24 0x1382a58 in gdb_rl_callback_handler gdb/event-top.c:259
#25 0x21dbb80 in rl_callback_read_char readline/readline/callback.c:290
#26 0x1382510 in gdb_rl_callback_read_char_wrapper_noexcept gdb/event-top.c:195
#27 0x138277c in gdb_rl_callback_read_char_wrapper gdb/event-top.c:234
#28 0x1fe9b40 in stdin_event_handler gdb/ui.c:155
#29 0x35ff1bc in handle_file_event gdbsupport/event-loop.cc:573
SUMMARY: AddressSanitizer: heap-buffer-overflow (/lib64/libasan.so.8+0x6da18) in memmove
...
The error happens when trying to print either variable y or y2:
...
type Variable_Record (A : Boolean := True) is record
case A is
when True =>
B : Integer;
when False =>
C : Float;
D : Integer;
end case;
end record;
Y : Variable_Record := (A => True, B => 1);
Y2 : Variable_Record := (A => False, C => 1.0, D => 2);
...
when the variables are uninitialized.
The error happens only when printing the entire variable:
...
(gdb) p y.a
$2 = 216
(gdb) p y.b
There is no member named b.
(gdb) p y.c
$3 = 9.18340949e-41
(gdb) p y.d
$4 = 1
(gdb) p y
<AddressSanitizer: heap-buffer-overflow>
...
The error happens as follows:
- field a functions as discriminant, choosing either the b, or c+d variant.
- when y.a happens to be set to 216, as above, gdb interprets this as the
variable having the c+d variant (which is why trying to print y.b fails).
- when printing y, gdb allocates a value, copies the bytes into it from the
target, and then prints the value.
- gdb allocates the value using the type size, which is 8. It's 8 because
that's what the DW_AT_byte_size indicates. Note that for valid values of a,
it gives correct results: if a is 0 (c+d variant), size is 12, if a is 1
(b variant), size is 8.
- gdb tries to print field d, which is at an 8 byte offset, and that results
in a out-of-bounds access for the allocated 8-byte value.
Fix this by handling this case in value::contents_copy_raw, such that we have:
...
(gdb) p y
$1 = (a => 24, c => 9.18340949e-41,
d => <error reading variable: access outside bounds of object>)
...
An alternative (additional) fix could be this: in compute_variant_fields_inner
gdb reads the discriminant y.a to decide which variant is active. It would be
nice to detect that the value (y.a == 24) is not a valid Boolean, and give up
on choosing a variant altoghether. However, the situation regarding the
internal type CODE_TYPE_BOOL is currently ambiguous (see PR31282) and it's not
possible to reliably decide what valid values are.
The test-case source file gdb.ada/uninitialized-variable-record/parse.adb is
a reduced version of gdb.ada/uninitialized_vars/parse.adb, so it copies the
copyright years.
Note that the test-case needs gcc-12 or newer, it's unsupported for older gcc
versions. [ So, it would be nice to rewrite it into a dwarf assembly
test-case. ]
The test-case loops over all languages. This is inherited from an earlier
attempt to fix this, which had language-specific fixes (in print_field_values,
cp_print_value_fields, pascal_object_print_value_fields and
f_language::value_print_inner). I've left this in, but I suppose it's not
strictly necessary anymore.
Tested on x86_64-linux.
PR exp/31258
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31258
---
.../gdb.ada/uninitialized-variable-record.exp | 122 ++++++++++++++++++
.../uninitialized-variable-record/parse.adb | 33 +++++
gdb/value.c | 3 +
3 files changed, 158 insertions(+)
create mode 100644 gdb/testsuite/gdb.ada/uninitialized-variable-record.exp
create mode 100644 gdb/testsuite/gdb.ada/uninitialized-variable-record/parse.adb
diff --git a/gdb/testsuite/gdb.ada/uninitialized-variable-record.exp b/gdb/testsuite/gdb.ada/uninitialized-variable-record.exp
new file mode 100644
index 00000000000..7fc72395edf
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/uninitialized-variable-record.exp
@@ -0,0 +1,122 @@
+# Copyright 2024 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/>.
+
+load_lib "ada.exp"
+
+require allow_ada_tests
+
+standard_ada_testfile parse
+
+if {[gdb_compile_ada "${srcfile}" "${binfile}" executable {debug}] != "" } {
+ return -1
+}
+
+clean_restart ${testfile}
+
+set bp_location [gdb_get_line_number "START" ${testdir}/parse.adb]
+runto "parse.adb:$bp_location"
+
+# Check that we have the expected value for variable y2.
+
+gdb_test "p y2" [string_to_regexp " = (a => false, c => 1.0, d => 2)"]
+
+# Shorthand.
+
+proc set_lang { lang } {
+ gdb_test_multiple "set language $lang" "" {
+ -re -wrap "" {
+ }
+ }
+}
+
+# Calculate the offset of y2.d.
+
+set re_cast [string_to_regexp "(access integer)"]
+gdb_test_multiple "print &y2.d - &y2" "" {
+ -re -wrap " = $re_cast ($hex)" {
+ set offset_d $expect_out(1,string)
+ pass $gdb_test_name
+ }
+}
+
+# Try to find a interesting discriminator value, such that at the same time:
+# - the d field is part of the variable, and
+# - the type size is too small to contain d.
+
+set interesting_discriminator -1
+set_lang c
+for { set i 0 } { $i < 256 } { incr i } {
+ with_test_prefix $i {
+
+ # Patch in the discriminator value.
+ gdb_test_multiple "set var *(unsigned char *)(&y2.a)=$i" "" {
+ -re -wrap "" {
+ }
+ }
+
+ # Check that we have the variant with fields c+d instead of b.
+ set have_b 0
+ gdb_test_multiple "with language ada -- print y2.b" "" {
+ -re -wrap " = $decimal" {
+ set have_b 1
+ }
+ -re -wrap "" {
+ }
+ }
+ if { $have_b } {
+ # This is the variant with field b.
+ continue
+ }
+
+ set size 0
+ gdb_test_multiple "print sizeof (y2)" "" {
+ -re -wrap " = (.*)" {
+ set size $expect_out(1,string)
+ }
+ }
+
+ if { ! $size } {
+ continue
+ }
+
+ if { [expr $size > $offset_d] } {
+ # Field d fits in the size.
+ continue
+ }
+
+ set interesting_discriminator $i
+ break
+ }
+}
+
+require {expr $interesting_discriminator != -1}
+
+foreach lang [gdb_supported_languages] {
+ with_test_prefix $lang {
+ set_lang $lang
+
+ gdb_test_multiple "print y2" "" {
+ -re -wrap ", d => $decimal.*" {
+ fail $gdb_test_name
+ }
+ -re -wrap ", d = $decimal.*" {
+ fail $gdb_test_name
+ }
+ -re -wrap "" {
+ pass $gdb_test_name
+ }
+ }
+ }
+}
diff --git a/gdb/testsuite/gdb.ada/uninitialized-variable-record/parse.adb b/gdb/testsuite/gdb.ada/uninitialized-variable-record/parse.adb
new file mode 100644
index 00000000000..f00c75ca2dc
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/uninitialized-variable-record/parse.adb
@@ -0,0 +1,33 @@
+-- Copyright 2009-2024 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/>.
+
+-- Based on gdb.ada/uninitialized_vars/parse.adb.
+
+procedure Parse is
+
+ type Variable_Record (A : Boolean := True) is record
+ case A is
+ when True =>
+ B : Integer;
+ when False =>
+ C : Float;
+ D : Integer;
+ end case;
+ end record;
+ Y2 : Variable_Record := (A => False, C => 1.0, D => 2);
+
+begin
+ null; -- START
+end Parse;
diff --git a/gdb/value.c b/gdb/value.c
index 1cc32625629..56ae9db6603 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -1188,6 +1188,9 @@ value::contents_copy_raw (struct value *dst, LONGEST dst_offset,
gdb_assert (!dst->bits_any_optimized_out (TARGET_CHAR_BIT * dst_offset,
TARGET_CHAR_BIT * length));
+ if ((src_offset + copy_length) * unit_size > enclosing_type ()-> length ())
+ error (_("access outside bounds of object"));
+
/* Copy the data. */
gdb::array_view<gdb_byte> dst_contents
= dst->contents_all_raw ().slice (dst_offset * unit_size,
--
2.35.3

View File

@ -12,7 +12,269 @@ https://bugzilla.redhat.com/show_bug.cgi?id=1270534
diff --git a/gdb/configure b/gdb/configure
--- a/gdb/configure
+++ b/gdb/configure
@@ -20916,6 +20916,7 @@ if test x"$prefer_curses" = xyes; then
@@ -780,9 +780,6 @@ ENABLE_BFD_64_BIT_TRUE
subdirs
RPM_LIBS
RPM_CFLAGS
-PKG_CONFIG_LIBDIR
-PKG_CONFIG_PATH
-PKG_CONFIG
GDB_DATADIR
DEBUGDIR
MAKEINFO_EXTRA_FLAGS
@@ -990,12 +987,12 @@ PKG_CONFIG_PATH
PKG_CONFIG_LIBDIR
MAKEINFO
MAKEINFOFLAGS
+RPM_CFLAGS
+RPM_LIBS
AMD_DBGAPI_CFLAGS
AMD_DBGAPI_LIBS
DEBUGINFOD_CFLAGS
DEBUGINFOD_LIBS
-RPM_CFLAGS
-RPM_LIBS
YACC
YFLAGS
ZSTD_CFLAGS
@@ -1684,11 +1681,11 @@ Optional Packages:
[--with-auto-load-dir]
--without-auto-load-safe-path
do not restrict auto-loaded files locations
+ --with-rpm query rpm database for missing debuginfos (yes/no,
+ def. auto=librpm.so)
--with-amd-dbgapi support for the amd-dbgapi target (yes / no / auto)
--with-debuginfod Enable debuginfo lookups with debuginfod
(auto/yes/no)
- --with-rpm query rpm database for missing debuginfos (yes/no,
- def. auto=librpm.so)
--with-libunwind-ia64 use libunwind frame unwinding for ia64 targets
--with-curses use the curses library instead of the termcap
library
@@ -1761,6 +1758,8 @@ Some influential environment variables:
MAKEINFO Parent configure detects if it is of sufficient version.
MAKEINFOFLAGS
Parameters for MAKEINFO.
+ RPM_CFLAGS C compiler flags for RPM, overriding pkg-config
+ RPM_LIBS linker flags for RPM, overriding pkg-config
AMD_DBGAPI_CFLAGS
C compiler flags for AMD_DBGAPI, overriding pkg-config
AMD_DBGAPI_LIBS
@@ -1769,8 +1768,6 @@ Some influential environment variables:
C compiler flags for DEBUGINFOD, overriding pkg-config
DEBUGINFOD_LIBS
linker flags for DEBUGINFOD, overriding pkg-config
- RPM_CFLAGS C compiler flags for RPM, overriding pkg-config
- RPM_LIBS linker flags for RPM, overriding pkg-config
YACC The `Yet Another Compiler Compiler' implementation to use.
Defaults to the first program found out of: `bison -y', `byacc',
`yacc'.
@@ -11495,7 +11492,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11486 "configure"
+#line 11495 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11601,7 +11598,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11592 "configure"
+#line 11601 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -18102,8 +18099,8 @@ $as_echo_n "checking specific librpm version... " >&6; }
if test "$cross_compiling" = yes; then :
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "cannot run test program while cross compiling
-See \`config.log' for more details." "$LINENO" 5; }
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5; }
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -18275,132 +18272,12 @@ $as_echo "#define HAVE_LIBRPM 1" >>confdefs.h
$as_echo "no" >&6; }
LIBS="$save_LIBS"
if $DLOPEN_REQUIRE; then
- as_fn_error "Specific name $LIBRPM was requested but it could not be opened." "$LINENO" 5
+ as_fn_error $? "Specific name $LIBRPM was requested but it could not be opened." "$LINENO" 5
fi
-
-
-
-
-
-
-if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
-set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_PKG_CONFIG+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- case $PKG_CONFIG in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-PKG_CONFIG=$ac_cv_path_PKG_CONFIG
-if test -n "$PKG_CONFIG"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
-$as_echo "$PKG_CONFIG" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_path_PKG_CONFIG"; then
- ac_pt_PKG_CONFIG=$PKG_CONFIG
- # Extract the first word of "pkg-config", so it can be a program name with args.
-set dummy pkg-config; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- case $ac_pt_PKG_CONFIG in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
-if test -n "$ac_pt_PKG_CONFIG"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
-$as_echo "$ac_pt_PKG_CONFIG" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_pt_PKG_CONFIG" = x; then
- PKG_CONFIG=""
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- PKG_CONFIG=$ac_pt_PKG_CONFIG
- fi
-else
- PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
-fi
-
-fi
-if test -n "$PKG_CONFIG"; then
- _pkg_min_version=0.9.0
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
-$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
- if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
- PKG_CONFIG=""
- fi
-fi
-
pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for RPM" >&5
-$as_echo_n "checking for RPM... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for rpm" >&5
+$as_echo_n "checking for rpm... " >&6; }
if test -n "$RPM_CFLAGS"; then
pkg_cv_RPM_CFLAGS="$RPM_CFLAGS"
@@ -18437,6 +18314,30 @@ fi
pkg_failed=untried
fi
+if test $pkg_failed = no; then
+ pkg_save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $pkg_cv_RPM_LIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+else
+ pkg_failed=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$pkg_save_LDFLAGS
+fi
+
if test $pkg_failed = yes; then
@@ -18531,7 +18432,7 @@ $as_echo "#define HAVE_LIBRPM 1" >>confdefs.h
LIBS="$LIBS $RPM_LIBS"
else
if $RPM_REQUIRE; then
- as_fn_error "$RPM_PKG_ERRORS" "$LINENO" 5
+ as_fn_error $? "$RPM_PKG_ERRORS" "$LINENO" 5
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $RPM_PKG_ERRORS" >&5
$as_echo "$as_me: WARNING: $RPM_PKG_ERRORS" >&2;}
@@ -21164,6 +21065,7 @@ if test x"$prefer_curses" = xyes; then
# search /usr/local/include, if ncurses is installed in /usr/local. A
# default installation of ncurses on alpha*-dec-osf* will lead to such
# a situation.
@ -20,7 +282,7 @@ diff --git a/gdb/configure b/gdb/configure
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing waddstr" >&5
$as_echo_n "checking for library containing waddstr... " >&6; }
if ${ac_cv_search_waddstr+:} false; then :
@@ -20940,7 +20941,7 @@ return waddstr ();
@@ -21188,7 +21090,7 @@ return waddstr ();
return 0;
}
_ACEOF
@ -29,7 +291,7 @@ diff --git a/gdb/configure b/gdb/configure
if test -z "$ac_lib"; then
ac_res="none required"
else
@@ -21014,6 +21015,7 @@ case $host_os in
@@ -21260,6 +21162,7 @@ case $host_os in
esac
# These are the libraries checked by Readline.
@ -37,7 +299,7 @@ diff --git a/gdb/configure b/gdb/configure
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing tgetent" >&5
$as_echo_n "checking for library containing tgetent... " >&6; }
if ${ac_cv_search_tgetent+:} false; then :
@@ -21038,7 +21040,7 @@ return tgetent ();
@@ -21284,7 +21187,7 @@ return tgetent ();
return 0;
}
_ACEOF
@ -49,17 +311,17 @@ diff --git a/gdb/configure b/gdb/configure
diff --git a/gdb/configure.ac b/gdb/configure.ac
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -705,7 +705,8 @@ if test x"$prefer_curses" = xyes; then
@@ -749,7 +749,8 @@ if test x"$prefer_curses" = xyes; then
# search /usr/local/include, if ncurses is installed in /usr/local. A
# default installation of ncurses on alpha*-dec-osf* will lead to such
# a situation.
- AC_SEARCH_LIBS(waddstr, [ncursesw ncurses cursesX curses])
- AC_SEARCH_LIBS(waddstr, [ncursesw ncurses cursesX curses],
+ # Fedora: Force libncursesw over libncurses to match the includes.
+ AC_SEARCH_LIBS(waddstr, [ncursesw])
if test "$ac_cv_search_waddstr" != no; then
curses_found=yes
@@ -747,7 +748,8 @@ case $host_os in
+ AC_SEARCH_LIBS(waddstr, [ncursesw],
[curses_found=yes
AC_DEFINE([HAVE_LIBCURSES], [1],
[Define to 1 if curses is enabled.])
@@ -789,7 +790,8 @@ case $host_os in
esac
# These are the libraries checked by Readline.

View File

@ -0,0 +1,144 @@
From 350172ea215c7074601e8424ff636563612f91e8 Mon Sep 17 00:00:00 2001
From: Pedro Alves <pedro@palves.net>
Date: Wed, 21 Feb 2024 16:23:55 +0000
Subject: [PATCH 14/48] [gdb] Fix heap-use-after-free in select_event_lwp
PR gdb/31259 reveals one scenario where we run into a
heap-use-after-free reported by thread sanitizer, while running
gdb.base/vfork-follow-parent.exp.
The heap-use-after-free happens during the following scenario:
- linux_nat_wait_1 is about to return an event for T2. It stops all
other threads, and while doing so, stop_wait_callback -> wait_lwp
sees T1 exit, and decides to leave the exit event pending. It
should have set the lp->stopped flag too, but does not -- this is
the bug.
- The event for T2 is reported, is processed by infrun, and we're
back at linux_nat_wait_1.
- linux_nat_wait_1 selects LWP T1 with the pending exit status to
report.
- it sets variable lp to point to the corresponding lwp_info.
- it calls stop_callback and stop_wait_callback for all threads
(because !target_is_non_stop_p ()).
- it calls select_event_lwp to maybe pick another thread than T1, to
prevent starvation.
The problem is the following:
- while calling stop_wait_callback for all threads, it also does this
for T1. While doing so, the corresponding lwp_info is deleted
(callstack stop_wait_callback -> wait_lwp -> exit_lwp ->
delete_lwp), leaving variable lp as a dangling pointer.
- variable lp is passed to select_event_lwp, which derefences it,
which causes the heap-use-after-free.
Note that the comment here mentions "all other LWP's":
...
/* Now stop all other LWP's ... */
iterate_over_lwps (minus_one_ptid, stop_callback);
/* ... and wait until all of them have reported back that
they're no longer running. */
iterate_over_lwps (minus_one_ptid, stop_wait_callback);
...
The reason the comments say "all other LWP's", and doesn't bother
filtering out LP is that lp->stopped should be true at this point, and
the callbacks (both stop_callback and stop_wait_callback) check that
flag, and do nothing if set. I.e., they skip already-stopped threads,
so they should skip LP.
In this particular scenario, though, we missed setting the stopped
flag right in the first step described above, so LP was iterated over
incorrectly.
The fix is to make wait_lwp set the lp->stopped flag when it decides
to leave the exit event pending. However, going a bit further,
gdbserver has a mark_lwp_dead function to centralize setting up
various lwp flags such that the rest of the code doesn't mishandle
them, and it seems like a good idea to do a similar thing in gdb as
well. That is what this patch does.
PR gdb/31259
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31259
Co-Authored-By: Tom de Vries <tdevries@suse.de>
Change-Id: I4a6169976f89bf714c478cbb2b7d4c32365e62a9
---
gdb/linux-nat.c | 34 +++++++++++++++++++++++++---------
1 file changed, 25 insertions(+), 9 deletions(-)
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 7e36ced6292..ed445c5e5bb 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -2029,6 +2029,27 @@ wait_for_signal ()
}
}
+/* Mark LWP dead, with STATUS as exit status pending to report
+ later. */
+
+static void
+mark_lwp_dead (lwp_info *lp, int status)
+{
+ /* Store the exit status lp->waitstatus, because lp->status would be
+ ambiguous (W_EXITCODE(0,0) == 0). */
+ lp->waitstatus = host_status_to_waitstatus (status);
+
+ /* If we're processing LP's status, there should be no other event
+ already recorded as pending. */
+ gdb_assert (lp->status == 0);
+
+ /* Dead LWPs aren't expected to report a pending sigstop. */
+ lp->signalled = 0;
+
+ /* Prevent trying to stop it. */
+ lp->stopped = 1;
+}
+
/* Wait for LP to stop. Returns the wait status, or 0 if the LWP has
exited. */
@@ -2114,9 +2135,8 @@ wait_lwp (struct lwp_info *lp)
/* If this is the leader exiting, it means the whole
process is gone. Store the status to report to the
- core. Store it in lp->waitstatus, because lp->status
- would be ambiguous (W_EXITCODE(0,0) == 0). */
- lp->waitstatus = host_status_to_waitstatus (status);
+ core. */
+ mark_lwp_dead (lp, status);
return 0;
}
@@ -2908,12 +2928,7 @@ linux_nat_filter_event (int lwpid, int status)
linux_nat_debug_printf ("LWP %ld exited (resumed=%d)",
lp->ptid.lwp (), lp->resumed);
- /* Dead LWP's aren't expected to reported a pending sigstop. */
- lp->signalled = 0;
-
- /* Store the pending event in the waitstatus, because
- W_EXITCODE(0,0) == 0. */
- lp->waitstatus = host_status_to_waitstatus (status);
+ mark_lwp_dead (lp, status);
return;
}
@@ -3248,6 +3263,7 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
}
gdb_assert (lp);
+ gdb_assert (lp->stopped);
status = lp->status;
lp->status = 0;
--
2.35.3

View File

@ -1,6 +1,6 @@
From 75617e6d28b93814ac46ad85ad4fc2b133f61114 Mon Sep 17 00:00:00 2001
From 1d02ba0f4adcba2595a67e88fb1ba6d35c7f8e5b Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Fri, 3 Nov 2023 16:25:33 +0100
Date: Tue, 7 May 2024 11:33:57 +0200
Subject: [PATCH] [gdb] Fix segfault in for_each_block, part 1
When running test-case gdb.base/vfork-follow-parent.exp on powerpc64 (likewise
@ -75,7 +75,7 @@ Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30547
gdb/breakpoint.c | 29 ++++++++-------
gdb/inferior.c | 8 ++---
gdb/inferior.h | 2 +-
gdb/infrun.c | 20 +++++------
gdb/infrun.c | 18 +++++-----
gdb/linux-nat.c | 2 +-
gdb/process-stratum-target.c | 2 +-
gdb/progspace.c | 22 +++++-------
@ -85,13 +85,13 @@ Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30547
gdb/scoped-mock-context.h | 2 +-
gdb/target-dcache.c | 11 +++---
gdbsupport/refcounted-object.h | 17 +++++++++
13 files changed, 103 insertions(+), 80 deletions(-)
13 files changed, 102 insertions(+), 79 deletions(-)
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index f8d19356828..f4acb4ea8c4 100644
index 01f187ca4fe..a22bdb091cd 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -1605,7 +1605,7 @@ one_breakpoint_xfer_memory (gdb_byte *readbuf, gdb_byte *writebuf,
@@ -1723,7 +1723,7 @@ one_breakpoint_xfer_memory (gdb_byte *readbuf, gdb_byte *writebuf,
int bptoffset = 0;
if (!breakpoint_address_match (target_info->placed_address_space, 0,
@ -100,7 +100,7 @@ index f8d19356828..f4acb4ea8c4 100644
{
/* The breakpoint is inserted in a different address space. */
return;
@@ -2278,7 +2278,7 @@ should_be_inserted (struct bp_location *bl)
@@ -2409,7 +2409,7 @@ should_be_inserted (struct bp_location *bl)
a breakpoint. */
if ((bl->loc_type == bp_loc_software_breakpoint
|| bl->loc_type == bp_loc_hardware_breakpoint)
@ -109,7 +109,7 @@ index f8d19356828..f4acb4ea8c4 100644
bl->address)
/* The single-step breakpoint may be inserted at the location
we're trying to step if the instruction branches to itself.
@@ -2713,7 +2713,7 @@ insert_bp_location (struct bp_location *bl,
@@ -2847,7 +2847,7 @@ insert_bp_location (struct bp_location *bl,
read the breakpoint instead of returning the data saved in
the breakpoint location's shadow contents. */
bl->target_info.reqstd_address = bl->address;
@ -118,7 +118,7 @@ index f8d19356828..f4acb4ea8c4 100644
bl->target_info.length = bl->length;
/* When working with target-side conditions, we must pass all the conditions
@@ -4276,7 +4276,7 @@ bp_location_inserted_here_p (const struct bp_location *bl,
@@ -4429,7 +4429,7 @@ bp_location_inserted_here_p (const struct bp_location *bl,
const address_space *aspace, CORE_ADDR pc)
{
if (bl->inserted
@ -127,16 +127,16 @@ index f8d19356828..f4acb4ea8c4 100644
aspace, pc))
{
/* An unmapped overlay can't be a match. */
@@ -4355,7 +4355,7 @@ hardware_watchpoint_inserted_in_range (const address_space *aspace,
@@ -4508,7 +4508,7 @@ hardware_watchpoint_inserted_in_range (const address_space *aspace,
continue;
for (bp_location *loc : bpt->locations ())
- if (loc->pspace->aspace == aspace && loc->inserted)
+ if (loc->pspace->aspace.get () == aspace && loc->inserted)
for (bp_location &loc : bpt.locations ())
- if (loc.pspace->aspace == aspace && loc.inserted)
+ if (loc.pspace->aspace.get () == aspace && loc.inserted)
{
CORE_ADDR l, h;
@@ -7153,10 +7153,10 @@ breakpoint_location_address_match (struct bp_location *bl,
@@ -7330,10 +7330,10 @@ breakpoint_location_address_match (struct bp_location *bl,
const address_space *aspace,
CORE_ADDR addr)
{
@ -149,7 +149,7 @@ index f8d19356828..f4acb4ea8c4 100644
bl->address, bl->length,
aspace, addr)));
}
@@ -7173,7 +7173,7 @@ breakpoint_location_address_range_overlap (struct bp_location *bl,
@@ -7350,7 +7350,7 @@ breakpoint_location_address_range_overlap (struct bp_location *bl,
CORE_ADDR addr, int len)
{
if (gdbarch_has_global_breakpoints (target_gdbarch ())
@ -158,7 +158,7 @@ index f8d19356828..f4acb4ea8c4 100644
{
int bl_len = bl->length != 0 ? bl->length : 1;
@@ -7230,8 +7230,10 @@ breakpoint_locations_match (const struct bp_location *loc1,
@@ -7407,8 +7407,10 @@ breakpoint_locations_match (const struct bp_location *loc1,
/* We compare bp_location.length in order to cover ranged
breakpoints. Keep this in sync with
bp_location_is_less_than. */
@ -171,7 +171,7 @@ index f8d19356828..f4acb4ea8c4 100644
&& (loc1->loc_type == loc2->loc_type || sw_hw_bps_match)
&& loc1->length == loc2->length);
}
@@ -9297,8 +9299,9 @@ ranged_breakpoint::breakpoint_hit (const struct bp_location *bl,
@@ -9568,8 +9570,9 @@ ranged_breakpoint::breakpoint_hit (const struct bp_location *bl,
|| ws.sig () != GDB_SIGNAL_TRAP)
return 0;
@ -183,7 +183,7 @@ index f8d19356828..f4acb4ea8c4 100644
}
/* Implement the "resources_needed" method for ranged breakpoints. */
@@ -11696,7 +11699,7 @@ code_breakpoint::breakpoint_hit (const struct bp_location *bl,
@@ -12018,7 +12021,7 @@ code_breakpoint::breakpoint_hit (const struct bp_location *bl,
|| ws.sig () != GDB_SIGNAL_TRAP)
return 0;
@ -193,10 +193,10 @@ index f8d19356828..f4acb4ea8c4 100644
return 0;
diff --git a/gdb/inferior.c b/gdb/inferior.c
index b0ecca8b63a..87c61eeafd7 100644
index 550bbd2827c..461f4fc076a 100644
--- a/gdb/inferior.c
+++ b/gdb/inferior.c
@@ -775,15 +775,13 @@ remove_inferior_command (const char *args, int from_tty)
@@ -831,15 +831,13 @@ remove_inferior_command (const char *args, int from_tty)
struct inferior *
add_inferior_with_spaces (void)
{
@ -213,7 +213,7 @@ index b0ecca8b63a..87c61eeafd7 100644
inf = add_inferior (0);
inf->pspace = pspace;
inf->aspace = pspace->aspace;
@@ -946,15 +944,13 @@ clone_inferior_command (const char *args, int from_tty)
@@ -1002,15 +1000,13 @@ clone_inferior_command (const char *args, int from_tty)
for (i = 0; i < copies; ++i)
{
@ -231,10 +231,10 @@ index b0ecca8b63a..87c61eeafd7 100644
inf->pspace = pspace;
inf->aspace = pspace->aspace;
diff --git a/gdb/inferior.h b/gdb/inferior.h
index 4d001b0ad50..fa5c3c92eeb 100644
index 29c90d15efa..4139791740f 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -541,7 +541,7 @@ class inferior : public refcounted_object,
@@ -577,7 +577,7 @@ class inferior : public refcounted_object,
bool removable = false;
/* The address space bound to this inferior. */
@ -244,10 +244,10 @@ index 4d001b0ad50..fa5c3c92eeb 100644
/* The program space bound to this inferior. */
struct program_space *pspace = NULL;
diff --git a/gdb/infrun.c b/gdb/infrun.c
index c078098a6f8..4073150d80c 100644
index 7be98cfc252..3854c66bf6c 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -501,8 +501,8 @@ holding the child stopped. Try \"set detach-on-fork\" or \
@@ -531,8 +531,8 @@ holding the child stopped. Try \"set detach-on-fork\" or \
}
else
{
@ -258,7 +258,7 @@ index c078098a6f8..4073150d80c 100644
child_inf->removable = true;
clone_program_space (child_inf->pspace, parent_inf->pspace);
}
@@ -573,8 +573,8 @@ holding the child stopped. Try \"set detach-on-fork\" or \
@@ -610,8 +610,8 @@ holding the child stopped. Try \"set detach-on-fork\" or \
child_inf->aspace = parent_inf->aspace;
child_inf->pspace = parent_inf->pspace;
@ -269,7 +269,7 @@ index c078098a6f8..4073150d80c 100644
clone_program_space (parent_inf->pspace, child_inf->pspace);
/* The parent inferior is still the current one, so keep things
@@ -583,8 +583,8 @@ holding the child stopped. Try \"set detach-on-fork\" or \
@@ -620,8 +620,8 @@ holding the child stopped. Try \"set detach-on-fork\" or \
}
else
{
@ -280,7 +280,7 @@ index c078098a6f8..4073150d80c 100644
child_inf->removable = true;
child_inf->symfile_flags = SYMFILE_NO_READ;
clone_program_space (child_inf->pspace, parent_inf->pspace);
@@ -938,7 +938,6 @@ handle_vfork_child_exec_or_exit (int exec)
@@ -1031,7 +1031,6 @@ handle_vfork_child_exec_or_exit (int exec)
if (vfork_parent->pending_detach)
{
struct program_space *pspace;
@ -288,7 +288,7 @@ index c078098a6f8..4073150d80c 100644
/* follow-fork child, detach-on-fork on. */
@@ -963,9 +962,8 @@ handle_vfork_child_exec_or_exit (int exec)
@@ -1056,9 +1055,8 @@ handle_vfork_child_exec_or_exit (int exec)
of" a hack. */
pspace = inf->pspace;
@ -299,17 +299,8 @@ index c078098a6f8..4073150d80c 100644
if (print_inferior_events)
{
@@ -1019,7 +1017,7 @@ handle_vfork_child_exec_or_exit (int exec)
/* Temporarily switch to the vfork parent, to facilitate ptrace
calls done during maybe_new_address_space. */
switch_to_thread (any_live_thread_of_inferior (vfork_parent));
- address_space *aspace = maybe_new_address_space ();
+ address_space_ref_ptr aspace = maybe_new_address_space ();
/* Switch back to the vfork child inferior. Switch to no-thread
while running clone_program_space, so that clone_program_space
@@ -5639,7 +5637,7 @@ handle_inferior_event (struct execution_control_state *ecs)
= get_thread_arch_aspace_regcache (parent_inf->process_target (),
@@ -5906,7 +5904,7 @@ handle_inferior_event (struct execution_control_state *ecs)
= get_thread_arch_aspace_regcache (parent_inf,
ecs->ws.child_ptid (),
gdbarch,
- parent_inf->aspace);
@ -318,10 +309,10 @@ index c078098a6f8..4073150d80c 100644
parent_pc = regcache_read_pc (regcache);
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 2b206a4ec1e..474d3c7f945 100644
index ed445c5e5bb..c8991cc3da4 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -4316,7 +4316,7 @@ linux_nat_target::thread_address_space (ptid_t ptid)
@@ -4365,7 +4365,7 @@ linux_nat_target::thread_address_space (ptid_t ptid)
inf = find_inferior_pid (this, pid);
gdb_assert (inf != NULL);
@ -331,7 +322,7 @@ index 2b206a4ec1e..474d3c7f945 100644
/* Return the cached value of the processor core for thread PTID. */
diff --git a/gdb/process-stratum-target.c b/gdb/process-stratum-target.c
index 4722c5a0f28..e67012a8591 100644
index 5c031203e89..4bcca4f39c2 100644
--- a/gdb/process-stratum-target.c
+++ b/gdb/process-stratum-target.c
@@ -37,7 +37,7 @@ process_stratum_target::thread_address_space (ptid_t ptid)
@ -344,10 +335,10 @@ index 4722c5a0f28..e67012a8591 100644
struct gdbarch *
diff --git a/gdb/progspace.c b/gdb/progspace.c
index 32bdfebcf7c..55df3b65dfe 100644
index 1dbcd5875dd..b4d25ba6196 100644
--- a/gdb/progspace.c
+++ b/gdb/progspace.c
@@ -54,8 +54,8 @@ address_space::address_space ()
@@ -55,8 +55,8 @@ address_space::address_space ()
return a pointer to an existing address space, in case inferiors
share an address space on this target system. */
@ -358,7 +349,7 @@ index 32bdfebcf7c..55df3b65dfe 100644
{
int shared_aspace = gdbarch_has_shared_address_space (target_gdbarch ());
@@ -65,7 +65,7 @@ maybe_new_address_space (void)
@@ -66,7 +66,7 @@ maybe_new_address_space (void)
return program_spaces[0]->aspace;
}
@ -367,7 +358,7 @@ index 32bdfebcf7c..55df3b65dfe 100644
}
/* Start counting over from scratch. */
@@ -93,9 +93,9 @@ remove_program_space (program_space *pspace)
@@ -94,9 +94,9 @@ remove_program_space (program_space *pspace)
/* See progspace.h. */
@ -378,8 +369,8 @@ index 32bdfebcf7c..55df3b65dfe 100644
+ aspace (std::move (aspace_))
{
program_spaces.push_back (this);
}
@@ -118,8 +118,6 @@ program_space::~program_space ()
gdb::observers::new_program_space.notify (this);
@@ -121,8 +121,6 @@ program_space::~program_space ()
/* Defer breakpoint re-set because we don't want to create new
locations for this pspace which we're tearing down. */
clear_symtab_users (SYMFILE_DEFER_BP_RESET);
@ -388,7 +379,7 @@ index 32bdfebcf7c..55df3b65dfe 100644
}
/* See progspace.h. */
@@ -389,18 +387,14 @@ update_address_spaces (void)
@@ -408,18 +406,14 @@ update_address_spaces (void)
if (shared_aspace)
{
@ -409,7 +400,7 @@ index 32bdfebcf7c..55df3b65dfe 100644
for (inferior *inf : all_inferiors ())
if (gdbarch_has_global_solist (target_gdbarch ()))
@@ -437,5 +431,5 @@ initialize_progspace (void)
@@ -456,5 +450,5 @@ initialize_progspace (void)
modules have done that. Do this before
initialize_current_architecture, because that accesses the ebfd
of current_program_space. */
@ -417,7 +408,7 @@ index 32bdfebcf7c..55df3b65dfe 100644
+ current_program_space = new program_space (new_address_space ());
}
diff --git a/gdb/progspace.h b/gdb/progspace.h
index 85215f0e2f1..07cca8c675c 100644
index ee12d89c173..12f113f6d9c 100644
--- a/gdb/progspace.h
+++ b/gdb/progspace.h
@@ -28,6 +28,8 @@
@ -479,7 +470,7 @@ index 85215f0e2f1..07cca8c675c 100644
/* Releases a program space, and all its contents (shared libraries,
objfiles, and any other references to the program space in other
@@ -332,7 +368,7 @@ struct program_space
@@ -336,7 +372,7 @@ struct program_space
are global, then this field is ignored (we don't currently
support inferiors sharing a program space if the target doesn't
make breakpoints global). */
@ -488,7 +479,7 @@ index 85215f0e2f1..07cca8c675c 100644
/* True if this program space's section offsets don't yet represent
the final offsets of the "live" address space (that is, the
@@ -379,28 +415,6 @@ struct program_space
@@ -383,28 +419,6 @@ struct program_space
target_section_table m_target_sections;
};
@ -517,7 +508,7 @@ index 85215f0e2f1..07cca8c675c 100644
/* The list of all program spaces. There's always at least one. */
extern std::vector<struct program_space *>program_spaces;
@@ -443,7 +457,7 @@ class scoped_restore_current_program_space
@@ -447,7 +461,7 @@ class scoped_restore_current_program_space
/* Maybe create a new address space object, and add it to the list, or
return a pointer to an existing address space, in case inferiors
share an address space. */
@ -527,10 +518,10 @@ index 85215f0e2f1..07cca8c675c 100644
/* Update all program spaces matching to address spaces. The user may
have created several program spaces, and loaded executables into
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index 0daba893813..276cdcc03b8 100644
index 97447d3e8f8..a4d6c1b5bf2 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -2314,7 +2314,7 @@ record_btrace_replay_at_breakpoint (struct thread_info *tp)
@@ -2321,7 +2321,7 @@ record_btrace_replay_at_breakpoint (struct thread_info *tp)
if (insn == NULL)
return 0;
@ -540,17 +531,17 @@ index 0daba893813..276cdcc03b8 100644
}
diff --git a/gdb/regcache.c b/gdb/regcache.c
index 56b6d047874..8a0b57e67b8 100644
index 91b20b7a2a2..a78fe0a80e7 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -1617,7 +1617,7 @@ get_thread_arch_aspace_regcache_and_check (process_stratum_target *target,
@@ -1628,7 +1628,7 @@ get_thread_arch_aspace_regcache_and_check (inferior *inf_for_target_calls,
the current inferior's gdbarch. Also use the current inferior's address
space. */
gdbarch *arch = current_inferior ()->gdbarch;
- address_space *aspace = current_inferior ()->aspace;
+ address_space *aspace = current_inferior ()->aspace.get ();
regcache *regcache
= get_thread_arch_aspace_regcache (target, ptid, arch, aspace);
gdbarch *arch = inf_for_target_calls->gdbarch;
- address_space *aspace = inf_for_target_calls->aspace;
+ address_space *aspace = inf_for_target_calls->aspace.get ();
regcache *regcache = get_thread_arch_aspace_regcache (inf_for_target_calls,
ptid, arch, aspace);
diff --git a/gdb/scoped-mock-context.h b/gdb/scoped-mock-context.h
index 9ad7ebf5f0c..5f25dc7ed6b 100644
@ -639,7 +630,7 @@ index d8fdb950043..294fd873df1 100644
+
#endif /* COMMON_REFCOUNTED_OBJECT_H */
base-commit: c55a452eaf9390d5659d3205f762aa2cb84511e1
base-commit: 0bb6f49bb9ad577667075550ca2ad4cb49931078
--
2.35.3

View File

@ -1,7 +1,7 @@
From 1cd845ab3d405412aabf9b959aa527dd60143826 Mon Sep 17 00:00:00 2001
From 3490f51a80a10d46dc1885ba672d9390a8221170 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 2 Nov 2023 14:51:02 +0100
Subject: [PATCH] [gdb] Fix segfault in for_each_block, part 2
Subject: [PATCH] Fix segfault in for_each_block, part 2
The previous commit describes PR gdb/30547, a segfault when running test-case
gdb.base/vfork-follow-parent.exp on powerpc64 (likewise on s390x).
@ -81,10 +81,10 @@ Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30547
4 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 9c1b1f04e4d..c078098a6f8 100644
index 3854c66bf6c..d259e81df84 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -1014,13 +1014,19 @@ handle_vfork_child_exec_or_exit (int exec)
@@ -1105,13 +1105,19 @@ handle_vfork_child_exec_or_exit (int exec)
go ahead and create a new one for this exiting
inferior. */
@ -98,14 +98,14 @@ index 9c1b1f04e4d..c078098a6f8 100644
+ /* Temporarily switch to the vfork parent, to facilitate ptrace
+ calls done during maybe_new_address_space. */
+ switch_to_thread (any_live_thread_of_inferior (vfork_parent));
+ address_space *aspace = maybe_new_address_space ();
+ address_space_ref_ptr aspace = maybe_new_address_space ();
+
+ /* Switch back to the vfork child inferior. Switch to no-thread
+ while running clone_program_space, so that clone_program_space
+ doesn't want to read the selected frame of a dead process. */
+ switch_to_inferior_no_thread (inf);
+
+ inf->pspace = new program_space (aspace);
+ inf->pspace = new program_space (std::move (aspace));
inf->aspace = inf->pspace->aspace;
set_current_program_space (inf->pspace);
inf->removable = true;
@ -123,10 +123,10 @@ index 0957d1b58a7..74549754806 100644
/* Check for 64-bit inferior process. This is the case when the host is
diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c
index d8a8fbdf706..500fb566bc1 100644
index d14aba694e5..817505ea73e 100644
--- a/gdb/ppc-linux-nat.c
+++ b/gdb/ppc-linux-nat.c
@@ -1918,6 +1918,8 @@ ppc_linux_nat_target::auxv_parse (const gdb_byte **readptr,
@@ -1914,6 +1914,8 @@ ppc_linux_nat_target::auxv_parse (const gdb_byte **readptr,
const gdb_byte *endptr, CORE_ADDR *typep,
CORE_ADDR *valp)
{
@ -136,7 +136,7 @@ index d8a8fbdf706..500fb566bc1 100644
if (tid == 0)
tid = inferior_ptid.pid ();
diff --git a/gdb/s390-linux-nat.c b/gdb/s390-linux-nat.c
index fc3917d30be..403f37d690d 100644
index 8f54e9f6322..54167f49480 100644
--- a/gdb/s390-linux-nat.c
+++ b/gdb/s390-linux-nat.c
@@ -949,10 +949,12 @@ s390_target_wordsize (void)
@ -162,7 +162,7 @@ index fc3917d30be..403f37d690d 100644
enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
const gdb_byte *ptr = *readptr;
base-commit: 59053f06bd94be51efacfa80f9a1f738e3e1ee9c
base-commit: 1d02ba0f4adcba2595a67e88fb1ba6d35c7f8e5b
--
2.35.3

View File

@ -0,0 +1,42 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Kevin Buettner <kevinb@redhat.com>
Date: Wed, 17 Jan 2024 12:53:53 -0700
Subject: gdb-ftbs-swapped-calloc-args.patch
Backport upstream commit 54195469c18ec9873cc5ba6907f768509473fa9b
which fixes a build problem in which arguments to calloc were swapped.
[opcodes] ARC + PPC: Fix -Walloc-size warnings
Recently, -Walloc-size warnings started to kick in. Fix these two
calloc() calls to match the intended usage pattern.
opcodes/ChangeLog:
* arc-dis.c (init_arc_disasm_info): Fix calloc() call.
* ppc-dis.c (powerpc_init_dialect): Ditto.
diff --git a/opcodes/arc-dis.c b/opcodes/arc-dis.c
--- a/opcodes/arc-dis.c
+++ b/opcodes/arc-dis.c
@@ -147,7 +147,7 @@ static bool
init_arc_disasm_info (struct disassemble_info *info)
{
struct arc_disassemble_info *arc_infop
- = calloc (sizeof (*arc_infop), 1);
+ = calloc (1, sizeof (*arc_infop));
if (arc_infop == NULL)
return false;
diff --git a/opcodes/ppc-dis.c b/opcodes/ppc-dis.c
--- a/opcodes/ppc-dis.c
+++ b/opcodes/ppc-dis.c
@@ -348,7 +348,7 @@ powerpc_init_dialect (struct disassemble_info *info)
{
ppc_cpu_t dialect = 0;
ppc_cpu_t sticky = 0;
- struct dis_private *priv = calloc (sizeof (*priv), 1);
+ struct dis_private *priv = calloc (1, sizeof (*priv));
if (priv == NULL)
return;

View File

@ -1,138 +0,0 @@
From 6c9e159dbd1a35aafa134fcd52982174236a8dd9 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 5 Oct 2023 23:22:11 +0200
Subject: [PATCH 3/3] [gdb/go] Handle v3 go_0 mangled prefix
With gcc-10 we have:
...
(gdb) break package2.Foo^M
Breakpoint 2 at 0x402563: file package2.go, line 5.^M
(gdb) PASS: gdb.go/package.exp: setting breakpoint 1
...
but with gcc-11:
...
gdb) break package2.Foo^M
Function "package2.Foo" not defined.^M
Make breakpoint pending on future shared library load? (y or [n]) n^M
(gdb) FAIL: gdb.go/package.exp: gdb_breakpoint: set breakpoint at package2.Foo
...
In the gcc-10 case, though the exec contains dwarf, it's not used to set the
breakpoint (which is an independent problem, filed as PR go/30941), instead
the minimal symbol information is used.
The minimal symbol information changed between gcc-10 and gcc-11:
...
$ nm a.out.10 | grep Foo
000000000040370d T go.package2.Foo
0000000000404e50 R go.package2.Foo..f
$ nm a.out.11 | grep Foo
0000000000403857 T go_0package2.Foo
0000000000405030 R go_0package2.Foo..f
...
A new v3 mangling scheme was used. The mangling schemes define a separator
character and mangling character:
- for v2, dot is used both as separator character and mangling character, and
- for v3, dot is used as separator character and underscore as mangling
character.
For more details, see [1] and [2].
In v3, "_0" demangles to ".". [ See gcc commit a01dda3c23b ("compiler, libgo:
change mangling scheme"), function Special_char_code::Special_char_code. ]
Handle the new go_0 prefix in unpack_mangled_go_symbol, which fixes the
test-case.
Note that this doesn't fix this regression:
...
$ gccgo-10 package2.go -c -g0
$ gccgo-10 package1.go package2.o -g0
$ gdb -q -batch a.out -ex "break go.package2.Foo"
Breakpoint 1 at 0x40370d
$ gccgo-11 package2.go -c -g0
$ gccgo-11 package1.go package2.o -g0
$ gdb -q -batch a.out -ex "break go.package2.Foo"
Function "go.package2.Foo" not defined.
...
With gcc-10, we set a breakpoint on the mangled minimal symbol. That
one has simply changed for gcc-11, so it's equivalent to using:
...
$ gdb -q -batch a.out -ex "break go_0package2.Foo"
Breakpoint 1 at 0x403857
...
which does work.
Tested on x86_64-linux:
- openSUSE Leap 15.4, using gccgo-7,
- openSUSE Tumbleweed, using gccgo-13.
PR go/27238
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=27238
[1] https://go-review.googlesource.com/c/gofrontend/+/271726
[2] https://github.com/golang/go/issues/41862#issuecomment-707244103
---
gdb/go-lang.c | 30 +++++++++++++++++++++++++++---
1 file changed, 27 insertions(+), 3 deletions(-)
diff --git a/gdb/go-lang.c b/gdb/go-lang.c
index f9176ace71d..8a5568f56e0 100644
--- a/gdb/go-lang.c
+++ b/gdb/go-lang.c
@@ -233,16 +233,28 @@ unpack_mangled_go_symbol (const char *mangled_name,
libgo_.*: used by gccgo's runtime
Thus we don't support -fgo-prefix (except as used by the runtime). */
- if (!startswith (mangled_name, "go.")
- && !startswith (mangled_name, "libgo_"))
+ bool v3;
+ if (startswith (mangled_name, "go_0"))
+ /* V3 mangling detected, see
+ https://go-review.googlesource.com/c/gofrontend/+/271726 . */
+ v3 = true;
+ else if (startswith (mangled_name, "go.")
+ || startswith (mangled_name, "libgo_"))
+ v3 = false;
+ else
return NULL;
/* Quick check for whether a search may be fruitful. */
/* Ignore anything with @plt, etc. in it. */
if (strchr (mangled_name, '@') != NULL)
return NULL;
+
/* It must have at least two dots. */
- first_dot = strchr (mangled_name, '.');
+ if (v3)
+ first_dot = strchr (mangled_name, '0');
+ else
+ first_dot = strchr (mangled_name, '.');
+
if (first_dot == NULL)
return NULL;
/* Treat "foo.bar" as unmangled. It can collide with lots of other
@@ -263,6 +275,18 @@ unpack_mangled_go_symbol (const char *mangled_name,
gdb::unique_xmalloc_ptr<char> result = make_unique_xstrdup (mangled_name);
buf = result.get ();
+ if (v3)
+ {
+ /* Replace "go_0" with "\0go.". */
+ buf[0] = '\0';
+ buf[1] = 'g';
+ buf[2] = 'o';
+ buf[3] = '.';
+
+ /* Skip the '\0'. */
+ buf++;
+ }
+
/* Search backwards looking for "N<digit(s)>". */
p = buf + len;
saw_digit = method_type = NULL;
--
2.35.3

View File

@ -0,0 +1,317 @@
From 1046c22724e2844ee99b92684b65cd5e9552c4aa Mon Sep 17 00:00:00 2001
From: Pedro Alves <pedro@palves.net>
Date: Wed, 13 Jul 2022 17:16:38 +0100
Subject: [PATCH 5/7] gdb/linux: Delete all other LWPs immediately on ptrace
exec event
I noticed that on an Ubuntu 20.04 system, after a following patch
("Step over clone syscall w/ breakpoint,
TARGET_WAITKIND_THREAD_CLONED"), the gdb.threads/step-over-exec.exp
was passing cleanly, but still, we'd end up with four new unexpected
GDB core dumps:
=== gdb Summary ===
# of unexpected core files 4
# of expected passes 48
That said patch is making the pre-existing
gdb.threads/step-over-exec.exp testcase (almost silently) expose a
latent problem in gdb/linux-nat.c, resulting in a GDB crash when:
#1 - a non-leader thread execs
#2 - the post-exec program stops somewhere
#3 - you kill the inferior
Instead of #3 directly, the testcase just returns, which ends up in
gdb_exit, tearing down GDB, which kills the inferior, and is thus
equivalent to #3 above.
Vis (after said patch is applied):
$ gdb --args ./gdb /home/pedro/gdb/build/gdb/testsuite/outputs/gdb.threads/step-over-exec/step-over-exec-execr-thread-other-diff-text-segs-true
...
(top-gdb) r
...
(gdb) b main
...
(gdb) r
...
Breakpoint 1, main (argc=1, argv=0x7fffffffdb88) at /home/pedro/gdb/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.threads/step-over-exec.c:69
69 argv0 = argv[0];
(gdb) c
Continuing.
[New Thread 0x7ffff7d89700 (LWP 2506975)]
Other going in exec.
Exec-ing /home/pedro/gdb/build/gdb/testsuite/outputs/gdb.threads/step-over-exec/step-over-exec-execr-thread-other-diff-text-segs-true-execd
process 2506769 is executing new program: /home/pedro/gdb/build/gdb/testsuite/outputs/gdb.threads/step-over-exec/step-over-exec-execr-thread-other-diff-text-segs-true-execd
Thread 1 "step-over-exec-" hit Breakpoint 1, main () at /home/pedro/gdb/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.threads/step-over-exec-execd.c:28
28 foo ();
(gdb) k
...
Thread 1 "gdb" received signal SIGSEGV, Segmentation fault.
0x000055555574444c in thread_info::has_pending_waitstatus (this=0x0) at ../../src/gdb/gdbthread.h:393
393 return m_suspend.waitstatus_pending_p;
(top-gdb) bt
#0 0x000055555574444c in thread_info::has_pending_waitstatus (this=0x0) at ../../src/gdb/gdbthread.h:393
#1 0x0000555555a884d1 in get_pending_child_status (lp=0x5555579b8230, ws=0x7fffffffd130) at ../../src/gdb/linux-nat.c:1345
#2 0x0000555555a8e5e6 in kill_unfollowed_child_callback (lp=0x5555579b8230) at ../../src/gdb/linux-nat.c:3564
#3 0x0000555555a92a26 in gdb::function_view<int (lwp_info*)>::bind<int, lwp_info*>(int (*)(lwp_info*))::{lambda(gdb::fv_detail::erased_callable, lwp_info*)#1}::operator()(gdb::fv_detail::erased_callable, lwp_info*) const (this=0x0, ecall=..., args#0=0x5555579b8230) at ../../src/gdb/../gdbsupport/function-view.h:284
#4 0x0000555555a92a51 in gdb::function_view<int (lwp_info*)>::bind<int, lwp_info*>(int (*)(lwp_info*))::{lambda(gdb::fv_detail::erased_callable, lwp_info*)#1}::_FUN(gdb::fv_detail::erased_callable, lwp_info*) () at ../../src/gdb/../gdbsupport/function-view.h:278
#5 0x0000555555a91f84 in gdb::function_view<int (lwp_info*)>::operator()(lwp_info*) const (this=0x7fffffffd210, args#0=0x5555579b8230) at ../../src/gdb/../gdbsupport/function-view.h:247
#6 0x0000555555a87072 in iterate_over_lwps(ptid_t, gdb::function_view<int (lwp_info*)>) (filter=..., callback=...) at ../../src/gdb/linux-nat.c:864
#7 0x0000555555a8e732 in linux_nat_target::kill (this=0x55555653af40 <the_amd64_linux_nat_target>) at ../../src/gdb/linux-nat.c:3590
#8 0x0000555555cfdc11 in target_kill () at ../../src/gdb/target.c:911
...
The root of the problem is that when a non-leader LWP execs, it just
changes its tid to the tgid, replacing the pre-exec leader thread,
becoming the new leader. There's no thread exit event for the execing
thread. It's as if the old pre-exec LWP vanishes without trace. The
ptrace man page says:
"PTRACE_O_TRACEEXEC (since Linux 2.5.46)
Stop the tracee at the next execve(2). A waitpid(2) by the
tracer will return a status value such that
status>>8 == (SIGTRAP | (PTRACE_EVENT_EXEC<<8))
If the execing thread is not a thread group leader, the thread
ID is reset to thread group leader's ID before this stop.
Since Linux 3.0, the former thread ID can be retrieved with
PTRACE_GETEVENTMSG."
When the core of GDB processes an exec events, it deletes all the
threads of the inferior. But, that is too late -- deleting the thread
does not delete the corresponding LWP, so we end leaving the pre-exec
non-leader LWP stale in the LWP list. That's what leads to the crash
above -- linux_nat_target::kill iterates over all LWPs, and after the
patch in question, that code will look for the corresponding
thread_info for each LWP. For the pre-exec non-leader LWP still
listed, won't find one.
This patch fixes it, by deleting the pre-exec non-leader LWP (and
thread) from the LWP/thread lists as soon as we get an exec event out
of ptrace.
GDBserver does not need an equivalent fix, because it is already doing
this, as side effect of mourning the pre-exec process, in
gdbserver/linux-low.cc:
else if (event == PTRACE_EVENT_EXEC && cs.report_exec_events)
{
...
/* Delete the execing process and all its threads. */
mourn (proc);
switch_to_thread (nullptr);
The crash with gdb.threads/step-over-exec.exp is not observable on
newer systems, which postdate the glibc change to move "libpthread.so"
internals to "libc.so.6", because right after the exec, GDB traps a
load event for "libc.so.6", which leads to GDB trying to open
libthread_db for the post-exec inferior, and, on such systems that
succeeds. When we load libthread_db, we call
linux_stop_and_wait_all_lwps, which, as the name suggests, stops all
lwps, and then waits to see their stops. While doing this, GDB
detects that the pre-exec stale LWP is gone, and deletes it.
If we use "catch exec" to stop right at the exec before the
"libc.so.6" load event ever happens, and issue "kill" right there,
then GDB crashes on newer systems as well. So instead of tweaking
gdb.threads/step-over-exec.exp to cover the fix, add a new
gdb.threads/threads-after-exec.exp testcase that uses "catch exec".
The test also uses the new "maint info linux-lwps" command if testing
on Linux native, which also exposes the stale LWP problem with an
unfixed GDB.
Also tweak a comment in infrun.c:follow_exec referring to how
linux-nat.c used to behave, as it would become stale otherwise.
Reviewed-By: Andrew Burgess <aburgess@redhat.com>
Change-Id: I21ec18072c7750f3a972160ae6b9e46590376643
---
gdb/infrun.c | 8 +--
gdb/linux-nat.c | 15 +++++
.../gdb.threads/threads-after-exec.c | 56 ++++++++++++++++++
.../gdb.threads/threads-after-exec.exp | 57 +++++++++++++++++++
4 files changed, 131 insertions(+), 5 deletions(-)
create mode 100644 gdb/testsuite/gdb.threads/threads-after-exec.c
create mode 100644 gdb/testsuite/gdb.threads/threads-after-exec.exp
diff --git a/gdb/infrun.c b/gdb/infrun.c
index d259e81df84..b1d50d5cb3d 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -1251,13 +1251,11 @@ follow_exec (ptid_t ptid, const char *exec_file_target)
some other thread does the exec, and even if the main thread was
stopped or already gone. We may still have non-leader threads of
the process on our list. E.g., on targets that don't have thread
- exit events (like remote); or on native Linux in non-stop mode if
- there were only two threads in the inferior and the non-leader
- one is the one that execs (and nothing forces an update of the
- thread list up to here). When debugging remotely, it's best to
+ exit events (like remote) and nothing forces an update of the
+ thread list up to here. When debugging remotely, it's best to
avoid extra traffic, when possible, so avoid syncing the thread
list with the target, and instead go ahead and delete all threads
- of the process but one that reported the event. Note this must
+ of the process but the one that reported the event. Note this must
be done before calling update_breakpoints_after_exec, as
otherwise clearing the threads' resources would reference stale
thread breakpoints -- it may have been one of these threads that
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index c8991cc3da4..2f89d283acc 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -1991,6 +1991,21 @@ linux_handle_extended_wait (struct lwp_info *lp, int status)
thread execs, it changes its tid to the tgid, and the old
tgid thread might have not been resumed. */
lp->resumed = 1;
+
+ /* All other LWPs are gone now. We'll have received a thread
+ exit notification for all threads other the execing one.
+ That one, if it wasn't the leader, just silently changes its
+ tid to the tgid, and the previous leader vanishes. Since
+ Linux 3.0, the former thread ID can be retrieved with
+ PTRACE_GETEVENTMSG, but since we support older kernels, don't
+ bother with it, and just walk the LWP list. Even with
+ PTRACE_GETEVENTMSG, we'd still need to lookup the
+ corresponding LWP object, and it would be an extra ptrace
+ syscall, so this way may even be more efficient. */
+ for (lwp_info *other_lp : all_lwps_safe ())
+ if (other_lp != lp && other_lp->ptid.pid () == lp->ptid.pid ())
+ exit_lwp (other_lp);
+
return 0;
}
diff --git a/gdb/testsuite/gdb.threads/threads-after-exec.c b/gdb/testsuite/gdb.threads/threads-after-exec.c
new file mode 100644
index 00000000000..b3ed7ec5f69
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/threads-after-exec.c
@@ -0,0 +1,56 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2023 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/>. */
+
+#include <pthread.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+static char *program_name;
+
+void *
+thread_execler (void *arg)
+{
+ /* Exec ourselves again, but with an extra argument, to avoid
+ infinite recursion. */
+ if (execl (program_name, program_name, "1", NULL) == -1)
+ {
+ perror ("execl");
+ abort ();
+ }
+
+ return NULL;
+}
+
+int
+main (int argc, char **argv)
+{
+ pthread_t thread;
+
+ if (argc > 1)
+ {
+ /* Getting here via execl. */
+ return 0;
+ }
+
+ program_name = argv[0];
+
+ pthread_create (&thread, NULL, thread_execler, NULL);
+ pthread_join (thread, NULL);
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.threads/threads-after-exec.exp b/gdb/testsuite/gdb.threads/threads-after-exec.exp
new file mode 100644
index 00000000000..cd8adf900d9
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/threads-after-exec.exp
@@ -0,0 +1,57 @@
+# Copyright 2023 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/>.
+
+# Test that after an exec of a non-leader thread, we don't leave the
+# non-leader thread listed in internal thread lists, causing problems.
+
+standard_testfile .c
+
+proc do_test { } {
+ if [prepare_for_testing "failed to prepare" $::testfile $::srcfile {debug pthreads}] {
+ return -1
+ }
+
+ if ![runto_main] {
+ return
+ }
+
+ gdb_test "catch exec" "Catchpoint $::decimal \\(exec\\)"
+
+ gdb_test "continue" "Catchpoint $::decimal .*" "continue until exec"
+
+ # Confirm we only have one thread in the thread list.
+ gdb_test "info threads" "\\* 1\[ \t\]+\[^\r\n\]+.*"
+
+ if {[istarget *-*-linux*] && [gdb_is_target_native]} {
+ # Confirm there's only one LWP in the list as well, and that
+ # it is bound to thread 1.1.
+ set inf_pid [get_inferior_pid]
+ gdb_test_multiple "maint info linux-lwps" "" {
+ -wrap -re "Thread ID *\r\n$inf_pid\.$inf_pid\.0\[ \t\]+1\.1 *" {
+ pass $gdb_test_name
+ }
+ }
+ }
+
+ # Test that GDB is able to kill the inferior. This used to crash
+ # on native Linux as GDB did not dispose of the pre-exec LWP for
+ # the non-leader (and that LWP did not have a matching thread in
+ # the core thread list).
+ gdb_test "with confirm off -- kill" \
+ "\\\[Inferior 1 (.*) killed\\\]" \
+ "kill inferior"
+}
+
+do_test
--
2.35.3

View File

@ -9,9 +9,9 @@ Subject: gdb-linux_perf-bundle.patch
diff --git a/gdb/gdb.c b/gdb/gdb.c
--- a/gdb/gdb.c
+++ b/gdb/gdb.c
@@ -20,11 +20,19 @@
#include "main.h"
@@ -21,6 +21,10 @@
#include "interps.h"
#include "run-on-main-thread.h"
+#ifdef PERF_ATTR_SIZE_VER5_BUNDLE
+extern "C" void __libipt_init(void);
@ -20,6 +20,8 @@ diff --git a/gdb/gdb.c b/gdb/gdb.c
int
main (int argc, char **argv)
{
@@ -32,6 +36,10 @@ main (int argc, char **argv)
struct captured_main_args args;
+#ifdef PERF_ATTR_SIZE_VER5_BUNDLE
@ -32,7 +34,7 @@ diff --git a/gdb/gdb.c b/gdb/gdb.c
diff --git a/gdb/nat/linux-btrace.h b/gdb/nat/linux-btrace.h
--- a/gdb/nat/linux-btrace.h
+++ b/gdb/nat/linux-btrace.h
@@ -27,6 +27,177 @@
@@ -28,6 +28,177 @@
# include <linux/perf_event.h>
#endif
@ -213,7 +215,7 @@ diff --git a/gdb/nat/linux-btrace.h b/gdb/nat/linux-btrace.h
diff --git a/gdbsupport/common.m4 b/gdbsupport/common.m4
--- a/gdbsupport/common.m4
+++ b/gdbsupport/common.m4
@@ -166,7 +166,7 @@ AC_DEFUN([GDB_AC_COMMON], [
@@ -168,7 +168,7 @@ AC_DEFUN([GDB_AC_COMMON], [
AC_PREPROC_IFELSE([AC_LANG_SOURCE([[
#include <linux/perf_event.h>
#ifndef PERF_ATTR_SIZE_VER5

View File

@ -1,3 +1,8 @@
From adfcabe4cc43766996a61bdf08ce1e9db7f18dcc Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 18 Apr 2024 14:27:04 +0200
Subject: [PATCH] gdb-python-finishbreakpoint-update
[gdb/python] FinishBreakPoint update
I.
@ -324,19 +329,18 @@ Tested on x86_64-linux with native and target board unix/-m32, by rebuilding
and running the test-cases:
- gdb.python/py-finish-breakpoint.exp
- gdb.python/py-finish-breakpoint2.exp
---
gdb/breakpoint.c | 10 ++++++++++
gdb/doc/python.texi | 6 ++++--
gdb/python/py-finishbreakpoint.c | 21 +++++++++++++++++++++
gdb/testsuite/gdb.python/py-finish-breakpoint2.exp | 16 +++++++++++++---
4 files changed, 48 insertions(+), 5 deletions(-)
gdb/breakpoint.c | 10 ++++++++++
gdb/doc/python.texi | 6 ++++--
gdb/python/py-finishbreakpoint.c | 20 +++++++++++++++++++
.../gdb.python/py-finish-breakpoint2.exp | 1 +
4 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index dbbea6b8bff..64a9a3d394f 100644
index db7d2e6a8e5..01f187ca4fe 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -15452,6 +15452,10 @@ initialize_breakpoint_ops (void)
@@ -14683,6 +14683,10 @@ breakpoint_free_objfile (struct objfile *objfile)
static struct cmd_list_element *enablebreaklist = NULL;
@ -347,7 +351,7 @@ index dbbea6b8bff..64a9a3d394f 100644
/* See breakpoint.h. */
cmd_list_element *commands_cmd_element = nullptr;
@@ -16065,6 +16069,12 @@ This is useful for formatted output in user-defined commands."));
@@ -15243,8 +15247,14 @@ This is useful for formatted output in user-defined commands."));
gdb::observers::about_to_proceed.attach (breakpoint_about_to_proceed,
"breakpoint");
@ -359,12 +363,14 @@ index dbbea6b8bff..64a9a3d394f 100644
gdb::observers::thread_exit.attach (remove_threaded_breakpoints,
"breakpoint");
+#endif
gdb::observers::inferior_removed.attach (remove_inferior_breakpoints,
"breakpoint");
}
diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
index f4865b3d6a6..17a67800ba2 100644
index 99670cca025..ba414b4e2c3 100644
--- a/gdb/doc/python.texi
+++ b/gdb/doc/python.texi
@@ -5698,7 +5698,7 @@ attribute is @code{None}. This attribute is writable.
@@ -6648,7 +6648,7 @@ is not writable.
@tindex gdb.FinishBreakpoint
A finish breakpoint is a temporary breakpoint set at the return address of
@ -373,7 +379,7 @@ index f4865b3d6a6..17a67800ba2 100644
extends @code{gdb.Breakpoint}. The underlying breakpoint will be disabled
and deleted when the execution will run out of the breakpoint scope (i.e.@:
@code{Breakpoint.stop} or @code{FinishBreakpoint.out_of_scope} triggered).
@@ -5717,7 +5717,9 @@ details about this argument.
@@ -6667,7 +6667,9 @@ details about this argument.
In some circumstances (e.g.@: @code{longjmp}, C@t{++} exceptions, @value{GDBN}
@code{return} command, @dots{}), a function may not properly terminate, and
thus never hit the finish breakpoint. When @value{GDBN} notices such a
@ -385,25 +391,25 @@ index f4865b3d6a6..17a67800ba2 100644
You may want to sub-class @code{gdb.FinishBreakpoint} and override this
method:
diff --git a/gdb/python/py-finishbreakpoint.c b/gdb/python/py-finishbreakpoint.c
index 1d8373d807e..a881103fdad 100644
index 42a7e0706d2..fa7ec43fbb4 100644
--- a/gdb/python/py-finishbreakpoint.c
+++ b/gdb/python/py-finishbreakpoint.c
@@ -398,6 +398,24 @@ bpfinishpy_handle_exit (struct inferior *inf)
bpfinishpy_detect_out_scope_cb (bp, nullptr);
@@ -433,6 +433,24 @@ bpfinishpy_handle_exit (struct inferior *inf)
bpfinishpy_detect_out_scope_cb (&bp, nullptr, true);
}
+/* Attached to `thread_exit' notifications, triggers all the necessary out of
+ scope notifications. */
+
+static void
+bpfinishpy_handle_thread_exit (struct thread_info *tp, int ignore)
+bpfinishpy_handle_thread_exit (struct thread_info *tp, gdb::optional<ULONGEST>, bool)
+{
+ gdbpy_enter enter_py (target_gdbarch (), current_language);
+
+ for (breakpoint *bp : all_breakpoints_safe ())
+ for (breakpoint &bp : all_breakpoints_safe ())
+ {
+ if (tp->global_num == bp->thread)
+ bpfinishpy_detect_out_scope_cb (bp, nullptr);
+ if (tp->global_num == bp.thread)
+ bpfinishpy_detect_out_scope_cb (&bp, nullptr, true);
+ }
+}
+
@ -412,42 +418,30 @@ index 1d8373d807e..a881103fdad 100644
+
/* Initialize the Python finish breakpoint code. */
int
@@ -414,6 +432,9 @@ gdbpy_initialize_finishbreakpoints (void)
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
@@ -452,6 +470,8 @@ gdbpy_initialize_finishbreakpoints (void)
"py-finishbreakpoint");
gdb::observers::inferior_exit.attach (bpfinishpy_handle_exit,
"py-finishbreakpoint");
+ gdb::observers::thread_exit.attach
+ (bpfinishpy_handle_thread_exit,
+ bpfinishpy_handle_thread_exit_observer_token, "py-finishbreakpoint");
+ (bpfinishpy_handle_thread_exit, "py-finishbreakpoint");
return 0;
}
diff --git a/gdb/testsuite/gdb.python/py-finish-breakpoint2.exp b/gdb/testsuite/gdb.python/py-finish-breakpoint2.exp
index 58e086ad3b4..46c39d0d108 100644
index 66587b8b9a0..31479a05e6f 100644
--- a/gdb/testsuite/gdb.python/py-finish-breakpoint2.exp
+++ b/gdb/testsuite/gdb.python/py-finish-breakpoint2.exp
@@ -50,10 +50,20 @@ gdb_test "continue" "Breakpoint .*throw_exception_1.*" "run to exception 1"
gdb_test "python print (len(gdb.breakpoints()))" "3" "check BP count"
gdb_test "python ExceptionFinishBreakpoint(gdb.newest_frame())" \
"init ExceptionFinishBreakpoint" "set FinishBP after the exception"
-gdb_test "continue" ".*stopped at ExceptionFinishBreakpoint.*" "check FinishBreakpoint in catch()"
-gdb_test "python print (len(gdb.breakpoints()))" "3" "check finish BP removal"
-gdb_test "continue" ".*Breakpoint.* throw_exception_1.*" "continue to second exception"
+gdb_test_multiple "continue" "continue after setting FinishBreakpoint" {
+ -re -wrap ".*stopped at ExceptionFinishBreakpoint.*" {
+ pass "$gdb_test_name (scenario 1, triggered)"
+ gdb_test "python print (len(gdb.breakpoints()))" "3" \
+ "check finish BP removal"
+ gdb_test "continue" ".*Breakpoint.* throw_exception_1.*" \
+ "continue to second exception"
+ }
+ -re -wrap ".*Breakpoint.* throw_exception_1.*" {
+ pass "$gdb_test_name (scenario 2, not triggered)"
+ }
+}
@@ -87,6 +87,7 @@ if { $need_continue } {
gdb_test "continue" ".*Breakpoint.* throw_exception_1.*" \
"continue to second exception"
}
+
gdb_test "python ExceptionFinishBreakpoint(gdb.newest_frame())" \
"init ExceptionFinishBreakpoint" "set FinishBP after the exception again"
gdb_test "continue" ".*exception did not finish.*" "FinishBreakpoint with exception thrown not caught"
base-commit: 6de9111c512de99fd8cb3ea89f9890b1d72f6ef0
--
2.35.3

View File

@ -0,0 +1,61 @@
From eafca1ce3d589c731927e5481199db715bcbeff3 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Sat, 2 Mar 2024 09:35:22 +0100
Subject: [PATCH 2/2] [gdb/python] Make gdb.UnwindInfo.add_saved_register more
robust
On arm-linux, until commit bbb12eb9c84 ("gdb/arm: Remove tpidruro register
from non-FreeBSD target descriptions") I ran into:
...
FAIL: gdb.base/inline-frame-cycle-unwind.exp: cycle at level 5: \
backtrace when the unwind is broken at frame 5
...
What happens is the following:
- the TestUnwinder from inline-frame-cycle-unwind.py calls
gdb.UnwindInfo.add_saved_register with reg == tpidruro and value
"<unavailable>",
- pyuw_sniffer calls value->contents ().data () to access the value of the
register, which throws an UNAVAILABLE_ERROR,
- this causes the TestUnwinder unwinder to fail, after which another unwinder
succeeds and returns the correct frame, and
- the test-case fails because it's counting on the TestUnwinder to succeed and
return an incorrect frame.
Fix this by checking for !value::entirely_available as well as
valued::optimized_out in unwind_infopy_add_saved_register.
Tested on x86_64-linux and arm-linux.
PR python/31437
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31437
---
gdb/python/py-unwind.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/gdb/python/py-unwind.c b/gdb/python/py-unwind.c
index 1856e41e2a1..471eb851674 100644
--- a/gdb/python/py-unwind.c
+++ b/gdb/python/py-unwind.c
@@ -354,6 +354,18 @@ unwind_infopy_add_saved_register (PyObject *self, PyObject *args, PyObject *kw)
return nullptr;
}
+ if (value->optimized_out () || !value->entirely_available ())
+ {
+ /* If we allow this value to be registered here, pyuw_sniffer is going
+ to run into an exception when trying to access its contents.
+ Throwing an exception here just puts a burden on the user to
+ implement the same checks on the user side. We could return False
+ here and True otherwise, but again that might require changes in user
+ code. So, handle this with minimal impact for the user, while
+ improving robustness: silently ignore the register/value pair. */
+ Py_RETURN_NONE;
+ }
+
gdbpy_ref<> new_value = gdbpy_ref<>::new_reference (pyo_reg_value);
bool found = false;
for (saved_reg &reg : *unwind_info->saved_regs)
--
2.35.3

View File

@ -0,0 +1,229 @@
From 0ad71e3088f345101085a1f72e81a000a100db18 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Sat, 27 Apr 2024 17:48:22 +0200
Subject: [PATCH 25/48] [gdb/remote] Fix abort on REMOTE_CLOSE_ERROR
When running test-case gdb.server/connect-with-no-symbol-file.exp on
aarch64-linux (specifically, an opensuse leap 15.5 container on a
fedora asahi 39 system), I run into:
...
(gdb) detach^M
Detaching from program: target:connect-with-no-symbol-file, process 185104^M
Ending remote debugging.^M
terminate called after throwing an instance of 'gdb_exception_error'^M
...
The detailed backtrace of the corefile is:
...
(gdb) bt
#0 0x0000ffff75504f54 in raise () from /lib64/libpthread.so.0
#1 0x00000000007a86b4 in handle_fatal_signal (sig=6)
at gdb/event-top.c:926
#2 <signal handler called>
#3 0x0000ffff74b977b4 in raise () from /lib64/libc.so.6
#4 0x0000ffff74b98c18 in abort () from /lib64/libc.so.6
#5 0x0000ffff74ea26f4 in __gnu_cxx::__verbose_terminate_handler() ()
from /usr/lib64/libstdc++.so.6
#6 0x0000ffff74ea011c in ?? () from /usr/lib64/libstdc++.so.6
#7 0x0000ffff74ea0180 in std::terminate() () from /usr/lib64/libstdc++.so.6
#8 0x0000ffff74ea0464 in __cxa_throw () from /usr/lib64/libstdc++.so.6
#9 0x0000000001548870 in throw_it (reason=RETURN_ERROR,
error=TARGET_CLOSE_ERROR, fmt=0x16c7810 "Remote connection closed", ap=...)
at gdbsupport/common-exceptions.cc:203
#10 0x0000000001548920 in throw_verror (error=TARGET_CLOSE_ERROR,
fmt=0x16c7810 "Remote connection closed", ap=...)
at gdbsupport/common-exceptions.cc:211
#11 0x0000000001548a00 in throw_error (error=TARGET_CLOSE_ERROR,
fmt=0x16c7810 "Remote connection closed")
at gdbsupport/common-exceptions.cc:226
#12 0x0000000000ac8f2c in remote_target::readchar (this=0x233d3d90, timeout=2)
at gdb/remote.c:9856
#13 0x0000000000ac9f04 in remote_target::getpkt (this=0x233d3d90,
buf=0x233d40a8, forever=false, is_notif=0x0) at gdb/remote.c:10326
#14 0x0000000000acf3d0 in remote_target::remote_hostio_send_command
(this=0x233d3d90, command_bytes=13, which_packet=17,
remote_errno=0xfffff1a3cf38, attachment=0xfffff1a3ce88,
attachment_len=0xfffff1a3ce90) at gdb/remote.c:12567
#15 0x0000000000ad03bc in remote_target::fileio_fstat (this=0x233d3d90, fd=3,
st=0xfffff1a3d020, remote_errno=0xfffff1a3cf38)
at gdb/remote.c:12979
#16 0x0000000000c39878 in target_fileio_fstat (fd=0, sb=0xfffff1a3d020,
target_errno=0xfffff1a3cf38) at gdb/target.c:3315
#17 0x00000000007eee5c in target_fileio_stream::stat (this=0x233d4400,
abfd=0x2323fc40, sb=0xfffff1a3d020) at gdb/gdb_bfd.c:467
#18 0x00000000007f012c in <lambda(bfd*, void*, stat*)>::operator()(bfd *,
void *, stat *) const (__closure=0x0, abfd=0x2323fc40, stream=0x233d4400,
sb=0xfffff1a3d020) at gdb/gdb_bfd.c:955
#19 0x00000000007f015c in <lambda(bfd*, void*, stat*)>::_FUN(bfd *, void *,
stat *) () at gdb/gdb_bfd.c:956
#20 0x0000000000f9b838 in opncls_bstat (abfd=0x2323fc40, sb=0xfffff1a3d020)
at bfd/opncls.c:665
#21 0x0000000000f90adc in bfd_stat (abfd=0x2323fc40, statbuf=0xfffff1a3d020)
at bfd/bfdio.c:431
#22 0x000000000065fe20 in reopen_exec_file () at gdb/corefile.c:52
#23 0x0000000000c3a3e8 in generic_mourn_inferior ()
at gdb/target.c:3642
#24 0x0000000000abf3f0 in remote_unpush_target (target=0x233d3d90)
at gdb/remote.c:6067
#25 0x0000000000aca8b0 in remote_target::mourn_inferior (this=0x233d3d90)
at gdb/remote.c:10587
#26 0x0000000000c387cc in target_mourn_inferior (
ptid=<error reading variable: Cannot access memory at address 0x2d310>)
at gdb/target.c:2738
#27 0x0000000000abfff0 in remote_target::remote_detach_1 (this=0x233d3d90,
inf=0x22fce540, from_tty=1) at gdb/remote.c:6421
#28 0x0000000000ac0094 in remote_target::detach (this=0x233d3d90,
inf=0x22fce540, from_tty=1) at gdb/remote.c:6436
#29 0x0000000000c37c3c in target_detach (inf=0x22fce540, from_tty=1)
at gdb/target.c:2526
#30 0x0000000000860424 in detach_command (args=0x0, from_tty=1)
at gdb/infcmd.c:2817
#31 0x000000000060b594 in do_simple_func (args=0x0, from_tty=1, c=0x231431a0)
at gdb/cli/cli-decode.c:94
#32 0x00000000006108c8 in cmd_func (cmd=0x231431a0, args=0x0, from_tty=1)
at gdb/cli/cli-decode.c:2741
#33 0x0000000000c65a94 in execute_command (p=0x232e52f6 "", from_tty=1)
at gdb/top.c:570
#34 0x00000000007a7d2c in command_handler (command=0x232e52f0 "")
at gdb/event-top.c:566
#35 0x00000000007a8290 in command_line_handler (rl=...)
at gdb/event-top.c:802
#36 0x0000000000c9092c in tui_command_line_handler (rl=...)
at gdb/tui/tui-interp.c:103
#37 0x00000000007a750c in gdb_rl_callback_handler (rl=0x23385330 "detach")
at gdb/event-top.c:258
#38 0x0000000000d910f4 in rl_callback_read_char ()
at readline/readline/callback.c:290
#39 0x00000000007a7338 in gdb_rl_callback_read_char_wrapper_noexcept ()
at gdb/event-top.c:194
#40 0x00000000007a73f0 in gdb_rl_callback_read_char_wrapper
(client_data=0x22fbf640) at gdb/event-top.c:233
#41 0x0000000000cbee1c in stdin_event_handler (error=0, client_data=0x22fbf640)
at gdb/ui.c:154
#42 0x000000000154ed60 in handle_file_event (file_ptr=0x232be730, ready_mask=1)
at gdbsupport/event-loop.cc:572
#43 0x000000000154f21c in gdb_wait_for_event (block=1)
at gdbsupport/event-loop.cc:693
#44 0x000000000154dec4 in gdb_do_one_event (mstimeout=-1)
at gdbsupport/event-loop.cc:263
#45 0x0000000000910f98 in start_event_loop () at gdb/main.c:400
#46 0x0000000000911130 in captured_command_loop () at gdb/main.c:464
#47 0x0000000000912b5c in captured_main (data=0xfffff1a3db58)
at gdb/main.c:1338
#48 0x0000000000912bf4 in gdb_main (args=0xfffff1a3db58)
at gdb/main.c:1357
#49 0x00000000004170f4 in main (argc=10, argv=0xfffff1a3dcc8)
at gdb/gdb.c:38
(gdb)
...
The abort happens because a c++ exception escapes to c code, specifically
opncls_bstat in bfd/opncls.c. Compiling with -fexceptions works around this.
Fix this by catching the exception just before it escapes, in stat_trampoline
and likewise in few similar spot.
Add a new template catch_exceptions to do so in a consistent way.
Tested on aarch64-linux.
Approved-by: Pedro Alves <pedro@palves.net>
PR remote/31577
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31577
---
gdb/gdb_bfd.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 56 insertions(+), 3 deletions(-)
diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c
index 217753cf914..3c34cc5693f 100644
--- a/gdb/gdb_bfd.c
+++ b/gdb/gdb_bfd.c
@@ -887,6 +887,29 @@ gdb_bfd_openw (const char *filename, const char *target)
return gdb_bfd_ref_ptr::new_reference (result);
}
+/* Wrap f (args) and handle exceptions by:
+ - returning val, and
+ - calling set_quit_flag or set_force_quit_flag, if needed. */
+
+template <typename R, R val, typename F, typename... Args>
+static R
+catch_exceptions (F &&f, Args&&... args)
+{
+ try
+ {
+ return f (std::forward<Args> (args)...);
+ }
+ catch (const gdb_exception &ex)
+ {
+ if (ex.reason == RETURN_QUIT)
+ set_quit_flag ();
+ else if (ex.reason == RETURN_FORCED_QUIT)
+ set_force_quit_flag ();
+ }
+
+ return val;
+}
+
/* See gdb_bfd.h. */
gdb_bfd_ref_ptr
@@ -896,21 +919,51 @@ gdb_bfd_openr_iovec (const char *filename, const char *target,
auto do_open = [] (bfd *nbfd, void *closure) -> void *
{
auto real_opener = static_cast<gdb_iovec_opener_ftype *> (closure);
- return (*real_opener) (nbfd);
+ /* Prevent exceptions from escaping to C code and triggering an abort. */
+ auto res = catch_exceptions<gdb_bfd_iovec_base *, nullptr> ([&]
+ {
+ return (*real_opener) (nbfd);
+ });
+ if (res == nullptr)
+ {
+ errno = EIO;
+ bfd_set_error (bfd_error_system_call);
+ }
+ return res;
};
auto read_trampoline = [] (bfd *nbfd, void *stream, void *buf,
file_ptr nbytes, file_ptr offset) -> file_ptr
{
gdb_bfd_iovec_base *obj = static_cast<gdb_bfd_iovec_base *> (stream);
- return obj->read (nbfd, buf, nbytes, offset);
+ /* Prevent exceptions from escaping to C code and triggering an abort. */
+ auto res = catch_exceptions<long int, -1> ([&]
+ {
+ return obj->read (nbfd, buf, nbytes, offset);
+ });
+ if (res == -1)
+ {
+ errno = EIO;
+ bfd_set_error (bfd_error_system_call);
+ }
+ return res;
};
auto stat_trampoline = [] (struct bfd *abfd, void *stream,
struct stat *sb) -> int
{
gdb_bfd_iovec_base *obj = static_cast<gdb_bfd_iovec_base *> (stream);
- return obj->stat (abfd, sb);
+ /* Prevent exceptions from escaping to C code and triggering an abort. */
+ auto res = catch_exceptions<int, -1> ([&]
+ {
+ return obj->stat (abfd, sb);
+ });
+ if (res == -1)
+ {
+ errno = EIO;
+ bfd_set_error (bfd_error_system_call);
+ }
+ return res;
};
auto close_trampoline = [] (struct bfd *nbfd, void *stream) -> int
--
2.35.3

View File

@ -206,7 +206,7 @@ diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c
/* But it should still be a new element in the hash table. */
gdb_assert (slot->name == nullptr);
@@ -388,7 +437,7 @@ write_hash_table (mapped_symtab *symtab, data_buf &output, data_buf &cpool)
@@ -387,7 +436,7 @@ write_hash_table (mapped_symtab *symtab, data_buf &output, data_buf &cpool)
/* We add all the index vectors to the constant pool first, to
ensure alignment is ok. */
@ -215,7 +215,7 @@ diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c
{
if (entry.name == NULL)
continue;
@@ -417,7 +466,7 @@ write_hash_table (mapped_symtab *symtab, data_buf &output, data_buf &cpool)
@@ -416,7 +465,7 @@ write_hash_table (mapped_symtab *symtab, data_buf &output, data_buf &cpool)
/* Now write out the hash table. */
std::unordered_map<c_str_view, offset_type, c_str_view_hasher> str_table;
@ -224,7 +224,7 @@ diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c
{
offset_type str_off, vec_off;
@@ -1149,7 +1198,7 @@ write_cooked_index (cooked_index_vector *table,
@@ -1151,7 +1200,7 @@ write_cooked_index (cooked_index *table,
const auto it = cu_index_htab.find (entry->per_cu);
gdb_assert (it != cu_index_htab.cend ());
@ -233,16 +233,16 @@ diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c
if (entry->per_cu->lang () == language_ada)
{
@@ -1169,7 +1218,7 @@ write_cooked_index (cooked_index_vector *table,
gdb, it has to use the encoded name, with any
suffixes stripped. */
std::string encoded = ada_encode (name, false);
- name = obstack_strdup (&symtab->m_string_obstack,
+ name = obstack_strdup (symtab->obstack (),
encoded.c_str ());
}
@@ -1159,7 +1208,7 @@ write_cooked_index (cooked_index *table,
gdb, it has to use the encoded name, with any
suffixes stripped. */
std::string encoded = ada_encode (name, false);
- name = obstack_strdup (&symtab->m_string_obstack,
+ name = obstack_strdup (symtab->obstack (),
encoded.c_str ());
}
@@ -1202,8 +1251,8 @@ write_cooked_index (cooked_index_vector *table,
else if (entry->per_cu->lang () == language_cplus
@@ -1191,8 +1240,8 @@ write_cooked_index (cooked_index *table,
else
kind = GDB_INDEX_SYMBOL_KIND_TYPE;
@ -253,7 +253,7 @@ diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c
}
}
@@ -1281,8 +1330,6 @@ write_gdbindex (dwarf2_per_objfile *per_objfile,
@@ -1267,8 +1316,6 @@ write_gdbindex (dwarf2_per_bfd *per_bfd, cooked_index *table,
symtab.minimize ();
data_buf symtab_vec, constant_pool;

View File

@ -35,7 +35,7 @@ Approved-By: Tom Tromey <tom@tromey.com>
diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c
--- a/gdb/dwarf2/index-write.c
+++ b/gdb/dwarf2/index-write.c
@@ -453,6 +453,11 @@ class c_str_view
@@ -452,6 +452,11 @@ class c_str_view
return strcmp (m_cstr, other.m_cstr) == 0;
}
@ -47,7 +47,7 @@ diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c
/* Return the underlying C string. Note, the returned string is
only a reference with lifetime of this object. */
const char *c_str () const
@@ -770,10 +775,18 @@ class debug_names
@@ -771,10 +776,18 @@ class debug_names
}
for (size_t bucket_ix = 0; bucket_ix < bucket_hash.size (); ++bucket_ix)
{

View File

@ -138,7 +138,7 @@ diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c
/* See class definition. */
void
@@ -1325,6 +1391,9 @@ write_gdbindex (dwarf2_per_objfile *per_objfile,
@@ -1311,6 +1377,9 @@ write_gdbindex (dwarf2_per_bfd *per_bfd, cooked_index *table,
for (auto map : table->get_addrmaps ())
write_address_map (map, addr_vec, cu_index_htab);
@ -206,8 +206,8 @@ diff --git a/gdb/testsuite/gdb.gdb/index-file.exp b/gdb/testsuite/gdb.gdb/index-
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -9274,6 +9274,21 @@ proc gdb_step_until { regexp {test_name ""} {max_steps 10} } {
}
@@ -10033,6 +10033,21 @@ proc is_target_non_stop { {testname ""} } {
return $is_non_stop
}
+# Return the number of worker threads that GDB is currently using.

View File

@ -1,105 +0,0 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Kevin Buettner <kevinb@redhat.com>
Date: Mon, 2 Oct 2023 15:05:23 -0700
Subject: gdb-rhbz1773651-gdb-index-internal-error.patch
;; Backport upstream patch which prevents internal error when
;; generating a gdb-index file (RH BZ 1773651).
Throw error when creating an overly large gdb-index file
The header in a .gdb_index section uses 32-bit unsigned offsets to
refer to other areas of the section. Thus, there is a size limit of
2^32-1 which is currently unaccounted for by GDB's code for outputting
these sections.
At the moment, when GDB creates an overly large section, it will exit
abnormally due to an internal error, which is caused by a failed
assert in assert_file_size, which in turn is called from
write_gdbindex_1, both of which are in gdb/dwarf2/index-write.c.
This is what happens when that assert fails:
$ gdb -q -nx -iex 'set auto-load no' -iex 'set debuginfod enabled off' -ex file ./libgraph_tool_inference.so -ex "save gdb-index `pwd`/"
Reading symbols from ./libgraph_tool_inference.so...
No executable file now.
Discard symbol table from `libgraph_tool_inference.so'? (y or n) n
Not confirmed.
../../gdb/dwarf2/index-write.c:1069: internal-error: assert_file_size: Assertion `file_size == expected_size' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
----- Backtrace -----
0x55fddb4d78b0 gdb_internal_backtrace_1
../../gdb/bt-utils.c:122
0x55fddb4d78b0 _Z22gdb_internal_backtracev
../../gdb/bt-utils.c:168
0x55fddb98b5d4 internal_vproblem
../../gdb/utils.c:396
0x55fddb98b8de _Z15internal_verrorPKciS0_P13__va_list_tag
../../gdb/utils.c:476
0x55fddbb71654 _Z18internal_error_locPKciS0_z
../../gdbsupport/errors.cc:58
0x55fddb5a0f23 assert_file_size
../../gdb/dwarf2/index-write.c:1069
0x55fddb5a1ee0 assert_file_size
/usr/include/c++/13/bits/stl_iterator.h:1158
0x55fddb5a1ee0 write_gdbindex_1
../../gdb/dwarf2/index-write.c:1119
0x55fddb5a51be write_gdbindex
../../gdb/dwarf2/index-write.c:1273
[...]
---------------------
../../gdb/dwarf2/index-write.c:1069: internal-error: assert_file_size: Assertion `file_size == expected_size' failed.
This problem was encountered while building the python-graph-tool
package on Fedora. The Fedora bugzilla bug can be found here:
https://bugzilla.redhat.com/show_bug.cgi?id=1773651
This commit prevents the internal error from occurring by calling error()
when the file size exceeds 2^32-1.
Using a gdb built with this commit, I now see this behavior instead:
$ gdb -q -nx -iex 'set auto-load no' -iex 'set debuginfod enabled off' -ex file ./libgraph_tool_inference.so -ex "save gdb-index `pwd`/"
Reading symbols from ./libgraph_tool_inference.so...
No executable file now.
Discard symbol table from `/mesquite2/fedora-bugs/1773651/libgraph_tool_inference.so'? (y or n) n
Not confirmed.
Error while writing index for `/mesquite2/fedora-bugs/1773651/libgraph_tool_inference.so': gdb-index maximum file size of 4294967295 exceeded
(gdb)
I wish I could provide a test case, but due to the sizes of both the
input and output files, I think that testing resources would be
strained or exceeded in many environments.
My testing on Fedora 38 shows no regressions.
Approved-by: Tom Tromey <tom@tromey.com>
diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c
--- a/gdb/dwarf2/index-write.c
+++ b/gdb/dwarf2/index-write.c
@@ -1082,7 +1082,7 @@ write_gdbindex_1 (FILE *out_file,
{
data_buf contents;
const offset_type size_of_header = 6 * sizeof (offset_type);
- offset_type total_len = size_of_header;
+ size_t total_len = size_of_header;
/* The version number. */
contents.append_offset (8);
@@ -1109,6 +1109,13 @@ write_gdbindex_1 (FILE *out_file,
gdb_assert (contents.size () == size_of_header);
+ /* The maximum size of an index file is limited by the maximum value
+ capable of being represented by 'offset_type'. Throw an error if
+ that length has been exceeded. */
+ size_t max_size = ~(offset_type) 0;
+ if (total_len > max_size)
+ error (_("gdb-index maximum file size of %zu exceeded"), max_size);
+
contents.file_write (out_file);
cu_list.file_write (out_file);
types_cu_list.file_write (out_file);

View File

@ -1,108 +0,0 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Kevin Buettner <kevinb@redhat.com>
Date: Thu, 29 Jun 2023 18:20:30 -0700
Subject: gdb-rhbz2160211-excessive-core-file-warnings.patch
;; Backport two commits, 0ad504dd464 and ea70f941f9b, from Lancelot SIX
;; which prevent repeated warnings from being printed while loading a
;; core file. (RH BZ 2160211)
gdb/corelow.c: avoid repeated warnings in build_file_mappings
When GDB opens a coredump it tries to locate and then open all files
which were mapped in the process.
If a file is found but cannot be opened with BFD (bfd_open /
bfd_check_format fails), then a warning is printed to the user. If the
same file was mapped multiple times in the process's address space, the
warning is printed once for each time the file was mapped. I find this
un-necessarily noisy.
This patch makes it so the warning message is printed only once per
file.
There was a comment in the code assuming that if the file was found on
the system, opening it (bfd_open + bfd_check_format) should always
succeed. A recent change in BFD (014a602b86f "Don't optimise bfd_seek
to same position") showed that this assumption is not valid. For
example, it is possible to have a core dump of a process which had
mmaped an IO page from a DRI render node (/dev/dri/runderD$NUM). In
such case the core dump does contain the information that portions of
this special file were mapped in the host process, but trying to seek to
position 0 will fail, making bfd_check_format fail. This patch removes
this comment.
Reviewed-By: John Baldwin <jhb@FreeBSD.org>
Approved-By: Andrew Burgess <aburgess@redhat.com>
gdb/corelow.c: do not try to reopen a file if open failed once
In the current implementation, core_target::build_file_mappings will try
to locate and open files which were mapped in the process for which the
core dump was produced. If the file cannot be found or cannot be
opened, GDB will re-try to open it once for each time it was mapped in
the process's address space.
This patch makes it so GDB recognizes that it has already failed to open
a given file once and does not re-try the process for each mapping.
Reviewed-By: John Baldwin <jhb@FreeBSD.org>
Approved-By: Andrew Burgess <aburgess@redhat.com>
diff --git a/gdb/corelow.c b/gdb/corelow.c
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -237,6 +237,16 @@ core_target::build_file_mappings ()
weed out non-file-backed mappings. */
gdb_assert (filename != nullptr);
+ if (unavailable_paths.find (filename) != unavailable_paths.end ())
+ {
+ /* We have already seen some mapping for FILENAME but failed to
+ find/open the file. There is no point in trying the same
+ thing again so just record that the range [start, end) is
+ unavailable. */
+ m_core_unavailable_mappings.emplace_back (start, end - start);
+ return;
+ }
+
struct bfd *bfd = bfd_map[filename];
if (bfd == nullptr)
{
@@ -254,11 +264,10 @@ core_target::build_file_mappings ()
if (expanded_fname == nullptr)
{
m_core_unavailable_mappings.emplace_back (start, end - start);
- /* Print just one warning per path. */
- if (unavailable_paths.insert (filename).second)
- warning (_("Can't open file %s during file-backed mapping "
- "note processing"),
- filename);
+ unavailable_paths.insert (filename);
+ warning (_("Can't open file %s during file-backed mapping "
+ "note processing"),
+ filename);
return;
}
@@ -268,18 +277,11 @@ core_target::build_file_mappings ()
if (bfd == nullptr || !bfd_check_format (bfd, bfd_object))
{
m_core_unavailable_mappings.emplace_back (start, end - start);
- /* If we get here, there's a good chance that it's due to
- an internal error. We issue a warning instead of an
- internal error because of the possibility that the
- file was removed in between checking for its
- existence during the expansion in exec_file_find()
- and the calls to bfd_openr() / bfd_check_format().
- Output both the path from the core file note along
- with its expansion to make debugging this problem
- easier. */
+ unavailable_paths.insert (filename);
warning (_("Can't open file %s which was expanded to %s "
"during file-backed mapping note processing"),
filename, expanded_fname.get ());
+
if (bfd != nullptr)
bfd_close (bfd);
return;

View File

@ -1,107 +0,0 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Kevin Buettner <kevinb@redhat.com>
Date: Wed, 3 May 2023 11:28:24 -0700
Subject: gdb-rhbz2192105-ftbs-dangling-pointer
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
;; Backport upstream patch fixing a "dangling pointer" build problem
;; first seen when building with GCC 13.1.1 20230426 (Red Hat ;; 13.1.1-1).
Pass const frame_info_ptr reference for skip_[language_]trampoline
g++ 13.1.1 produces a -Werror=dangling-pointer=
In file included from ../../binutils-gdb/gdb/frame.h:75,
from ../../binutils-gdb/gdb/symtab.h:40,
from ../../binutils-gdb/gdb/language.c:33:
In member function void intrusive_list<T, AsNode>::push_empty(T&) [with T = frame_info_ptr; AsNode = intrusive_base_node<frame_info_ptr>],
inlined from void intrusive_list<T, AsNode>::push_back(reference) [with T = frame_info_ptr; AsNode = intrusive_base_node<frame_info_ptr>] at gdbsupport/intrusive_list.h:332:24,
inlined from frame_info_ptr::frame_info_ptr(const frame_info_ptr&) at gdb/frame.h:241:26,
inlined from CORE_ADDR skip_language_trampoline(frame_info_ptr, CORE_ADDR) at gdb/language.c:530:49:
gdbsupport/intrusive_list.h:415:12: error: storing the address of local variable <anonymous> in frame_info_ptr::frame_list.intrusive_list<frame_info_ptr>::m_back [-Werror=dangling-pointer=]
415 | m_back = &elem;
| ~~~~~~~^~~~~~~
gdb/language.c: In function CORE_ADDR skip_language_trampoline(frame_info_ptr, CORE_ADDR):
gdb/language.c:530:49: note: <anonymous> declared here
530 | CORE_ADDR real_pc = lang->skip_trampoline (frame, pc);
| ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~
gdb/frame.h:359:41: note: frame_info_ptr::frame_list declared here
359 | static intrusive_list<frame_info_ptr> frame_list;
| ^~~~~~~~~~
Each new frame_info_ptr is being pushed on a static frame list and g++
cannot see why that is safe in case the frame_info_ptr is created and
destroyed immediately when passed as value.
It isn't clear why only in this one place g++ sees the issue (probably
because it can inline enough code in this specific case).
Since passing the frame_info_ptr as const reference is cheaper, use
that as workaround for this warning.
PR build/30413
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30413
Tested-by: Kevin Buettner <kevinb@redhat.com>
Reviewed-by: Kevin Buettner <kevinb@redhat.com>
Reviewed-by: Tom Tromey <tom@tromey.com>
diff --git a/gdb/c-lang.c b/gdb/c-lang.c
--- a/gdb/c-lang.c
+++ b/gdb/c-lang.c
@@ -1003,7 +1003,7 @@ class cplus_language : public language_defn
/* See language.h. */
- CORE_ADDR skip_trampoline (frame_info_ptr fi,
+ CORE_ADDR skip_trampoline (const frame_info_ptr &fi,
CORE_ADDR pc) const override
{
return cplus_skip_trampoline (fi, pc);
diff --git a/gdb/language.c b/gdb/language.c
--- a/gdb/language.c
+++ b/gdb/language.c
@@ -528,7 +528,7 @@ add_set_language_command ()
Return the result from the first that returns non-zero, or 0 if all
`fail'. */
CORE_ADDR
-skip_language_trampoline (frame_info_ptr frame, CORE_ADDR pc)
+skip_language_trampoline (const frame_info_ptr &frame, CORE_ADDR pc)
{
for (const auto &lang : language_defn::languages)
{
diff --git a/gdb/language.h b/gdb/language.h
--- a/gdb/language.h
+++ b/gdb/language.h
@@ -471,7 +471,7 @@ struct language_defn
If that PC falls in a trampoline belonging to this language, return
the address of the first pc in the real function, or 0 if it isn't a
language tramp for this language. */
- virtual CORE_ADDR skip_trampoline (frame_info_ptr fi, CORE_ADDR pc) const
+ virtual CORE_ADDR skip_trampoline (const frame_info_ptr &fi, CORE_ADDR pc) const
{
return (CORE_ADDR) 0;
}
@@ -789,7 +789,7 @@ extern const char *language_str (enum language);
/* Check for a language-specific trampoline. */
-extern CORE_ADDR skip_language_trampoline (frame_info_ptr, CORE_ADDR pc);
+extern CORE_ADDR skip_language_trampoline (const frame_info_ptr &, CORE_ADDR pc);
/* Return demangled language symbol, or NULL. */
extern gdb::unique_xmalloc_ptr<char> language_demangle
diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c
--- a/gdb/objc-lang.c
+++ b/gdb/objc-lang.c
@@ -282,7 +282,7 @@ class objc_language : public language_defn
/* See language.h. */
- CORE_ADDR skip_trampoline (frame_info_ptr frame,
+ CORE_ADDR skip_trampoline (const frame_info_ptr &frame,
CORE_ADDR stop_pc) const override
{
struct gdbarch *gdbarch = get_frame_arch (frame);

View File

@ -1,50 +0,0 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= <ahajkova@redhat.com>
Date: Sun, 17 Sep 2023 13:36:13 +0200
Subject: gdb-rhbz2233961-CVE-2022-4806.patch
;; Backport PR29922, SHT_NOBITS section
;; avoids section size sanity check.
PR29922, SHT_NOBITS section avoids section size sanity check
PR 29922
* dwarf2.c (find_debug_info): Ignore sections without
SEC_HAS_CONTENTS.
diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c
--- a/bfd/dwarf2.c
+++ b/bfd/dwarf2.c
@@ -4831,16 +4831,19 @@ find_debug_info (bfd *abfd, const struct dwarf_debug_section *debug_sections,
{
look = debug_sections[debug_info].uncompressed_name;
msec = bfd_get_section_by_name (abfd, look);
- if (msec != NULL)
+ /* Testing SEC_HAS_CONTENTS is an anti-fuzzer measure. Of
+ course debug sections always have contents. */
+ if (msec != NULL && (msec->flags & SEC_HAS_CONTENTS) != 0)
return msec;
look = debug_sections[debug_info].compressed_name;
msec = bfd_get_section_by_name (abfd, look);
- if (msec != NULL)
+ if (msec != NULL && (msec->flags & SEC_HAS_CONTENTS) != 0)
return msec;
for (msec = abfd->sections; msec != NULL; msec = msec->next)
- if (startswith (msec->name, GNU_LINKONCE_INFO))
+ if ((msec->flags & SEC_HAS_CONTENTS) != 0
+ && startswith (msec->name, GNU_LINKONCE_INFO))
return msec;
return NULL;
@@ -4848,6 +4851,9 @@ find_debug_info (bfd *abfd, const struct dwarf_debug_section *debug_sections,
for (msec = after_sec->next; msec != NULL; msec = msec->next)
{
+ if ((msec->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
look = debug_sections[debug_info].uncompressed_name;
if (strcmp (msec->name, look) == 0)
return msec;

View File

@ -1,115 +0,0 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= <ahajkova@redhat.com>
Date: Sun, 1 Oct 2023 10:36:06 +0200
Subject: gdb-rhbz2233965-memory-leak.patch
;; Backport PR29925, Memory leak in find_abstract_instance
PR29925, Memory leak in find_abstract_instance
The testcase in the PR had a variable with both DW_AT_decl_file and
DW_AT_specification, where the DW_AT_specification also specified
DW_AT_decl_file. This leads to a memory leak as the file name is
malloced and duplicates are not expected.
I've also changed find_abstract_instance to not use a temp for "name",
because that can result in a change in behaviour from the usual last
of duplicate attributes wins.
PR 29925
* dwarf2.c (find_abstract_instance): Delete "name" variable.
Free *filename_ptr before assigning new file name.
(scan_unit_for_symbols): Similarly free func->file and
var->file before assigning.
diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c
--- a/bfd/dwarf2.c
+++ b/bfd/dwarf2.c
@@ -3441,7 +3441,6 @@ find_abstract_instance (struct comp_unit *unit,
struct abbrev_info *abbrev;
uint64_t die_ref = attr_ptr->u.val;
struct attribute attr;
- const char *name = NULL;
if (recur_count == 100)
{
@@ -3602,9 +3601,9 @@ find_abstract_instance (struct comp_unit *unit,
case DW_AT_name:
/* Prefer DW_AT_MIPS_linkage_name or DW_AT_linkage_name
over DW_AT_name. */
- if (name == NULL && is_str_form (&attr))
+ if (*pname == NULL && is_str_form (&attr))
{
- name = attr.u.str;
+ *pname = attr.u.str;
if (mangle_style (unit->lang) == 0)
*is_linkage = true;
}
@@ -3612,7 +3611,7 @@ find_abstract_instance (struct comp_unit *unit,
case DW_AT_specification:
if (is_int_form (&attr)
&& !find_abstract_instance (unit, &attr, recur_count + 1,
- &name, is_linkage,
+ pname, is_linkage,
filename_ptr, linenumber_ptr))
return false;
break;
@@ -3622,7 +3621,7 @@ find_abstract_instance (struct comp_unit *unit,
non-string forms into these attributes. */
if (is_str_form (&attr))
{
- name = attr.u.str;
+ *pname = attr.u.str;
*is_linkage = true;
}
break;
@@ -3630,8 +3629,11 @@ find_abstract_instance (struct comp_unit *unit,
if (!comp_unit_maybe_decode_line_info (unit))
return false;
if (is_int_form (&attr))
- *filename_ptr = concat_filename (unit->line_table,
- attr.u.val);
+ {
+ free (*filename_ptr);
+ *filename_ptr = concat_filename (unit->line_table,
+ attr.u.val);
+ }
break;
case DW_AT_decl_line:
if (is_int_form (&attr))
@@ -3643,7 +3645,6 @@ find_abstract_instance (struct comp_unit *unit,
}
}
}
- *pname = name;
return true;
}
@@ -4139,8 +4140,11 @@ scan_unit_for_symbols (struct comp_unit *unit)
case DW_AT_decl_file:
if (is_int_form (&attr))
- func->file = concat_filename (unit->line_table,
- attr.u.val);
+ {
+ free (func->file);
+ func->file = concat_filename (unit->line_table,
+ attr.u.val);
+ }
break;
case DW_AT_decl_line:
@@ -4182,8 +4186,11 @@ scan_unit_for_symbols (struct comp_unit *unit)
case DW_AT_decl_file:
if (is_int_form (&attr))
- var->file = concat_filename (unit->line_table,
- attr.u.val);
+ {
+ free (var->file);
+ var->file = concat_filename (unit->line_table,
+ attr.u.val);
+ }
break;
case DW_AT_decl_line:

View File

@ -0,0 +1,48 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= <ahajkova@redhat.com>
Date: Mon, 8 Jan 2024 13:24:05 +0100
Subject: gdb-rhbz2250652-avoid-PyOS_ReadlineTState.patch
gdb/python: avoid use of _PyOS_ReadlineTState
In python/py-gdb-readline.c we make use of _PyOS_ReadlineTState,
however, this variable is no longer public in Python 3.13, and so GDB
no longer builds.
We are making use of _PyOS_ReadlineTState in order to re-acquire the
Python Global Interpreter Lock (GIL). The _PyOS_ReadlineTState
variable is set in Python's outer readline code prior to calling the
user (GDB) supplied readline callback function, which for us is
gdbpy_readline_wrapper. The gdbpy_readline_wrapper function is called
without the GIL held.
Instead of using _PyOS_ReadlineTState, I propose that we switch to
calling PyGILState_Ensure() and PyGILState_Release(). These functions
will acquire the GIL based on the current thread. I think this should
be sufficient; I can't imagine why we'd be running
gdbpy_readline_wrapper on one thread on behalf of a different Python
thread.... that would be unexpected I think.
Approved-By: Tom Tromey <tom@tromey.com>
diff --git a/gdb/python/py-gdb-readline.c b/gdb/python/py-gdb-readline.c
--- a/gdb/python/py-gdb-readline.c
+++ b/gdb/python/py-gdb-readline.c
@@ -56,13 +56,11 @@ gdbpy_readline_wrapper (FILE *sys_stdin, FILE *sys_stdout,
if (except.reason == RETURN_QUIT)
return NULL;
- /* The thread state is nulled during gdbpy_readline_wrapper,
- with the original value saved in the following undocumented
- variable (see Python's Parser/myreadline.c and
- Modules/readline.c). */
- PyEval_RestoreThread (_PyOS_ReadlineTState);
+
+ /* This readline callback is called without the GIL held. */
+ gdbpy_gil gil;
+
gdbpy_convert_exception (except);
- PyEval_SaveThread ();
return NULL;
}

View File

@ -0,0 +1,81 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= <ahajkova@redhat.com>
Date: Mon, 8 Jan 2024 13:12:15 +0100
Subject: gdb-rhbz2250652-gdbpy_gil.patch
gdb: move gdbpy_gil into python-internal.h
Move gdbpy_gil class into python-internal.h, the next
commit wants to make use of this class from a file other
than python.c.
Approved-By: Tom Tromey <tom@tromey.com>
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -754,6 +754,30 @@ class gdbpy_allow_threads
PyThreadState *m_save;
};
+/* A helper class to save and restore the GIL, but without touching
+ the other globals that are handled by gdbpy_enter. */
+
+class gdbpy_gil
+{
+public:
+
+ gdbpy_gil ()
+ : m_state (PyGILState_Ensure ())
+ {
+ }
+
+ ~gdbpy_gil ()
+ {
+ PyGILState_Release (m_state);
+ }
+
+ DISABLE_COPY_AND_ASSIGN (gdbpy_gil);
+
+private:
+
+ PyGILState_STATE m_state;
+};
+
/* Use this after a TRY_EXCEPT to throw the appropriate Python
exception. */
#define GDB_PY_HANDLE_EXCEPTION(Exception) \
diff --git a/gdb/python/python.c b/gdb/python/python.c
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -257,30 +257,6 @@ gdbpy_enter::finalize ()
python_gdbarch = target_gdbarch ();
}
-/* A helper class to save and restore the GIL, but without touching
- the other globals that are handled by gdbpy_enter. */
-
-class gdbpy_gil
-{
-public:
-
- gdbpy_gil ()
- : m_state (PyGILState_Ensure ())
- {
- }
-
- ~gdbpy_gil ()
- {
- PyGILState_Release (m_state);
- }
-
- DISABLE_COPY_AND_ASSIGN (gdbpy_gil);
-
-private:
-
- PyGILState_STATE m_state;
-};
-
/* Set the quit flag. */
static void

View File

@ -0,0 +1,55 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Kevin Buettner <kevinb@redhat.com>
Date: Mon, 29 Jan 2024 14:51:22 -0700
Subject: gdb-rhbz2261580-intrusive_list-assertion-fix.patch
;; Backport upstream workaround for GCC 14 problem which cause assertion
;; failures in GDB.
[gdb/build] Workaround gcc PR113599
Since gcc commit d3f48f68227 ("c++: non-dependent .* operand folding
[PR112427]"), with gdb we run into PR gcc/113599 [1], a wrong-code bug, as
reported in PR build/31281.
Work around this by flipping inherit order:
...
-class thread_info : public refcounted_object,
- public intrusive_list_node<thread_info>
+class thread_info : public intrusive_list_node<thread_info>,
+ public refcounted_object
...
An argument could be made that this isn't necessary, because this occurred in
an unreleased gcc version.
However, I think it could be useful when bisecting gcc for other problems in
building gdb. Having this workaround means the bisect won't reintroduce the
problem. Furthermore, the workaround is harmless.
Tested on Fedora rawhide x86_64.
Approved-By: Tom Tromey <tom@tromey.com>
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31281
[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113599
diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h
--- a/gdb/gdbthread.h
+++ b/gdb/gdbthread.h
@@ -242,10 +242,11 @@ using private_thread_info_up = std::unique_ptr<private_thread_info>;
strong reference, and is thus not accounted for in the thread's
refcount.
- The intrusive_list_node base links threads in a per-inferior list. */
+ The intrusive_list_node base links threads in a per-inferior list.
+ We place it first in the inherit order to work around PR gcc/113599. */
-class thread_info : public refcounted_object,
- public intrusive_list_node<thread_info>
+class thread_info : public intrusive_list_node<thread_info>,
+ public refcounted_object
{
public:
explicit thread_info (inferior *inf, ptid_t ptid);

View File

@ -1,45 +0,0 @@
From 1bbcd2144710c4b1daa9c404df0ebc80c3461747 Mon Sep 17 00:00:00 2001
From: Ilya Leoshkevich <iii@linux.ibm.com>
Date: Thu, 22 Jun 2023 01:03:04 +0200
Subject: [PATCH 11/12] gdb: support rseq auxvs
Linux kernel commit commit 317c8194e6ae ("rseq: Introduce feature size
and alignment ELF auxiliary vector entries") introduced two new auxvs:
AT_RSEQ_FEATURE_SIZE and AT_RSEQ_ALIGN. Support them in GDB. This
fixes auxv.exp on kernels >= v6.3.
---
gdb/auxv.c | 4 ++++
include/elf/common.h | 2 ++
2 files changed, 6 insertions(+)
diff --git a/gdb/auxv.c b/gdb/auxv.c
index 812b2807554..3ce5ccd3342 100644
--- a/gdb/auxv.c
+++ b/gdb/auxv.c
@@ -493,6 +493,10 @@ default_print_auxv_entry (struct gdbarch *gdbarch, struct ui_file *file,
AUXV_FORMAT_STR);
TAG (AT_RANDOM, _("Address of 16 random bytes"), AUXV_FORMAT_HEX);
TAG (AT_HWCAP2, _("Extension of AT_HWCAP"), AUXV_FORMAT_HEX);
+ TAG (AT_RSEQ_FEATURE_SIZE, _("rseq supported feature size"),
+ AUXV_FORMAT_HEX);
+ TAG (AT_RSEQ_ALIGN, _("rseq allocation alignment"),
+ AUXV_FORMAT_HEX);
TAG (AT_EXECFN, _("File name of executable"), AUXV_FORMAT_STR);
TAG (AT_SECURE, _("Boolean, was exec setuid-like?"), AUXV_FORMAT_DEC);
TAG (AT_SYSINFO, _("Special system info/entry points"), AUXV_FORMAT_HEX);
diff --git a/include/elf/common.h b/include/elf/common.h
index 16587f6fb06..a37b1f9a264 100644
--- a/include/elf/common.h
+++ b/include/elf/common.h
@@ -1353,6 +1353,8 @@
may differ from AT_PLATFORM. */
#define AT_RANDOM 25 /* Address of 16 random bytes. */
#define AT_HWCAP2 26 /* Extension of AT_HWCAP. */
+#define AT_RSEQ_FEATURE_SIZE 27 /* rseq supported feature size */
+#define AT_RSEQ_ALIGN 28 /* rseq allocation alignment */
#define AT_EXECFN 31 /* Filename of executable. */
/* Pointer to the global system page used for system calls and other
nice things. */
--
2.35.3

View File

@ -1,299 +0,0 @@
From 7f4601b0a51f400bd1b1bc0f7895254d467e3bb4 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Fri, 21 Jul 2023 08:25:25 +0200
Subject: [PATCH] [gdb/symtab] Add optimized out static var to cooked index
Consider the test-case:
...
$ cat main.c
int main (void) { return 0; }
$ cat static-optimized-out.c
static int aaa;
...
compiled like this:
...
$ gcc-12 static-optimized-out.c main.c -g -O2 -flto
...
There's a difference in behaviour depending on symtab expansion state:
...
$ gdb -q -batch a.out -ex "print aaa"
No symbol "aaa" in current context.
$ gdb -q -batch a.out -ex "maint expand-symtab" -ex "print aaa"
$1 = <optimized out>
...
The reason for the difference is that the optimized out variable aaa:
...
<1><104>: Abbrev Number: 2 (DW_TAG_variable)
<105> DW_AT_name : aaa
<109> DW_AT_decl_file : 1
<10a> DW_AT_decl_line : 18
<10b> DW_AT_decl_column : 12
<10c> DW_AT_type : <0x110>
...
is not added to the cooked index because of this clause in abbrev_table::read:
...
else if (!has_location && !has_specification_or_origin && !has_external
&& cur_abbrev->tag == DW_TAG_variable)
cur_abbrev->interesting = false;
...
Fix this inconsistency by making sure that the optimized out variable is added
to the cooked index.
Regression tested on x86_64-linux.
Add two test-cases, a C test-case gdb.opt/static-optimized-out.exp and a dwarf
assembly test-case gdb.dwarf2/static-optimized-out.exp.
Tested gdb.opt/static-optimized-out.exp with gcc-8 to gcc-12, for which we now
consistently get:
...
(gdb) print aaa^M
$1 = <optimized out>^M
...
and with gcc 7.5.0 and clang 13.0.1, for which we still consistently get:
...
(gdb) print aaa^M
No symbol "aaa" in current context.^M
...
due to missing debug info for the variable.
PR symtab/30656
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30656
Approved-By: Tom Tromey <tom@tromey.com>
---
gdb/dwarf2/abbrev.c | 9 ---
.../gdb.dwarf2/static-optimized-out.exp | 69 +++++++++++++++++++
gdb/testsuite/gdb.opt/main.c | 22 ++++++
gdb/testsuite/gdb.opt/static-optimized-out.c | 18 +++++
.../gdb.opt/static-optimized-out.exp | 49 +++++++++++++
5 files changed, 158 insertions(+), 9 deletions(-)
create mode 100644 gdb/testsuite/gdb.dwarf2/static-optimized-out.exp
create mode 100644 gdb/testsuite/gdb.opt/main.c
create mode 100644 gdb/testsuite/gdb.opt/static-optimized-out.c
create mode 100644 gdb/testsuite/gdb.opt/static-optimized-out.exp
diff --git a/gdb/dwarf2/abbrev.c b/gdb/dwarf2/abbrev.c
index 1ebf8f6eed5..3a429fd41b1 100644
--- a/gdb/dwarf2/abbrev.c
+++ b/gdb/dwarf2/abbrev.c
@@ -162,7 +162,6 @@ abbrev_table::read (struct dwarf2_section_info *section,
bool has_specification_or_origin = false;
bool has_name = false;
bool has_linkage_name = false;
- bool has_location = false;
bool has_external = false;
/* Now read in declarations. */
@@ -217,11 +216,6 @@ abbrev_table::read (struct dwarf2_section_info *section,
has_linkage_name = true;
break;
- case DW_AT_const_value:
- case DW_AT_location:
- has_location = true;
- break;
-
case DW_AT_sibling:
if (is_csize && cur_attr.form == DW_FORM_ref4)
sibling_offset = size;
@@ -296,9 +290,6 @@ abbrev_table::read (struct dwarf2_section_info *section,
cur_abbrev->interesting = false;
else if (!tag_interesting_for_index (cur_abbrev->tag))
cur_abbrev->interesting = false;
- else if (!has_location && !has_specification_or_origin && !has_external
- && cur_abbrev->tag == DW_TAG_variable)
- cur_abbrev->interesting = false;
else
cur_abbrev->interesting = true;
diff --git a/gdb/testsuite/gdb.dwarf2/static-optimized-out.exp b/gdb/testsuite/gdb.dwarf2/static-optimized-out.exp
new file mode 100644
index 00000000000..1547a8acbc0
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/static-optimized-out.exp
@@ -0,0 +1,69 @@
+# Copyright 2023 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 an optimized out static variable is printed the same independent
+# of state of symtab expansion. See also gdb.opt/static-optimized-out.exp.
+
+load_lib dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+if { ![dwarf2_support] } {
+ return 0
+}
+
+standard_testfile main.c -dw.S
+
+# Make DWARF for the test.
+set asm_file [standard_output_file $srcfile2]
+Dwarf::assemble $asm_file {
+ cu {} {
+ compile_unit {
+ {
+ language @DW_LANG_C
+ }
+ } {
+ declare_labels integer_label
+
+ integer_label: DW_TAG_base_type {
+ {DW_AT_byte_size 4 DW_FORM_sdata}
+ {DW_AT_encoding @DW_ATE_signed}
+ {DW_AT_name integer}
+ }
+
+ DW_TAG_variable {
+ {name var}
+ {type :$integer_label}
+ }
+ }
+ }
+}
+
+if { [prepare_for_testing "failed to prepare" ${testfile} \
+ [list $srcfile $asm_file] {nodebug}] } {
+ return -1
+}
+
+gdb_test "print var" " = <optimized out>"
+
+# Expand all symbol tables.
+gdb_test_no_output "maint expand-symtabs"
+
+# Make sure we do an actual lookup rather than just returning the same as
+# before.
+gdb_test_no_output "maint flush symbol-cache"
+
+with_test_prefix "after expand-symtabs" {
+ gdb_test "print var" " = <optimized out>"
+}
diff --git a/gdb/testsuite/gdb.opt/main.c b/gdb/testsuite/gdb.opt/main.c
new file mode 100644
index 00000000000..c6beff77dbe
--- /dev/null
+++ b/gdb/testsuite/gdb.opt/main.c
@@ -0,0 +1,22 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2023 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/>. */
+
+int
+main (void)
+{
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.opt/static-optimized-out.c b/gdb/testsuite/gdb.opt/static-optimized-out.c
new file mode 100644
index 00000000000..44287fbd6d2
--- /dev/null
+++ b/gdb/testsuite/gdb.opt/static-optimized-out.c
@@ -0,0 +1,18 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2023 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/>. */
+
+static int aaa;
diff --git a/gdb/testsuite/gdb.opt/static-optimized-out.exp b/gdb/testsuite/gdb.opt/static-optimized-out.exp
new file mode 100644
index 00000000000..bd673b6503e
--- /dev/null
+++ b/gdb/testsuite/gdb.opt/static-optimized-out.exp
@@ -0,0 +1,49 @@
+# Copyright 2023 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 an optimized out static variable is printed the same independent
+# of state of symtab expansion. See also gdb.dwarf2/static-optimized-out.exp.
+
+standard_testfile .c main.c
+
+set opts {}
+lappend opts debug
+lappend opts "optimize=-O2 -flto"
+
+if { [prepare_for_testing "failed to prepare" $testfile \
+ [list $srcfile $srcfile2] $opts] } {
+ return -1
+}
+
+set val ""
+gdb_test_multiple "print aaa" "" {
+ -re -wrap "\r\n(?:\\$$decimal = )?(\[^\r\n\]*)" {
+ set val $expect_out(1,string)
+ }
+}
+
+if { $val == "" } {
+ return
+}
+
+# Expand all symbol tables.
+gdb_test_no_output "maint expand-symtab"
+
+# Make sure we do an actual lookup rather than just returning the same as
+# before.
+gdb_test_no_output "maint flush symbol-cache"
+
+# Now check that we get the same result in both cases.
+gdb_test "print aaa" [string_to_regexp $val] "consistency"
base-commit: 800c393f89a94f49b01dff99f693cb13c5e28116
--
2.35.3

View File

@ -1,81 +0,0 @@
From 04d0d6ebdc6d08f5a7ec0d4c89eb1835deef54dc Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Sun, 13 Aug 2023 14:08:06 +0200
Subject: [PATCH] [gdb/symtab] Don't deduplicate variables in gdb-index
When running test-case gdb.python/py-symbol.exp with target board
cc-with-gdb-index, we run into:
...
(gdb) python print (len (gdb.lookup_static_symbols ('rr')))^M
1^M
(gdb) FAIL: gdb.python/py-symbol.exp: print (len (gdb.lookup_static_symbols ('rr')))
...
[ Note that the test-case contains rr in both py-symtab.c:
...
static int __attribute__ ((used)) rr = 42; /* line of rr */
...
and py-symtab-2.c:
...
static int __attribute__ ((used)) rr = 99; /* line of other rr */
... ]
This passes with gdb-12-branch, and fails with gdb-13-branch.
AFAIU the current code in symtab_index_entry::minimize makes the assumption
that it's fine to store only one copy of rr in the gdb-index, because
"print rr" will only ever print one, and always the same.
But that fails to recognize that gdb supports gdb.lookup_static_symbols, which
returns a list of variables rather than the first one.
In other words, the current approach breaks feature parity between cooked
index and gdb-index.
Note btw that also debug-names has both instances:
...
[ 5] #00597969 rr:
<4> DW_TAG_variable DW_IDX_compile_unit=3 DW_IDX_GNU_internal=1
<4> DW_TAG_variable DW_IDX_compile_unit=4 DW_IDX_GNU_internal=1
...
Fix this in symtab_index_entry::minimize, by not deduplicating variables.
Tested on x86_64-linux, with target boards unix and cc-with-gdb-index.
Reviewed-by: Kevin Buettner <kevinb@redhat.com>
PR symtab/30720
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30720
---
gdb/dwarf2/index-write.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c
index d10583568c0..ea67f73ac3c 100644
--- a/gdb/dwarf2/index-write.c
+++ b/gdb/dwarf2/index-write.c
@@ -294,7 +294,7 @@ symtab_index_entry::minimize ()
auto from = std::unique (cu_indices.begin (), cu_indices.end ());
cu_indices.erase (from, cu_indices.end ());
- /* We don't want to enter a variable or type more than once, so
+ /* We don't want to enter a type more than once, so
remove any such duplicates from the list as well. When doing
this, we want to keep the entry from the first CU -- but this is
implicit due to the sort. This choice is done because it's
@@ -304,8 +304,7 @@ symtab_index_entry::minimize ()
[&] (offset_type val)
{
gdb_index_symbol_kind kind = GDB_INDEX_SYMBOL_KIND_VALUE (val);
- if (kind != GDB_INDEX_SYMBOL_KIND_TYPE
- && kind != GDB_INDEX_SYMBOL_KIND_VARIABLE)
+ if (kind != GDB_INDEX_SYMBOL_KIND_TYPE)
return false;
val &= ~GDB_INDEX_CU_MASK;
base-commit: 2521ac7ed0c495b9e804c4356939b9be7166853c
--
2.35.3

View File

@ -1,7 +1,7 @@
From 6d472b241c96f181f88867860e92f1dfe7364903 Mon Sep 17 00:00:00 2001
From 0218e033b415df76be0a14871447bbd94dce62a3 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Sat, 16 Sep 2023 04:07:22 +0200
Subject: [PATCH 08/11] [gdb/symtab] Don't defer backward refs, inter-cu
Subject: [PATCH 10/13] [gdb/symtab] Don't defer backward refs, inter-cu
intra-shard case
In patch "[gdb/symtab] Resolve deferred entries, inter-shard case" we've
@ -16,10 +16,10 @@ Tested on x86_64-linux.
1 file changed, 28 insertions(+), 1 deletion(-)
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 0ab3e1a1500..d2d50b5c9cc 100644
index a97f738a54e..e7904532434 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -6709,6 +6709,12 @@ class cooked_index_storage
@@ -4709,6 +4709,12 @@ class cooked_index_storage
m_index->set_parent_valid (start, end);
}
@ -32,7 +32,7 @@ index 0ab3e1a1500..d2d50b5c9cc 100644
private:
/* Hash function for a cutu_reader. */
@@ -6857,6 +6863,12 @@ class cooked_indexer
@@ -4857,6 +4863,12 @@ class cooked_indexer
{
m_index_storage->set_parent_valid (start, end);
}
@ -45,7 +45,7 @@ index 0ab3e1a1500..d2d50b5c9cc 100644
};
/* Subroutine of dwarf2_build_psymtabs_hard to simplify it.
@@ -18387,7 +18399,22 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data *scanning_per_cu,
@@ -16482,7 +16494,22 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data *scanning_per_cu,
else
{
/* Inter-CU case. */

View File

@ -1,7 +1,7 @@
From dac6c3b27a77589078add7e4e4586515ac85610d Mon Sep 17 00:00:00 2001
From 8a444a93d4bd78355fc4e6ecb1935cc2b0a6a997 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Fri, 15 Sep 2023 08:38:00 +0200
Subject: [PATCH 04/11] [gdb/symtab] Factor out m_deferred_entries usage
Subject: [PATCH 04/13] [gdb/symtab] Factor out m_deferred_entries usage
Factor out usage of cooked_indexer::m_deferred_entries in new member
functions defer_entry, handle_deferred_entries and resolve_deferred_entry.
@ -12,10 +12,10 @@ Tested on x86_64-linux.
1 file changed, 28 insertions(+), 7 deletions(-)
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 1092cb1dca9..ff5be8e7dc5 100644
index d48f3010063..afdf9e870a8 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -6822,6 +6822,32 @@ class cooked_indexer
@@ -4822,6 +4822,32 @@ class cooked_indexer
we'll know the containing context of all the DIEs that we might
have scanned. This vector stores these deferred entries. */
std::vector<deferred_entry> m_deferred_entries;
@ -48,7 +48,7 @@ index 1092cb1dca9..ff5be8e7dc5 100644
};
/* Subroutine of dwarf2_build_psymtabs_hard to simplify it.
@@ -18519,7 +18545,7 @@ cooked_indexer::index_dies (cutu_reader *reader,
@@ -16611,7 +16637,7 @@ cooked_indexer::index_dies (cutu_reader *reader,
if (name != nullptr)
{
if (defer != 0)
@ -57,7 +57,7 @@ index 1092cb1dca9..ff5be8e7dc5 100644
this_die, name, defer, abbrev->tag, flags
});
else
@@ -18624,12 +18650,7 @@ cooked_indexer::make_index (cutu_reader *reader)
@@ -16716,12 +16742,7 @@ cooked_indexer::make_index (cutu_reader *reader)
return;
index_dies (reader, reader->info_ptr, nullptr, false);

View File

@ -1,7 +1,7 @@
From 6ac3acf29782a059258fdfe21bd55f1716fc46ed Mon Sep 17 00:00:00 2001
From b2f260d117dc11b8e90d4e9bf7f4b2cbd63d1d49 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Tue, 22 Aug 2023 13:17:47 +0200
Subject: [PATCH 02/11] [gdb/symtab] Factor out m_die_range_map usage
Subject: [PATCH 02/13] [gdb/symtab] Factor out m_die_range_map usage
Factor out usage of cooked_indexer::m_die_range_map into new class parent_map
with member functions find_parent and set_parent, and static member function
@ -9,15 +9,15 @@ form_addr.
Tested on x86_64-linux.
---
gdb/dwarf2/cooked-index.h | 32 ++++++++++++++++++++++++++
gdb/dwarf2/read.c | 48 +++++++++++++++++++++------------------
2 files changed, 58 insertions(+), 22 deletions(-)
gdb/dwarf2/cooked-index.h | 32 +++++++++++++++++++++++++++
gdb/dwarf2/read.c | 46 ++++++++++++++++++++-------------------
2 files changed, 56 insertions(+), 22 deletions(-)
diff --git a/gdb/dwarf2/cooked-index.h b/gdb/dwarf2/cooked-index.h
index 2ef1f4b27e9..1c967bdbf86 100644
index 5aacb321c91..979541fbf60 100644
--- a/gdb/dwarf2/cooked-index.h
+++ b/gdb/dwarf2/cooked-index.h
@@ -233,6 +233,38 @@ struct cooked_index_entry : public allocate_on_obstack
@@ -239,6 +239,38 @@ struct cooked_index_entry : public allocate_on_obstack
bool for_name) const;
};
@ -53,14 +53,14 @@ index 2ef1f4b27e9..1c967bdbf86 100644
+ addrmap_mutable m_parent_map;
+};
+
class cooked_index_vector;
class cooked_index;
/* An index of interesting DIEs. This is "cooked", in contrast to a
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 00471d20d41..1092cb1dca9 100644
index 466d3e59878..d48f3010063 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -6722,16 +6722,6 @@ class cooked_indexer
@@ -4722,16 +4722,6 @@ class cooked_indexer
private:
@ -77,7 +77,7 @@ index 00471d20d41..1092cb1dca9 100644
/* A helper function to scan the PC bounds of READER and record them
in the storage's addrmap. */
void check_bounds (cutu_reader *reader);
@@ -6799,7 +6789,20 @@ class cooked_indexer
@@ -4799,7 +4789,20 @@ class cooked_indexer
/* An addrmap that maps from section offsets (see the form_addr
method) to newly-created entries. See m_deferred_entries to
understand this. */
@ -99,7 +99,7 @@ index 00471d20d41..1092cb1dca9 100644
/* A single deferred entry. */
struct deferred_entry
@@ -18317,15 +18320,13 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data *scanning_per_cu,
@@ -16412,15 +16415,13 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data *scanning_per_cu,
if (*parent_entry == nullptr)
{
@ -118,15 +118,13 @@ index 00471d20d41..1092cb1dca9 100644
}
unsigned int bytes_read;
@@ -18444,11 +18445,15 @@ cooked_indexer::recurse (cutu_reader *reader,
if (parent_entry != nullptr)
@@ -16538,11 +16539,13 @@ cooked_indexer::recurse (cutu_reader *reader,
{
- CORE_ADDR start = form_addr (parent_entry->die_offset,
/* Both start and end are inclusive, so use both "+ 1" and "- 1" to
limit the range to the children of parent_entry. */
- CORE_ADDR start = form_addr (parent_entry->die_offset + 1,
- reader->cu->per_cu->is_dwz);
- CORE_ADDR end = form_addr (sect_offset (info_ptr - 1 - reader->buffer),
+ /* Both start and end are inclusive, so use both "+ 1" and "- 1" to
+ limit the range to the children of parent_entry. */
+ CORE_ADDR start
+ = parent_map::form_addr (parent_entry->die_offset + 1,
+ reader->cu->per_cu->is_dwz);
@ -138,7 +136,7 @@ index 00471d20d41..1092cb1dca9 100644
}
return info_ptr;
@@ -18621,8 +18626,7 @@ cooked_indexer::make_index (cutu_reader *reader)
@@ -16715,8 +16718,7 @@ cooked_indexer::make_index (cutu_reader *reader)
for (const auto &entry : m_deferred_entries)
{

View File

@ -1,202 +0,0 @@
From e2f41776aa9ca2f625bbc50e9bb498e2a95dba25 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Sat, 5 Aug 2023 17:57:13 +0200
Subject: [PATCH] [gdb/symtab] Find main language without symtab expansion
When loading an executable using "file a.out", the language is set according
to a.out, which can involve looking up the language of symbol "main", which
will cause the symtab expansion for the containing CU.
Expansion of lto debug info can be slow, so in commit d3214198119 ("[gdb] Use
partial symbol table to find language for main") a feature was added to avoid
the symtab expansion.
This feature stopped working after commit 7f4307436fd ("Fix "start" for D,
Rust, etc").
[ The commit addresses problems related to command start, which requires finding
the main function:
- for language D, "main" was found instead of "D main", and
- for Rust, the correct function was found, but attributed the wrong name
(not fully qualified). ]
Reimplement the feature by adding
cooked_index_functions::lookup_global_symbol_language.
Tested on x86_64-linux.
PR symtab/30661
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30661
---
gdb/dwarf2/read.c | 41 +++++++++++++++++++++++++++++++
gdb/testsuite/gdb.base/main-c.exp | 33 +++++++++++++++++++++++++
gdb/testsuite/gdb.cp/main-cp.exp | 33 +++++++++++++++++++++++++
gdb/testsuite/gdb.cp/main.cc | 22 +++++++++++++++++
4 files changed, 129 insertions(+)
create mode 100644 gdb/testsuite/gdb.base/main-c.exp
create mode 100644 gdb/testsuite/gdb.cp/main-cp.exp
create mode 100644 gdb/testsuite/gdb.cp/main.cc
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 04bc0e1cbbd..8aa7f8c31e5 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -18621,6 +18621,47 @@ struct cooked_index_functions : public dwarf2_base_index_functions
if (dwarf2_has_info (objfile, nullptr))
dwarf2_build_psymtabs (objfile);
}
+
+ enum language lookup_global_symbol_language (struct objfile *objfile,
+ const char *name,
+ domain_enum domain,
+ bool *symbol_found_p) override
+ {
+ *symbol_found_p = false;
+
+ if (!(domain == VAR_DOMAIN && streq (name, "main")))
+ return language_unknown;
+
+ dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
+ struct dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
+ if (per_bfd->index_table == nullptr)
+ return language_unknown;
+
+ /* Expansion of large CUs can be slow. By returning the language of main
+ here for C and C++, we avoid CU expansion during set_initial_language.
+ But by doing a symbol lookup in the cooked index, we are forced to wait
+ for finalization to complete. See PR symtab/30174 for ideas how to
+ bypass that as well. */
+ cooked_index_vector *table
+ = (gdb::checked_static_cast<cooked_index_vector *>
+ (per_objfile->per_bfd->index_table.get ()));
+ table->wait ();
+
+ for (const cooked_index_entry *entry : table->find (name, false))
+ {
+ if (entry->tag != DW_TAG_subprogram)
+ continue;
+
+ enum language lang = entry->per_cu->lang ();
+ if (!(lang == language_c || lang == language_cplus))
+ continue;
+
+ *symbol_found_p = true;
+ return lang;
+ }
+
+ return language_unknown;
+ }
};
dwarf2_per_cu_data *
diff --git a/gdb/testsuite/gdb.base/main-c.exp b/gdb/testsuite/gdb.base/main-c.exp
new file mode 100644
index 00000000000..bcbd0fca7e4
--- /dev/null
+++ b/gdb/testsuite/gdb.base/main-c.exp
@@ -0,0 +1,33 @@
+# Copyright 2023 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 finding main to set the current language doesn't cause any symtab
+# to be expanded.
+
+standard_testfile main.c
+
+if { [readnow] } {
+ return -1
+}
+
+if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } {
+ return -1
+}
+
+if { ![string eq [have_index $binfile] ""] } {
+ return -1
+}
+
+gdb_test_no_output "maint info symtabs"
diff --git a/gdb/testsuite/gdb.cp/main-cp.exp b/gdb/testsuite/gdb.cp/main-cp.exp
new file mode 100644
index 00000000000..86d626bdbaf
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/main-cp.exp
@@ -0,0 +1,33 @@
+# Copyright 2023 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 finding main to set the current language doesn't cause any symtab
+# to be expanded.
+
+standard_testfile main.cc
+
+if { [readnow] } {
+ return -1
+}
+
+if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } {
+ return -1
+}
+
+if { ![string eq [have_index $binfile] ""] } {
+ return -1
+}
+
+gdb_test_no_output "maint info symtabs"
diff --git a/gdb/testsuite/gdb.cp/main.cc b/gdb/testsuite/gdb.cp/main.cc
new file mode 100644
index 00000000000..c6beff77dbe
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/main.cc
@@ -0,0 +1,22 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2023 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/>. */
+
+int
+main (void)
+{
+ return 0;
+}
base-commit: ebceffa1196651683a7a6d31abb4b3b5adc6c168
--
2.35.3

View File

@ -1,7 +1,7 @@
From 19185006cfe0901da907da4f09fbc197aba976a2 Mon Sep 17 00:00:00 2001
From c79ecacd3f75cfb0ec1a3afc49ca3f30b1759009 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Fri, 11 Aug 2023 01:36:50 +0200
Subject: [PATCH 11/11] [gdb/symtab] Fix DW_TAG_inlined_subroutine entries in
Subject: [PATCH 13/13] [gdb/symtab] Fix DW_TAG_inlined_subroutine entries in
the cooked index
We get incorrect qualified names in the cooked index for
@ -19,10 +19,10 @@ Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30728
1 file changed, 32 insertions(+), 35 deletions(-)
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index e2d4fe8cde6..418acaabc60 100644
index 93708ef11b9..a4f982962ae 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -18369,52 +18369,49 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data *scanning_per_cu,
@@ -16464,52 +16464,49 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data *scanning_per_cu,
const gdb_byte *new_info_ptr = (new_reader->buffer
+ to_underlying (origin_offset));

View File

@ -1,84 +0,0 @@
From e5972def532f3ed248dfbd2f220f28dc367f4ca1 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Fri, 24 Mar 2023 15:45:56 +0100
Subject: [PATCH 07/12] [gdb/symtab] Fix line number of static const class
member
Since commit 6d263fe46e0 ("Avoid bad breakpoints with --gc-sections"), there
was a silent regression on openSUSE Leap 15.4 for test-case
gdb.cp/m-static.exp, from:
...
(gdb) info variable everywhere^M
All variables matching regular expression "everywhere":^M
^M
File /home/vries/tmp.local-remote-host-native/m-static.h:^M
8: const int gnu_obj_4::everywhere;^M
(gdb)
...
to:
...
(gdb) info variable everywhere^M
All variables matching regular expression "everywhere":^M
^M
File /data/vries/gdb/src/gdb/testsuite/gdb.cp/m-static.h:^M
8: const int gnu_obj_4::everywhere;^M
^M
File /data/vries/gdb/src/gdb/testsuite/gdb.cp/m-static1.cc:^M
8: const int gnu_obj_4::everywhere;^M
(gdb)
...
Another regression was found due to that commit, and it was fixed in commit
99d679e7b30 ("[gdb/symtab] Fix "file index out of range" complaint") by
limiting the scope of the fix in the original commit.
Fix this regression by yet further limiting the scope of that fix, making sure
that this bit in dwarf_decode_lines is executed again for m-static1.cc:
...
/* Make sure a symtab is created for every file, even files
which contain only variables (i.e. no code with associated
line numbers). */
...
Tested on x86_64-linux.
PR symtab/30265
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30265
---
gdb/dwarf2/read.c | 3 +--
gdb/testsuite/gdb.cp/m-static.exp | 4 +++-
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index f39eba7a008..04bc0e1cbbd 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -9633,8 +9633,7 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
then there won't be any interesting code in the CU, but a check later on
(in lnp_state_machine::check_line_address) will fail to properly exclude
an entry that was removed via --gc-sections. */
- if (have_code)
- dwarf_decode_lines (cu->line_header, cu, lowpc, decode_mapping);
+ dwarf_decode_lines (cu->line_header, cu, lowpc, decode_mapping && have_code);
}
/* Process DW_TAG_compile_unit or DW_TAG_partial_unit. */
diff --git a/gdb/testsuite/gdb.cp/m-static.exp b/gdb/testsuite/gdb.cp/m-static.exp
index a67b4cd3736..049e88299da 100644
--- a/gdb/testsuite/gdb.cp/m-static.exp
+++ b/gdb/testsuite/gdb.cp/m-static.exp
@@ -183,8 +183,10 @@ gdb_test "print test4.somewhere" "\\$\[0-9\].* = 3.14\[0-9\]*" "static const flo
if { $non_dwarf } { setup_xfail *-*-* }
gdb_test "info variable everywhere" \
[multi_line \
+ {All variables matching regular expression "everywhere":} \
+ "" \
"File (.*/)?m-static\[.\]h:" \
- "$decimal:\tconst int gnu_obj_4::everywhere;.*"]
+ "$decimal:\tconst int gnu_obj_4::everywhere;"]
# Perhaps at some point test4 should also include a test for a static
# const int that was initialized in the header file. But I'm not sure
--
2.35.3

View File

@ -1,66 +0,0 @@
From 1362bc937bd54dbd22dd7b3c7ae9d8ab6ca7bbfc Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Wed, 6 Sep 2023 11:00:01 +0200
Subject: [PATCH 10/12] [gdb/symtab] Fix too many symbols in
gdbpy_lookup_static_symbols
When running test-case gdb.python/py-symbol.exp with target board
cc-with-dwz-m, we run into:
...
(gdb) python print (len (gdb.lookup_static_symbols ('rr')))^M
4^M
(gdb) FAIL: gdb.python/py-symbol.exp: \
print (len (gdb.lookup_static_symbols ('rr')))
...
while with target board unix we have instead:
...
(gdb) python print (len (gdb.lookup_static_symbols ('rr')))^M
2^M
(gdb) PASS: gdb.python/py-symbol.exp: \
print (len (gdb.lookup_static_symbols ('rr')))
...
The problem is that the loop in gdbpy_lookup_static_symbols loops over compunits
representing both CUs and PUs:
...
for (compunit_symtab *cust : objfile->compunits ())
...
When doing a lookup on a PU, the user link is followed until we end up at a CU,
and the lookup is done in that CU.
In other words, when doing a lookup in the loop for a PU we duplicate the
lookup for a CU that is already handled by the loop.
Fix this by skipping PUs in the loop in gdb.lookup_static_symbols.
Tested on x86_64-linux.
PR symtab/25261
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=25261
---
gdb/python/py-symbol.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/gdb/python/py-symbol.c b/gdb/python/py-symbol.c
index b8777966c47..ed4250bc2c7 100644
--- a/gdb/python/py-symbol.c
+++ b/gdb/python/py-symbol.c
@@ -582,9 +582,12 @@ gdbpy_lookup_static_symbols (PyObject *self, PyObject *args, PyObject *kw)
{
for (compunit_symtab *cust : objfile->compunits ())
{
- const struct blockvector *bv;
+ /* Skip included compunits to prevent including compunits from
+ being searched twice. */
+ if (cust->user != nullptr)
+ continue;
- bv = cust->blockvector ();
+ const struct blockvector *bv = cust->blockvector ();
const struct block *block = bv->static_block ();
if (block != nullptr)
--
2.35.3

View File

@ -1,7 +1,7 @@
From 933f8ee225d4ccd3db9b81312dba76ae5a50b4ea Mon Sep 17 00:00:00 2001
From bc970668f83cf142c4955d1cbeaa24e8bcc4b238 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Fri, 25 Aug 2023 09:30:54 +0200
Subject: [PATCH 03/11] [gdb/symtab] Handle nullptr parent in
Subject: [PATCH 03/13] [gdb/symtab] Handle nullptr parent in
parent_map::set_parent
Set_parent uses m_die_range_map.set_empty, which doesn't allow
@ -18,10 +18,10 @@ Tested on x86_64-linux.
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/gdb/dwarf2/cooked-index.h b/gdb/dwarf2/cooked-index.h
index 1c967bdbf86..f4abc7a974e 100644
index 979541fbf60..79fbfe88c03 100644
--- a/gdb/dwarf2/cooked-index.h
+++ b/gdb/dwarf2/cooked-index.h
@@ -257,7 +257,9 @@ class parent_map
@@ -263,7 +263,9 @@ class parent_map
void set_parent (CORE_ADDR start, CORE_ADDR end,
const cooked_index_entry *parent_entry)
{

View File

@ -1,59 +0,0 @@
From c67e982325c5b2249b0e29d07a9dc1985614e898 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Wed, 6 Sep 2023 10:14:50 +0200
Subject: [PATCH 08/12] [gdb/symtab] Handle PU in iterate_over_some_symtabs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When running test-case gdb.base/setshow.exp with target board cc-with-dwz I
run into:
...
(gdb) info line 1^M
Line 1 of "setshow.c" is at address 0x400527 <main> but contains no code.^M
Line 1 of "setshow.c" is at address 0x400527 <main> but contains no code.^M
(gdb) FAIL: gdb.base/setshow.exp: test_setshow_annotate: annotation_level 1
...
while the expected output is:
...
Line 1 of "setshow.c" is at address 0x400527 <main> but contains no code.
<EFBFBD><EFBFBD>setshow.c:1:0:beg:0x400527
...
The second line of the expected output is missing due to the first line of the
expected output being repeated, so the problem is that the "Line 1" line is
printed twice.
This happens because the PU imported by the CU reuses the filetab of the CU,
and both the CU and PU are visited by iterate_over_some_symtabs.
Fix this by skipping PUs in iterate_over_some_symtabs.
Tested on x86_64-linux, target boards unix, cc-with-dwz and cc-with-dwz-m.
Approved-By: Tom Tromey <tom@tromey.com>
PR symtab/30797
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30797
---
gdb/symtab.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/gdb/symtab.c b/gdb/symtab.c
index a662d7d1869..fe7cc679b6b 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -550,6 +550,10 @@ iterate_over_some_symtabs (const char *name,
for (cust = first; cust != NULL && cust != after_last; cust = cust->next)
{
+ /* Skip included compunits. */
+ if (cust->user != nullptr)
+ continue;
+
for (symtab *s : cust->filetabs ())
{
if (compare_filenames_for_search (s->filename, name))
--
2.35.3

View File

@ -1,159 +0,0 @@
From 8f53ac47d3f9c3800c8429d9187961ba81707d8b Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Wed, 16 Aug 2023 23:43:25 +0200
Subject: [PATCH 1/2] [gdb/symtab] Handle self-reference DIE
While working on a dwarf assembly test-case I accidentally created the
following pathological dwarf:
...
<1><be>: Abbrev Number: 3 (DW_TAG_class_type)
<bf> DW_AT_name : c1
<c2> DW_AT_specification: <0xbe>
...
and noticed gdb segfaulting during cooked index creating due to running out of
stack. This is a regression from gdb-12, where gdb just hung.
Fix this by inhibiting the scan_attributes self-recursion for self-references.
The same test-case with -readnow makes gdb hang, so also fix this in
dwarf2_attr and follow_die_ref.
Note that this doesn't fix the same problems for the more complicated case of:
...
<1><be>: Abbrev Number: 3 (DW_TAG_class_type)
<bf> DW_AT_name : c1
<c2> DW_AT_specification: <0xc6>
<1><c6>: Abbrev Number: 4 (DW_TAG_class_type)
<c7> DW_AT_name : c2
<ca> DW_AT_specification: <0xbe>
...
but the approach for deciding whether to fix pathological dwarf cases is as
per PR27981 comment 3:
...
yes if it is cheap/obvious, and no if it is something complicated or expensive.
...
and at this point I'm not sure whether fixing this will fall in the first
category.
Tested on x86_64-linux.
Approved-By: Tom Tromey <tom@tromey.com>
---
gdb/dwarf2/read.c | 22 +++++++++--
gdb/testsuite/gdb.dwarf2/self-spec.exp | 54 ++++++++++++++++++++++++++
2 files changed, 73 insertions(+), 3 deletions(-)
create mode 100644 gdb/testsuite/gdb.dwarf2/self-spec.exp
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 61f4bd75013..1be5f381432 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -18289,9 +18289,15 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data *scanning_per_cu,
new_info_ptr,
&bytes_read);
new_info_ptr += bytes_read;
- scan_attributes (scanning_per_cu, new_reader, new_info_ptr, new_info_ptr,
- new_abbrev, name, linkage_name, flags, nullptr,
- parent_entry, maybe_defer, true);
+
+ if (new_reader->cu == reader->cu && new_info_ptr == watermark_ptr)
+ {
+ /* Self-reference, we're done. */
+ }
+ else
+ scan_attributes (scanning_per_cu, new_reader, new_info_ptr,
+ new_info_ptr, new_abbrev, name, linkage_name,
+ flags, nullptr, parent_entry, maybe_defer, true);
}
}
@@ -19783,7 +19789,11 @@ dwarf2_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *cu)
if (!spec)
break;
+ struct die_info *prev_die = die;
die = follow_die_ref (die, spec, &cu);
+ if (die == prev_die)
+ /* Self-reference, we're done. */
+ break;
}
return NULL;
@@ -22521,6 +22531,12 @@ follow_die_ref (struct die_info *src_die, const struct attribute *attr,
struct dwarf2_cu *cu = *ref_cu;
struct die_info *die;
+ if (attr->form != DW_FORM_GNU_ref_alt && src_die->sect_off == sect_off)
+ {
+ /* Self-reference, we're done. */
+ return src_die;
+ }
+
die = follow_die_offset (sect_off,
(attr->form == DW_FORM_GNU_ref_alt
|| cu->per_cu->is_dwz),
diff --git a/gdb/testsuite/gdb.dwarf2/self-spec.exp b/gdb/testsuite/gdb.dwarf2/self-spec.exp
new file mode 100644
index 00000000000..77e92549fd1
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/self-spec.exp
@@ -0,0 +1,54 @@
+# Copyright 2023 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 gdb doesn't hang or segfault on reading a DIE with a
+# specification reference to itself.
+
+load_lib dwarf.exp
+
+if {![dwarf2_support]} {
+ return 0
+}
+
+standard_testfile main.c .S
+
+# Create the DWARF.
+set asm_file [standard_output_file $srcfile2]
+Dwarf::assemble $asm_file {
+ cu {} {
+ compile_unit {{language @DW_LANG_C_plus_plus}} {
+ declare_labels c1
+ c1: class_type {
+ {name c1}
+ {specification :$c1}
+ }
+ }
+ }
+}
+
+if [prepare_for_testing "failed to prepare" $testfile "${asm_file} ${srcfile}" {}] {
+ return -1
+}
+
+set index [have_index $binfile]
+if { ![string eq $index ""] } {
+ return 0
+}
+
+if { [readnow] } {
+ return 0
+}
+
+gdb_test "maint expand-symtabs"
base-commit: 6c9e159dbd1a35aafa134fcd52982174236a8dd9
--
2.35.3

View File

@ -1,92 +0,0 @@
From 800c393f89a94f49b01dff99f693cb13c5e28116 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Mon, 28 Aug 2023 16:27:58 +0200
Subject: [PATCH 2/2] [gdb/symtab] Handle self-reference in
inherit_abstract_dies
Building gdb with gcc 7.5.0 and -flto -O2 -flto-partition=one generates a
self-referencing DIE:
...
<2><91dace>: Abbrev Number: 405 (DW_TAG_label)
<91dad0> DW_AT_abstract_origin: <0x91dace>
...
When encountering the self-reference DIE in inherit_abstract_dies we loop
following the abstract origin, effectively hanging gdb.
Fix this by handling self-referencing DIEs in the loop in
inherit_abstract_dies.
Tested on x86_64-linux.
Approved-By: Tom Tromey <tom@tromey.com>
PR symtab/30799
https://sourceware.org/bugzilla/show_bug.cgi?id=30799
---
gdb/dwarf2/read.c | 7 +++++++
gdb/testsuite/gdb.dwarf2/self-spec.exp | 16 +++++++++++++++-
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 1be5f381432..970dd54c7a5 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -11938,8 +11938,15 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
if (attr == nullptr)
break;
+ die_info *prev_child_origin_die = child_origin_die;
child_origin_die = follow_die_ref (child_origin_die, attr,
&child_origin_cu);
+
+ if (prev_child_origin_die == child_origin_die)
+ {
+ /* Handle DIE with self-reference. */
+ break;
+ }
}
/* If missing DW_AT_abstract_origin, try the corresponding child
diff --git a/gdb/testsuite/gdb.dwarf2/self-spec.exp b/gdb/testsuite/gdb.dwarf2/self-spec.exp
index 77e92549fd1..f04ff6da42e 100644
--- a/gdb/testsuite/gdb.dwarf2/self-spec.exp
+++ b/gdb/testsuite/gdb.dwarf2/self-spec.exp
@@ -14,7 +14,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Check that gdb doesn't hang or segfault on reading a DIE with a
-# specification reference to itself.
+# specification/abstract_origin reference to itself.
load_lib dwarf.exp
@@ -29,11 +29,25 @@ set asm_file [standard_output_file $srcfile2]
Dwarf::assemble $asm_file {
cu {} {
compile_unit {{language @DW_LANG_C_plus_plus}} {
+ # Check handling of self-referencing DIE.
declare_labels c1
c1: class_type {
{name c1}
{specification :$c1}
}
+
+ # Check handling of self-referencing child DIE. Regression test
+ # for PR30799.
+ declare_labels f1 abstract_f1 f1_l
+ abstract_f1: subprogram {}
+ f1: subprogram {
+ {MACRO_AT_func {main}}
+ {abstract_origin :$abstract_f1}
+ } {
+ f1_l: label {
+ {abstract_origin :$f1_l}
+ }
+ }
}
}
}
--
2.35.3

View File

@ -1,7 +1,7 @@
From be9718e911aff34896dcf1c3dfa41bfe34e5a9f4 Mon Sep 17 00:00:00 2001
From 0e706742f37ee90629350780263b573f326f1a5f Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 7 Dec 2023 10:38:05 +0100
Subject: [PATCH 10/11] [gdb/symtab] Keep track of all parents for cooked index
Subject: [PATCH 12/13] [gdb/symtab] Keep track of all parents for cooked index
Keep track of all parents for cooked index.
@ -11,10 +11,10 @@ Tested on x86_64-linux.
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 39f6e480e19..e2d4fe8cde6 100644
index de7b655d26c..93708ef11b9 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -18626,9 +18626,15 @@ cooked_indexer::index_dies (cutu_reader *reader,
@@ -16718,9 +16718,15 @@ cooked_indexer::index_dies (cutu_reader *reader,
});
}
else

View File

@ -1,7 +1,7 @@
From 439271c6fc28387ea7b6fb6e8bb07963e8b3fd7d Mon Sep 17 00:00:00 2001
From e8285c8b37d28033209cad6579db4b9f6a48a01a Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Sun, 24 Sep 2023 11:41:39 +0200
Subject: [PATCH 06/11] [gdb/symtab] Keep track of processed DIEs in shard
Subject: [PATCH 08/13] [gdb/symtab] Keep track of processed DIEs in shard
For optimizations in two following patches, we keep track in each shard which
DIEs have been processed.
@ -14,10 +14,10 @@ Tested on x86_64-linux.
3 files changed, 40 insertions(+)
diff --git a/gdb/dwarf2/cooked-index.c b/gdb/dwarf2/cooked-index.c
index 4a0ccc78c5d..cef57a96384 100644
index 3231d25db5a..c096da57d62 100644
--- a/gdb/dwarf2/cooked-index.c
+++ b/gdb/dwarf2/cooked-index.c
@@ -541,6 +541,7 @@ cooked_index_vector::handle_deferred_entries ()
@@ -723,6 +723,7 @@ cooked_index::handle_deferred_entries ()
{
shard->m_die_range_map.reset (nullptr);
shard->m_deferred_entries.reset (nullptr);
@ -26,18 +26,18 @@ index 4a0ccc78c5d..cef57a96384 100644
}
diff --git a/gdb/dwarf2/cooked-index.h b/gdb/dwarf2/cooked-index.h
index a06d99532ed..9d836379666 100644
index 66424c37f7c..fa895233035 100644
--- a/gdb/dwarf2/cooked-index.h
+++ b/gdb/dwarf2/cooked-index.h
@@ -312,6 +312,7 @@ class cooked_index
@@ -316,6 +316,7 @@ class cooked_index_shard
{
m_die_range_map.reset (new parent_map);
m_deferred_entries.reset (new std::vector<deferred_entry>);
+ m_die_range_map_valid.reset (new addrmap_mutable);
}
/* Create a new cooked_index_entry and register it with this object.
@@ -403,6 +404,18 @@ class cooked_index
DISABLE_COPY_AND_ASSIGN (cooked_index_shard);
@@ -407,6 +408,18 @@ class cooked_index_shard
const cooked_index_entry *resolve_deferred_entry
(const deferred_entry &entry, const cooked_index_entry *parent_entry);
@ -56,7 +56,7 @@ index a06d99532ed..9d836379666 100644
private:
/* Return the entry that is believed to represent the program's
@@ -466,6 +479,8 @@ class cooked_index
@@ -470,6 +483,8 @@ class cooked_index_shard
understand this. */
std::unique_ptr<parent_map> m_die_range_map;
@ -66,10 +66,10 @@ index a06d99532ed..9d836379666 100644
method in a class (or perhaps namespace) scope, with the
definition appearing outside this scope... just one of the many
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 41fa8affcd0..ba21b6a14c9 100644
index 5b7c0969ed7..09598e702bc 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -6697,6 +6697,12 @@ class cooked_index_storage
@@ -4697,6 +4697,12 @@ class cooked_index_storage
m_index->defer_entry (de);
}
@ -82,7 +82,7 @@ index 41fa8affcd0..ba21b6a14c9 100644
private:
/* Hash function for a cutu_reader. */
@@ -6840,6 +6846,11 @@ class cooked_indexer
@@ -4840,6 +4846,11 @@ class cooked_indexer
{
m_index_storage->defer_entry (de);
}
@ -94,9 +94,9 @@ index 41fa8affcd0..ba21b6a14c9 100644
};
/* Subroutine of dwarf2_build_psymtabs_hard to simplify it.
@@ -18512,6 +18523,11 @@ cooked_indexer::index_dies (cutu_reader *reader,
@@ -16604,6 +16615,11 @@ cooked_indexer::index_dies (cutu_reader *reader,
+ to_underlying (reader->cu->header.sect_off)
+ reader->cu->header.get_length ());
+ reader->cu->header.get_length_with_initial ());
+ const CORE_ADDR start_cu
+ = parent_map::form_addr (sect_offset (info_ptr - reader->buffer),
@ -106,7 +106,7 @@ index 41fa8affcd0..ba21b6a14c9 100644
while (info_ptr < end_ptr)
{
sect_offset this_die = (sect_offset) (info_ptr - reader->buffer);
@@ -18662,6 +18678,14 @@ cooked_indexer::index_dies (cutu_reader *reader,
@@ -16754,6 +16770,14 @@ cooked_indexer::index_dies (cutu_reader *reader,
}
}

View File

@ -1,7 +1,7 @@
From 541d6970c278dc5a8e9e32246b7139261a687592 Mon Sep 17 00:00:00 2001
From 0f53dc7e5cc07e30d11f3f5a0645239535824890 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 7 Dec 2023 10:36:07 +0100
Subject: [PATCH 09/11] [gdb/symtab] Recurse into c++ DW_TAG_subprogram DIEs
Subject: [PATCH 11/13] [gdb/symtab] Recurse into c++ DW_TAG_subprogram DIEs
for cooked index
Recurse into c++ DW_TAG_subprogram DIEs for cooked index, to add
@ -13,10 +13,10 @@ Tested on x86_64-linux.
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index d2d50b5c9cc..39f6e480e19 100644
index e7904532434..de7b655d26c 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -18689,7 +18689,8 @@ cooked_indexer::index_dies (cutu_reader *reader,
@@ -16781,7 +16781,8 @@ cooked_indexer::index_dies (cutu_reader *reader,
case DW_TAG_subprogram:
if ((m_language == language_fortran

View File

@ -1,7 +1,7 @@
From 0bba1c5bdbcb404327ba4d5f35254b96d2e48108 Mon Sep 17 00:00:00 2001
From f72f115b4c012e3748a2e702d7b970be19974885 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Mon, 11 Dec 2023 15:41:26 +0100
Subject: [PATCH 01/11] [gdb/symtab] Refactor condition in scan_attributes
Subject: [PATCH 01/13] [gdb/symtab] Refactor condition in scan_attributes
In scan_attributes there's code:
...
@ -34,10 +34,10 @@ Tested on x86_64-linux.
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 2339cceb829..00471d20d41 100644
index 50fa302b43a..466d3e59878 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -18315,15 +18315,17 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data *scanning_per_cu,
@@ -16410,15 +16410,17 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data *scanning_per_cu,
const gdb_byte *new_info_ptr = (new_reader->buffer
+ to_underlying (origin_offset));
@ -49,8 +49,8 @@ index 2339cceb829..00471d20d41 100644
+ if (*parent_entry == nullptr)
{
- CORE_ADDR lookup = form_addr (origin_offset, origin_is_dwz);
- *parent_entry
- = (cooked_index_entry *) m_die_range_map.find (lookup);
- void *obj = m_die_range_map.find (lookup);
- *parent_entry = static_cast <cooked_index_entry *> (obj);
+ CORE_ADDR addr = form_addr (origin_offset, origin_is_dwz);
+ if (new_reader->cu == reader->cu
+ && new_info_ptr > watermark_ptr)
@ -64,7 +64,7 @@ index 2339cceb829..00471d20d41 100644
unsigned int bytes_read;
base-commit: d445b7300b129a4886132ec31a23c7c2c894fa75
base-commit: 3490f51a80a10d46dc1885ba672d9390a8221170
--
2.35.3

View File

@ -1,7 +1,7 @@
From 7464f06e1a7ccf4c5908e563e4cf684744919dac Mon Sep 17 00:00:00 2001
From e2d7097cf236c9ea6959785754d067833fc302af Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Tue, 22 Aug 2023 14:24:42 +0200
Subject: [PATCH 05/11] [gdb/symtab] Resolve deferred entries, inter-shard case
Subject: [PATCH 05/13] [gdb/symtab] Resolve deferred entries, inter-shard case
Generically solve the case of inter-CU dependencies, including inter-shard
dependencies:
@ -29,10 +29,10 @@ Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30846
3 files changed, 254 insertions(+), 56 deletions(-)
diff --git a/gdb/dwarf2/cooked-index.c b/gdb/dwarf2/cooked-index.c
index 2b7f9054fe5..4a0ccc78c5d 100644
index 58ea541a5c9..3231d25db5a 100644
--- a/gdb/dwarf2/cooked-index.c
+++ b/gdb/dwarf2/cooked-index.c
@@ -200,6 +200,12 @@ cooked_index_entry::write_scope (struct obstack *storage,
@@ -228,6 +228,12 @@ cooked_index_entry::write_scope (struct obstack *storage,
/* See cooked-index.h. */
@ -43,25 +43,25 @@ index 2b7f9054fe5..4a0ccc78c5d 100644
+/* See cooked-index.h. */
+
const cooked_index_entry *
cooked_index::add (sect_offset die_offset, enum dwarf_tag tag,
cooked_index_flag flags, const char *name,
@@ -402,6 +408,8 @@ cooked_index::find (const std::string &name, bool completing)
cooked_index_vector::cooked_index_vector (vec_type &&vec)
cooked_index_shard::add (sect_offset die_offset, enum dwarf_tag tag,
cooked_index_flag flags, const char *name,
@@ -446,6 +452,8 @@ cooked_index_shard::wait (bool allow_quit) const
cooked_index::cooked_index (vec_type &&vec)
: m_vector (std::move (vec))
{
+ handle_deferred_entries ();
+
for (auto &idx : m_vector)
idx->finalize ();
}
@@ -467,6 +475,75 @@ cooked_index_vector::get_main () const
return result;
@@ -649,6 +657,75 @@ cooked_index::maybe_write_index (dwarf2_per_bfd *per_bfd,
global_index_cache.store (per_bfd, ctx);
}
+/* See cooked-index.h. */
+
+const cooked_index_entry *
+cooked_index::resolve_deferred_entry
+cooked_index_shard::resolve_deferred_entry
+ (const deferred_entry &de, const cooked_index_entry *parent_entry)
+{
+ reset_parent_deferred (parent_map::form_addr (de.die_offset, de.per_cu_2->is_dwz,
@ -73,8 +73,8 @@ index 2b7f9054fe5..4a0ccc78c5d 100644
+/* See cooked-index.h. */
+
+const cooked_index_entry *
+cooked_index_vector::find_parent_deferred_entry
+ (const cooked_index::deferred_entry &entry) const
+cooked_index::find_parent_deferred_entry
+ (const cooked_index_shard::deferred_entry &entry) const
+{
+ const cooked_index_entry *parent_entry = nullptr;
+ for (auto &parent_map_shard : m_vector)
@ -93,7 +93,7 @@ index 2b7f9054fe5..4a0ccc78c5d 100644
+/* See cooked-index.h. */
+
+void
+cooked_index_vector::handle_deferred_entries ()
+cooked_index::handle_deferred_entries ()
+{
+ bool changed;
+ bool deferred;
@ -127,11 +127,11 @@ index 2b7f9054fe5..4a0ccc78c5d 100644
+ }
+}
+
void _initialize_cooked_index ();
void
_initialize_cooked_index ()
/* Wait for all the index cache entries to be written before gdb
exits. */
static void
diff --git a/gdb/dwarf2/cooked-index.h b/gdb/dwarf2/cooked-index.h
index f4abc7a974e..a06d99532ed 100644
index 79fbfe88c03..66424c37f7c 100644
--- a/gdb/dwarf2/cooked-index.h
+++ b/gdb/dwarf2/cooked-index.h
@@ -34,6 +34,7 @@
@ -141,8 +141,8 @@ index f4abc7a974e..a06d99532ed 100644
+#include <unordered_set>
struct dwarf2_per_cu_data;
@@ -236,19 +237,29 @@ struct cooked_index_entry : public allocate_on_obstack
struct dwarf2_per_bfd;
@@ -242,19 +243,29 @@ struct cooked_index_entry : public allocate_on_obstack
class parent_map
{
public:
@ -173,7 +173,7 @@ index f4abc7a974e..a06d99532ed 100644
const void *obj = m_parent_map.find (lookup);
return static_cast<const cooked_index_entry *> (obj);
}
@@ -259,12 +270,28 @@ class parent_map
@@ -265,12 +276,28 @@ class parent_map
{
/* Calling set_empty with nullptr is currently not allowed. */
if (parent_entry != nullptr)
@ -202,26 +202,24 @@ index f4abc7a974e..a06d99532ed 100644
+ std::unordered_set<CORE_ADDR> m_deferred;
};
class cooked_index_vector;
@@ -279,9 +306,14 @@ class cooked_index_vector;
class cooked_index
class cooked_index;
@@ -285,7 +312,12 @@ class cooked_index;
class cooked_index_shard
{
public:
- cooked_index () = default;
DISABLE_COPY_AND_ASSIGN (cooked_index);
+ cooked_index ()
- cooked_index_shard () = default;
+ cooked_index_shard ()
+ {
+ m_die_range_map.reset (new parent_map);
+ m_deferred_entries.reset (new std::vector<deferred_entry>);
+ }
+
DISABLE_COPY_AND_ASSIGN (cooked_index_shard);
/* Create a new cooked_index_entry and register it with this object.
Entries are owned by this object. The new item is returned. */
const cooked_index_entry *add (sect_offset die_offset, enum dwarf_tag tag,
@@ -325,6 +357,52 @@ class cooked_index
@@ -329,6 +361,52 @@ class cooked_index_shard
for completion, will be returned. */
range find (const std::string &name, bool completing);
range find (const std::string &name, bool completing) const;
+ /* Find the parent of DIE LOOKUP. */
+ const cooked_index_entry *
@ -272,7 +270,7 @@ index f4abc7a974e..a06d99532ed 100644
private:
/* Return the entry that is believed to represent the program's
@@ -382,6 +460,20 @@ class cooked_index
@@ -386,6 +464,20 @@ class cooked_index_shard
that the 'get' method is never called on this future, only
'wait'. */
gdb::future<void> m_future;
@ -293,25 +291,25 @@ index f4abc7a974e..a06d99532ed 100644
};
/* The main index of DIEs. The parallel DIE indexers create
@@ -459,6 +551,13 @@ class cooked_index_vector : public dwarf_scanner_base
@@ -469,6 +561,13 @@ class cooked_index : public dwarf_scanner_base
private:
+ /* Find the parent corresponding to deferred entry ENTRY. */
+ const cooked_index_entry *find_parent_deferred_entry
+ (const cooked_index::deferred_entry &entry) const;
+ (const cooked_index_shard::deferred_entry &entry) const;
+
+ /* Create cooked_index_entries for the deferred entries. */
+ void handle_deferred_entries ();
+
/* The vector of cooked_index objects. This is stored because the
entries are stored on the obstacks in those objects. */
vec_type m_vector;
/* Maybe write the index to the index cache. */
void maybe_write_index (dwarf2_per_bfd *per_bfd,
const index_cache_store_context &);
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index ff5be8e7dc5..41fa8affcd0 100644
index afdf9e870a8..5b7c0969ed7 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -6672,6 +6672,31 @@ class cooked_index_storage
@@ -4672,6 +4672,31 @@ class cooked_index_storage
return &m_addrmap;
}
@ -335,7 +333,7 @@ index ff5be8e7dc5..41fa8affcd0 100644
+ }
+
+ /* Defer creating a cooked_index_entry corresponding to deferred_entry DE. */
+ void defer_entry (cooked_index::deferred_entry de)
+ void defer_entry (cooked_index_shard::deferred_entry de)
+ {
+ m_index->defer_entry (de);
+ }
@ -343,7 +341,7 @@ index ff5be8e7dc5..41fa8affcd0 100644
private:
/* Hash function for a cutu_reader. */
@@ -6794,59 +6819,26 @@ class cooked_indexer
@@ -4794,59 +4819,26 @@ class cooked_indexer
/* Find the parent of DIE LOOKUP. */
const cooked_index_entry *find_parent (CORE_ADDR lookup) const
{
@ -399,7 +397,7 @@ index ff5be8e7dc5..41fa8affcd0 100644
- /* Create cooked_index_entries for the deferred entries. */
- void handle_deferred_entries ()
+ /* Defer creating a cooked_index_entry corresponding to deferred_entry DE. */
+ void defer_entry (const cooked_index::deferred_entry &de)
+ void defer_entry (const cooked_index_shard::deferred_entry &de)
{
- for (const auto &entry : m_deferred_entries)
- {
@ -411,7 +409,7 @@ index ff5be8e7dc5..41fa8affcd0 100644
}
};
@@ -18346,13 +18338,36 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data *scanning_per_cu,
@@ -16441,13 +16433,36 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data *scanning_per_cu,
if (*parent_entry == nullptr)
{
@ -453,7 +451,7 @@ index ff5be8e7dc5..41fa8affcd0 100644
}
unsigned int bytes_read;
@@ -18475,10 +18490,12 @@ cooked_indexer::recurse (cutu_reader *reader,
@@ -16567,10 +16582,12 @@ cooked_indexer::recurse (cutu_reader *reader,
limit the range to the children of parent_entry. */
CORE_ADDR start
= parent_map::form_addr (parent_entry->die_offset + 1,
@ -468,7 +466,7 @@ index ff5be8e7dc5..41fa8affcd0 100644
set_parent (start, end, parent_entry);
}
@@ -18545,9 +18562,16 @@ cooked_indexer::index_dies (cutu_reader *reader,
@@ -16637,9 +16654,16 @@ cooked_indexer::index_dies (cutu_reader *reader,
if (name != nullptr)
{
if (defer != 0)
@ -488,7 +486,7 @@ index ff5be8e7dc5..41fa8affcd0 100644
else
this_entry = m_index_storage->add (this_die, abbrev->tag, flags,
name, this_parent_entry,
@@ -18649,8 +18673,6 @@ cooked_indexer::make_index (cutu_reader *reader)
@@ -16741,8 +16765,6 @@ cooked_indexer::make_index (cutu_reader *reader)
if (!reader->comp_unit_die->has_children)
return;
index_dies (reader, reader->info_ptr, nullptr, false);

View File

@ -1,7 +1,7 @@
From a4bf216accd43b25ea9b9b7507c93eb973872a82 Mon Sep 17 00:00:00 2001
From 3b2f2b376bb80edadacc582161c362612947e3a6 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Sun, 24 Sep 2023 11:43:24 +0200
Subject: [PATCH 07/11] [gdb/symtab] Resolve deferred entries, intra-shard case
Subject: [PATCH 09/13] [gdb/symtab] Resolve deferred entries, intra-shard case
In patch "[gdb/symtab] Resolve deferred entries, inter-shard case" we've
solved the generic case of handling deferred entries.
@ -17,24 +17,24 @@ Tested on x86_64-linux.
3 files changed, 52 insertions(+)
diff --git a/gdb/dwarf2/cooked-index.c b/gdb/dwarf2/cooked-index.c
index cef57a96384..d8a12bee265 100644
index c096da57d62..ebed21d510c 100644
--- a/gdb/dwarf2/cooked-index.c
+++ b/gdb/dwarf2/cooked-index.c
@@ -408,6 +408,7 @@ cooked_index::find (const std::string &name, bool completing)
cooked_index_vector::cooked_index_vector (vec_type &&vec)
@@ -452,6 +452,7 @@ cooked_index_shard::wait (bool allow_quit) const
cooked_index::cooked_index (vec_type &&vec)
: m_vector (std::move (vec))
{
+ /* Handle deferred entries, inter-cu case. */
handle_deferred_entries ();
for (auto &idx : m_vector)
@@ -477,6 +478,40 @@ cooked_index_vector::get_main () const
@@ -659,6 +660,40 @@ cooked_index::maybe_write_index (dwarf2_per_bfd *per_bfd,
/* See cooked-index.h. */
+const cooked_index_entry *
+cooked_index::find_parent_deferred_entry
+ (const cooked_index::deferred_entry &entry) const
+cooked_index_shard::find_parent_deferred_entry
+ (const cooked_index_shard::deferred_entry &entry) const
+{
+ return find_parent (entry.spec_offset);
+}
@ -42,7 +42,7 @@ index cef57a96384..d8a12bee265 100644
+/* See cooked-index.h. */
+
+void
+cooked_index::handle_deferred_entries ()
+cooked_index_shard::handle_deferred_entries ()
+{
+ for (auto it = m_deferred_entries->begin (); it != m_deferred_entries->end (); )
+ {
@ -67,19 +67,19 @@ index cef57a96384..d8a12bee265 100644
+/* See cooked-index.h. */
+
const cooked_index_entry *
cooked_index::resolve_deferred_entry
cooked_index_shard::resolve_deferred_entry
(const deferred_entry &de, const cooked_index_entry *parent_entry)
diff --git a/gdb/dwarf2/cooked-index.h b/gdb/dwarf2/cooked-index.h
index 9d836379666..bda1ed1e155 100644
index fa895233035..106e3091a90 100644
--- a/gdb/dwarf2/cooked-index.h
+++ b/gdb/dwarf2/cooked-index.h
@@ -404,6 +404,13 @@ class cooked_index
@@ -408,6 +408,13 @@ class cooked_index_shard
const cooked_index_entry *resolve_deferred_entry
(const deferred_entry &entry, const cooked_index_entry *parent_entry);
+ /* Find the parent entry for deferred_entry ENTRY. */
+ const cooked_index_entry *find_parent_deferred_entry
+ (const cooked_index::deferred_entry &entry) const;
+ (const cooked_index_shard::deferred_entry &entry) const;
+
+ /* Create cooked_index_entries for the deferred entries. */
+ void handle_deferred_entries ();
@ -88,10 +88,10 @@ index 9d836379666..bda1ed1e155 100644
void set_parent_valid (CORE_ADDR start, CORE_ADDR end)
{
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index ba21b6a14c9..0ab3e1a1500 100644
index 09598e702bc..a97f738a54e 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -6697,6 +6697,12 @@ class cooked_index_storage
@@ -4697,6 +4697,12 @@ class cooked_index_storage
m_index->defer_entry (de);
}
@ -104,7 +104,7 @@ index ba21b6a14c9..0ab3e1a1500 100644
/* Mark parents in range [START, END] as valid . */
void set_parent_valid (CORE_ADDR start, CORE_ADDR end)
{
@@ -7183,6 +7189,10 @@ dwarf2_build_psymtabs_hard (dwarf2_per_objfile *per_objfile)
@@ -5183,6 +5189,10 @@ dwarf2_build_psymtabs_hard (dwarf2_per_objfile *per_objfile)
errors.push_back (std::move (except));
}
}

View File

@ -1,7 +1,7 @@
From b1136560e772dd4c74f1fbb41f6ba840b92fb9d6 Mon Sep 17 00:00:00 2001
From 1b878333913343630472f89b4bc42f51b1619308 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Wed, 1 Nov 2023 00:33:12 +0100
Subject: [PATCH 2/2] [gdb/symtab] Work around gas PR28629
Subject: [PATCH 1/2] [gdb/symtab] Work around gas PR28629
When running test-case gdb.tui/tui-layout-asm-short-prog.exp on AlmaLinux 9.2
ppc64le, I run into:
@ -76,12 +76,12 @@ Approved-By: Tom Tromey <tom@tromey.com>
gdb/dwarf2/cu.c | 1 +
gdb/dwarf2/cu.h | 1 +
gdb/dwarf2/read.c | 37 +++++++-
.../gdb.dwarf2/dw2-gas-workaround.exp | 94 +++++++++++++++++++
4 files changed, 132 insertions(+), 1 deletion(-)
.../gdb.dwarf2/dw2-gas-workaround.exp | 92 +++++++++++++++++++
4 files changed, 130 insertions(+), 1 deletion(-)
create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-gas-workaround.exp
diff --git a/gdb/dwarf2/cu.c b/gdb/dwarf2/cu.c
index 42fd4f4441b..6b5d956649f 100644
index a908ec908cd..f9b05dfc709 100644
--- a/gdb/dwarf2/cu.c
+++ b/gdb/dwarf2/cu.c
@@ -40,6 +40,7 @@ dwarf2_cu::dwarf2_cu (dwarf2_per_cu_data *per_cu,
@ -93,7 +93,7 @@ index 42fd4f4441b..6b5d956649f 100644
processing_has_namespace_info (false),
load_all_dies (false)
diff --git a/gdb/dwarf2/cu.h b/gdb/dwarf2/cu.h
index 710aeb5b237..9b1e8775ff4 100644
index 6c611710503..ef8db480e3f 100644
--- a/gdb/dwarf2/cu.h
+++ b/gdb/dwarf2/cu.h
@@ -265,6 +265,7 @@ struct dwarf2_cu
@ -105,19 +105,19 @@ index 710aeb5b237..9b1e8775ff4 100644
/* When true, the file that we're processing is known to have
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 472684a5817..2339cceb829 100644
index fc4667b782f..50fa302b43a 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -146,6 +146,8 @@ static int dwarf2_loclist_index;
static int dwarf2_locexpr_block_index;
@@ -147,6 +147,8 @@ static int dwarf2_locexpr_block_index;
static int dwarf2_loclist_block_index;
static int ada_block_index;
+static bool producer_is_gas_lt_2_38 (struct dwarf2_cu *cu);
+
/* Size of .debug_loclists section header for 32-bit DWARF format. */
#define LOCLIST_HEADER_SIZE32 12
@@ -9663,6 +9665,27 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
@@ -7665,6 +7667,27 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
file_and_directory &fnd = find_file_and_directory (die, cu);
@ -145,7 +145,7 @@ index 472684a5817..2339cceb829 100644
cu->start_compunit_symtab (fnd.get_name (), fnd.intern_comp_dir (objfile),
lowpc);
@@ -13377,7 +13400,10 @@ check_producer (struct dwarf2_cu *cu)
@@ -11427,7 +11450,10 @@ check_producer (struct dwarf2_cu *cu)
else if (producer_is_clang (cu->producer, &major, &minor))
cu->producer_is_clang = true;
else if (producer_is_gas (cu->producer, &major, &minor))
@ -157,7 +157,7 @@ index 472684a5817..2339cceb829 100644
else
{
/* For other non-GCC compilers, expect their behavior is DWARF version
@@ -13413,6 +13439,15 @@ producer_is_codewarrior (struct dwarf2_cu *cu)
@@ -11463,6 +11489,15 @@ producer_is_codewarrior (struct dwarf2_cu *cu)
return cu->producer_is_codewarrior;
}
@ -175,10 +175,10 @@ index 472684a5817..2339cceb829 100644
{
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-gas-workaround.exp b/gdb/testsuite/gdb.dwarf2/dw2-gas-workaround.exp
new file mode 100644
index 00000000000..416778f51b7
index 00000000000..ca2b10f23b3
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-gas-workaround.exp
@@ -0,0 +1,94 @@
@@ -0,0 +1,92 @@
+# Copyright 2023 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
@ -199,9 +199,7 @@ index 00000000000..416778f51b7
+load_lib dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+if { ![dwarf2_support] } {
+ return -1
+}
+require dwarf2_support
+
+standard_testfile dw2-lines.c -dw2.S
+
@ -273,6 +271,8 @@ index 00000000000..416778f51b7
+ pass $gdb_test_name
+ }
+}
base-commit: d9951c3c9ea2e542d071710e9706ed505046fe36
--
2.35.3

View File

@ -0,0 +1,137 @@
From 582fc35843fdf71b82d645d83d2903e2546cc21a Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Wed, 1 May 2024 15:10:50 +0200
Subject: [PATCH 2/2] [gdb/symtab] Work around PR gas/29517, dwarf2 case
In commit 1d45d90934b ("[gdb/symtab] Work around PR gas/29517") we added a
workaround for PR gas/29517.
The problem is present in gas version 2.39, and fixed in 2.40, so the
workaround is only active for gas version == 2.39.
However, the problem in gas is only fixed for dwarf version >= 3, which
supports DW_TAG_unspecified_type.
Fix this by also activating the workaround for dwarf version == 2.
Tested on x86_64-linux.
PR symtab/31689
https://sourceware.org/bugzilla/show_bug.cgi?id=31689
---
gdb/dwarf2/read.c | 5 +++-
.../gdb.dwarf2/dw2-unspecified-type-foo.c | 7 ++++++
.../gdb.dwarf2/dw2-unspecified-type.c | 3 ++-
.../gdb.dwarf2/dw2-unspecified-type.exp | 23 ++++++++++++++++++-
4 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 761437f6631..fc4667b782f 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -14646,10 +14646,13 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
type = die_type (die, cu);
+ /* PR gas/29517 occurs in 2.39, and is fixed in 2.40, but it's only fixed
+ for dwarf version >= 3 which supports DW_TAG_unspecified_type. */
if (type->code () == TYPE_CODE_VOID
&& !type->is_stub ()
&& die->child == nullptr
- && producer_is_gas_2_39 (cu))
+ && (cu->per_cu->version () == 2
+ || producer_is_gas_2_39 (cu)))
{
/* Work around PR gas/29517, pretend we have an DW_TAG_unspecified_type
return type. */
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type-foo.c b/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type-foo.c
index 164e781c9f0..bcf525a4d2e 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type-foo.c
+++ b/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type-foo.c
@@ -21,3 +21,10 @@ foo (void)
asm ("foo_label: .globl foo_label");
return 0;
}
+
+int
+foo2 (void)
+{
+ asm ("foo2_label: .globl foo2_label");
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.c b/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.c
index e07d9517ff2..9e600f9dcce 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.c
+++ b/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.c
@@ -16,6 +16,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
extern int foo (void);
+extern int foo2 (void);
int
bar (void)
@@ -27,6 +28,6 @@ bar (void)
int
main (void)
{
- int res = foo () + bar ();
+ int res = foo () + bar () + foo2 ();
return res;
}
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.exp b/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.exp
index a6f2a57e33e..947246ba44d 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.exp
@@ -34,11 +34,19 @@ lassign $bar_res \
bar_start bar_len
set bar_end "$bar_start + $bar_len"
+set foo2_res \
+ [function_range foo2 \
+ [list ${srcdir}/${subdir}/$srcfile ${srcdir}/${subdir}/$srcfile2]]
+lassign $foo2_res \
+ foo2_start foo2_len
+set foo2_end "$foo2_start + $foo2_len"
+
# Create the DWARF.
set asm_file [standard_output_file $srcfile3]
Dwarf::assemble $asm_file {
global foo_start foo_end
global bar_start bar_end
+ global foo2_start foo2_end
declare_labels unspecified_type_label
cu {} {
@@ -68,6 +76,19 @@ Dwarf::assemble $asm_file {
}
}
}
+
+ cu { version 2 } {
+ compile_unit {
+ {language @DW_LANG_Mips_Assembler}
+ {producer "GNU AS 2.40.0"}
+ } {
+ DW_TAG_subprogram {
+ {name foo2}
+ {low_pc $foo2_start addr}
+ {high_pc $foo2_end addr}
+ }
+ }
+ }
}
if [prepare_for_testing "failed to prepare" $testfile \
@@ -79,7 +100,7 @@ if ![runto_main] {
return -1
}
-foreach f {foo bar} {
+foreach f {foo bar foo2} {
# Print the function type. Return type should be stub type, which is printed
# as void.
gdb_test "ptype $f" "type = void \\(void\\)"
--
2.35.3

View File

@ -1,7 +1,7 @@
From 92a5f5ae1b71d152d943ee896bf6cd073d50daa7 Mon Sep 17 00:00:00 2001
From 7a2731d9d1c0926d22905b9d07e32a7b63c43b34 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 28 Sep 2023 13:55:07 +0200
Subject: [PATCH 02/12] [gdb/symtab] Work around PR gas/29517
Subject: [PATCH 57/65] Work around PR gas/29517
When using glibc debuginfo generated with gas 2.39, we run into PR gas/29517:
...
@ -61,14 +61,14 @@ Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30911
---
gdb/dwarf2/cu.c | 1 +
gdb/dwarf2/cu.h | 1 +
gdb/dwarf2/read.c | 22 ++++++++++++
gdb/dwarf2/read.c | 23 ++++++++++++
gdb/producer.c | 8 ++++-
.../gdb.dwarf2/dw2-unspecified-type.c | 9 ++++-
.../gdb.dwarf2/dw2-unspecified-type.exp | 36 +++++++++++++++----
6 files changed, 68 insertions(+), 9 deletions(-)
6 files changed, 69 insertions(+), 9 deletions(-)
diff --git a/gdb/dwarf2/cu.c b/gdb/dwarf2/cu.c
index 9c1691c90e9..42fd4f4441b 100644
index 89de40daab0..a908ec908cd 100644
--- a/gdb/dwarf2/cu.c
+++ b/gdb/dwarf2/cu.c
@@ -40,6 +40,7 @@ dwarf2_cu::dwarf2_cu (dwarf2_per_cu_data *per_cu,
@ -80,7 +80,7 @@ index 9c1691c90e9..42fd4f4441b 100644
load_all_dies (false)
{
diff --git a/gdb/dwarf2/cu.h b/gdb/dwarf2/cu.h
index e8dbde9c019..710aeb5b237 100644
index 0c15d8b02db..6c611710503 100644
--- a/gdb/dwarf2/cu.h
+++ b/gdb/dwarf2/cu.h
@@ -265,6 +265,7 @@ struct dwarf2_cu
@ -92,10 +92,10 @@ index e8dbde9c019..710aeb5b237 100644
/* When true, the file that we're processing is known to have
debugging info for C++ namespaces. GCC 3.3.x did not produce
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index b9e7e18f2a6..f39eba7a008 100644
index a5c48baa6f8..e5e557c17d3 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -13370,6 +13370,8 @@ check_producer (struct dwarf2_cu *cu)
@@ -11426,6 +11426,8 @@ check_producer (struct dwarf2_cu *cu)
cu->producer_is_codewarrior = true;
else if (producer_is_clang (cu->producer, &major, &minor))
cu->producer_is_clang = true;
@ -104,7 +104,7 @@ index b9e7e18f2a6..f39eba7a008 100644
else
{
/* For other non-GCC compilers, expect their behavior is DWARF version
@@ -13405,6 +13407,15 @@ producer_is_codewarrior (struct dwarf2_cu *cu)
@@ -11461,6 +11463,15 @@ producer_is_codewarrior (struct dwarf2_cu *cu)
return cu->producer_is_codewarrior;
}
@ -120,7 +120,7 @@ index b9e7e18f2a6..f39eba7a008 100644
/* Return the accessibility of DIE, as given by DW_AT_accessibility.
If that attribute is not available, return the appropriate
default. */
@@ -16581,6 +16592,17 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
@@ -14635,6 +14646,18 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
type = die_type (die, cu);
@ -131,7 +131,8 @@ index b9e7e18f2a6..f39eba7a008 100644
+ {
+ /* Work around PR gas/29517, pretend we have an DW_TAG_unspecified_type
+ return type. */
+ type = init_type (cu->per_objfile->objfile, TYPE_CODE_VOID, 0, NULL);
+ type = (type_allocator (cu->per_objfile->objfile, cu->lang ())
+ .new_type (TYPE_CODE_VOID, 0, nullptr));
+ type->set_is_stub (true);
+ }
+
@ -186,10 +187,10 @@ index 1df09214d4a..e07d9517ff2 100644
return res;
}
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.exp b/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.exp
index a353395592e..bd707204fba 100644
index 5fa6ee544b2..a6f2a57e33e 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.exp
@@ -29,10 +29,18 @@ lassign $foo_res \
@@ -27,10 +27,18 @@ lassign $foo_res \
foo_start foo_len
set foo_end "$foo_start + $foo_len"
@ -208,7 +209,7 @@ index a353395592e..bd707204fba 100644
declare_labels unspecified_type_label
cu {} {
@@ -47,7 +55,19 @@ Dwarf::assemble $asm_file {
@@ -45,7 +53,19 @@ Dwarf::assemble $asm_file {
{high_pc $foo_end addr}
{type :$unspecified_type_label}
}
@ -228,7 +229,7 @@ index a353395592e..bd707204fba 100644
}
}
}
@@ -61,12 +81,14 @@ if ![runto_main] {
@@ -59,12 +79,14 @@ if ![runto_main] {
return -1
}

View File

@ -0,0 +1,122 @@
From d25e3f4ed05c3a6c207263d7e532f829860b83f0 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Wed, 20 Mar 2024 09:57:49 +0100
Subject: [PATCH 1/7] [gdb/symtab] Workaround PR gas/31115
On arm-linux, with gas 2.40, I run into:
...
(gdb) x /i main+8^M
0x4e1 <main+7>: vrhadd.u16 d14, d14, d31^M
(gdb) FAIL: gdb.arch/pr25124.exp: disassemble thumb instruction (1st try)
...
This is a regression due to PR gas/31115, which makes gas produce a low_pc
with the thumb bit set (0x4d8 & 0x1):
...
<1><24>: Abbrev Number: 2 (DW_TAG_subprogram)
<25> DW_AT_name : main
<29> DW_AT_external : 1
<29> DW_AT_type : <0x2f>
<2a> DW_AT_low_pc : 0x4d9
<2e> DW_AT_high_pc : 12
...
The regression was introduced in 2.39, and is also present in 2.40 and 2.41,
and hasn't been fixed yet.
Work around this in read_func_scope, by using gdbarch_addr_bits_remove on
low_pc and high_pc.
Tested on arm-linux and x86_64-linux.
PR tdep/31453
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31453
---
gdb/dwarf2/cu.c | 1 +
gdb/dwarf2/cu.h | 1 +
gdb/dwarf2/read.c | 22 ++++++++++++++++++++++
3 files changed, 24 insertions(+)
diff --git a/gdb/dwarf2/cu.c b/gdb/dwarf2/cu.c
index f9b05dfc709..7f89500effd 100644
--- a/gdb/dwarf2/cu.c
+++ b/gdb/dwarf2/cu.c
@@ -42,6 +42,7 @@ dwarf2_cu::dwarf2_cu (dwarf2_per_cu_data *per_cu,
producer_is_clang (false),
producer_is_gas_lt_2_38 (false),
producer_is_gas_2_39 (false),
+ producer_is_gas_ge_2_40 (false),
processing_has_namespace_info (false),
load_all_dies (false)
{
diff --git a/gdb/dwarf2/cu.h b/gdb/dwarf2/cu.h
index ef8db480e3f..1b02f89ed2f 100644
--- a/gdb/dwarf2/cu.h
+++ b/gdb/dwarf2/cu.h
@@ -267,6 +267,7 @@ struct dwarf2_cu
bool producer_is_clang : 1;
bool producer_is_gas_lt_2_38 : 1;
bool producer_is_gas_2_39 : 1;
+ bool producer_is_gas_ge_2_40 : 1;
/* When true, the file that we're processing is known to have
debugging info for C++ namespaces. GCC 3.3.x did not produce
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index a4f982962ae..8f2d7a34aef 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -148,6 +148,7 @@ static int dwarf2_loclist_block_index;
static int ada_block_index;
static bool producer_is_gas_lt_2_38 (struct dwarf2_cu *cu);
+static bool producer_is_gas_ge_2_39 (struct dwarf2_cu *cu);
/* Size of .debug_loclists section header for 32-bit DWARF format. */
#define LOCLIST_HEADER_SIZE32 12
@@ -10223,6 +10224,15 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
lowpc = per_objfile->relocate (unrel_low);
highpc = per_objfile->relocate (unrel_high);
+ if (gdbarch_bfd_arch_info (gdbarch)->arch == bfd_arch_arm
+ && producer_is_gas_ge_2_39 (cu))
+ {
+ /* Gas version 2.39 produces DWARF for a Thumb subprogram with a low_pc
+ attribute with the thumb bit set (PR gas/31115). Work around this. */
+ lowpc = gdbarch_addr_bits_remove (gdbarch, lowpc);
+ highpc = gdbarch_addr_bits_remove (gdbarch, highpc);
+ }
+
/* If we have any template arguments, then we must allocate a
different sort of symbol. */
for (child_die = die->child; child_die; child_die = child_die->sibling)
@@ -11507,6 +11517,7 @@ check_producer (struct dwarf2_cu *cu)
{
cu->producer_is_gas_lt_2_38 = major < 2 || (major == 2 && minor < 38);
cu->producer_is_gas_2_39 = major == 2 && minor == 39;
+ cu->producer_is_gas_ge_2_40 = major > 2 || (major == 2 && minor >= 40);
}
else
{
@@ -11561,6 +11572,17 @@ producer_is_gas_2_39 (struct dwarf2_cu *cu)
return cu->producer_is_gas_2_39;
}
+/* Return true if CU is produced by GAS 2.39 or later. */
+
+static bool
+producer_is_gas_ge_2_39 (struct dwarf2_cu *cu)
+{
+ if (!cu->checked_producer)
+ check_producer (cu);
+
+ return cu->producer_is_gas_2_39 || cu->producer_is_gas_ge_2_40;
+}
+
/* Return the accessibility of DIE, as given by DW_AT_accessibility.
If that attribute is not available, return the appropriate
default. */
base-commit: c79ecacd3f75cfb0ec1a3afc49ca3f30b1759009
--
2.35.3

View File

@ -1,140 +0,0 @@
From 433568090645c05d3b7fdbb1a4ae0887e96d9cc0 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Mon, 23 Jan 2023 16:49:36 +0100
Subject: [PATCH 1/2] [gdb/tdep, aarch64] Fix frame address of last insn
Consider the test-case test.c, compiled without debug info:
...
void
foo (const char *s)
{
}
int
main (void)
{
foo ("foo");
return 0;
}
...
Disassembly of foo:
...
0000000000400564 <foo>:
400564: d10043ff sub sp, sp, #0x10
400568: f90007e0 str x0, [sp, #8]
40056c: d503201f nop
400570: 910043ff add sp, sp, #0x10
400574: d65f03c0 ret
...
Now, let's do "info frame" at each insn in foo, as well as printing $sp
and $x29 (and strip the output of info frame to the first line, for brevity):
...
$ gdb -q a.out
Reading symbols from a.out...
(gdb) b *foo
Breakpoint 1 at 0x400564
(gdb) r
Starting program: a.out
Breakpoint 1, 0x0000000000400564 in foo ()
(gdb) display /x $sp
1: /x $sp = 0xfffffffff3a0
(gdb) display /x $x29
2: /x $x29 = 0xfffffffff3a0
(gdb) info frame
Stack level 0, frame at 0xfffffffff3a0:
(gdb) si
0x0000000000400568 in foo ()
1: /x $sp = 0xfffffffff390
2: /x $x29 = 0xfffffffff3a0
(gdb) info frame
Stack level 0, frame at 0xfffffffff3a0:
(gdb) si
0x000000000040056c in foo ()
1: /x $sp = 0xfffffffff390
2: /x $x29 = 0xfffffffff3a0
(gdb) info frame
Stack level 0, frame at 0xfffffffff3a0:
(gdb) si
0x0000000000400570 in foo ()
1: /x $sp = 0xfffffffff390
2: /x $x29 = 0xfffffffff3a0
(gdb) info frame
Stack level 0, frame at 0xfffffffff3a0:
(gdb) si
0x0000000000400574 in foo ()
1: /x $sp = 0xfffffffff3a0
2: /x $x29 = 0xfffffffff3a0
(gdb) info frame
Stack level 0, frame at 0xfffffffff3b0:
pc = 0x400574 in foo; saved pc = 0x40058c
(gdb) si
0x000000000040058c in main ()
1: /x $sp = 0xfffffffff3a0
2: /x $x29 = 0xfffffffff3a0
...
The "frame at" bit lists 0xfffffffff3a0 except at the last insn, where it
lists 0xfffffffff3b0.
The frame address is calculated here in aarch64_make_prologue_cache_1:
...
unwound_fp = get_frame_register_unsigned (this_frame, cache->framereg);
if (unwound_fp == 0)
return;
cache->prev_sp = unwound_fp + cache->framesize;
...
For insns after the prologue, we have cache->framereg == sp and
cache->framesize == 16, so unwound_fp + cache->framesize gives the wrong
answer once sp has been restored to entry value by the before-last insn.
Fix this by detecting the situation that the sp has been restored.
This fixes PRs tdep/30010 and tdep/30011.
This also fixes the aarch64 FAILs in gdb.reverse/solib-precsave.exp and
gdb.reverse/solib-reverse.exp I reported in PR gdb/PR29721.
Tested on aarch64-linux.
PR tdep/30010
PR tdep/30011
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30010
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30011
---
gdb/aarch64-tdep.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index 3cc0d3b234d..499b87ef480 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -145,6 +145,8 @@ static const char *const aarch64_mte_register_names[] =
"tag_ctl"
};
+static int aarch64_stack_frame_destroyed_p (struct gdbarch *, CORE_ADDR);
+
/* AArch64 prologue cache structure. */
struct aarch64_prologue_cache
{
@@ -996,7 +998,10 @@ aarch64_make_prologue_cache_1 (frame_info_ptr this_frame,
if (unwound_fp == 0)
return;
- cache->prev_sp = unwound_fp + cache->framesize;
+ cache->prev_sp = unwound_fp;
+ if (!aarch64_stack_frame_destroyed_p (get_frame_arch (this_frame),
+ cache->prev_pc))
+ cache->prev_sp += cache->framesize;
/* Calculate actual addresses of saved registers using offsets
determined by aarch64_analyze_prologue. */
base-commit: 11c93dc64f6137214809583d9c5a775b18b4f027
--
2.35.3

View File

@ -0,0 +1,130 @@
From e2a2cb30bc4e85f462b817bac5393b3fee1ecf9f Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Tue, 21 Nov 2023 11:44:07 +0100
Subject: [PATCH 3/7] [gdb/tdep] Fix catching syscall execve exit for arm
When running test-case gdb.base/catch-syscall.exp on a pinebook (64-bit
aarch64 kernel, 32-bit userland) I run into:
...
(gdb) PASS: $exp: execve: syscall(s) execve appears in 'info breakpoints'
continue^M
Continuing.^M
^M
Catchpoint 18 (call to syscall execve), 0xf7726318 in execve () from \
/lib/arm-linux-gnueabihf/libc.so.6^M
(gdb) PASS: gdb.base/catch-syscall.exp: execve: program has called execve
continue^M
Continuing.^M
process 32392 is executing new program: catch-syscall^M
Cannot access memory at address 0xf77c6a7c^M
(gdb) FAIL: $exp: execve: syscall execve has returned
...
The memory error is thrown by arm_linux_get_syscall_number, when doing:
...
/* PC gets incremented before the syscall-stop, so read the
previous instruction. */
unsigned long this_instr =
read_memory_unsigned_integer (pc - 4, 4, byte_order_for_code);
...
The reason for the error is that we're stopped at the syscall exit of syscall
execve, and the pc is at the first insn of the new exec, which also happens to
be the first insn in the code segment, so consequently we cannot read the
previous insn.
Fix this by detecting the situation by looking at the register state, similar
to what is done in aarch64_linux_get_syscall_number.
Furthermore, catch the memory error by using safe_read_memory_unsigned_integer
and return -1 instead, matching the documented behaviour of
arm_linux_get_syscall_number.
Finally, rather than using a hardcoded constant 11, introduce an ad-hoc
arm_sys_execve.
Tested on pinebook.
PR tdep/31071
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31071
---
gdb/arm-linux-tdep.c | 42 ++++++++++++++++++++++++++++++++++++++----
1 file changed, 38 insertions(+), 4 deletions(-)
diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c
index 33748731cfd..8116c1368ff 100644
--- a/gdb/arm-linux-tdep.c
+++ b/gdb/arm-linux-tdep.c
@@ -813,6 +813,32 @@ arm_linux_sigreturn_next_pc (struct regcache *regcache,
return next_pc;
}
+/* Return true if we're at execve syscall-exit-stop. */
+
+static bool
+is_execve_syscall_exit (struct regcache *regs)
+{
+ ULONGEST reg = -1;
+
+ /* Check that lr is 0. */
+ regcache_cooked_read_unsigned (regs, ARM_LR_REGNUM, &reg);
+ if (reg != 0)
+ return false;
+
+ /* Check that r0-r8 is 0. */
+ for (int i = 0; i <= 8; ++i)
+ {
+ reg = -1;
+ regcache_cooked_read_unsigned (regs, ARM_A1_REGNUM + i, &reg);
+ if (reg != 0)
+ return false;
+ }
+
+ return true;
+}
+
+#define arm_sys_execve 11
+
/* At a ptrace syscall-stop, return the syscall number. This either
comes from the SWI instruction (OABI) or from r7 (EABI).
@@ -830,6 +856,9 @@ arm_linux_get_syscall_number (struct gdbarch *gdbarch,
int is_thumb;
ULONGEST svc_number = -1;
+ if (is_execve_syscall_exit (regs))
+ return arm_sys_execve;
+
regcache_cooked_read_unsigned (regs, ARM_PC_REGNUM, &pc);
regcache_cooked_read_unsigned (regs, ARM_PS_REGNUM, &cpsr);
is_thumb = (cpsr & t_bit) != 0;
@@ -845,9 +874,14 @@ arm_linux_get_syscall_number (struct gdbarch *gdbarch,
/* PC gets incremented before the syscall-stop, so read the
previous instruction. */
- unsigned long this_instr =
- read_memory_unsigned_integer (pc - 4, 4, byte_order_for_code);
-
+ unsigned long this_instr;
+ {
+ ULONGEST val;
+ if (!safe_read_memory_unsigned_integer (pc - 4, 4, byte_order_for_code,
+ &val))
+ return -1;
+ this_instr = val;
+ }
unsigned long svc_operand = (0x00ffffff & this_instr);
if (svc_operand)
@@ -1265,7 +1299,7 @@ arm_canonicalize_syscall (int syscall)
case 8: return gdb_sys_creat;
case 9: return gdb_sys_link;
case 10: return gdb_sys_unlink;
- case 11: return gdb_sys_execve;
+ case arm_sys_execve: return gdb_sys_execve;
case 12: return gdb_sys_chdir;
case 13: return gdb_sys_time;
case 14: return gdb_sys_mknod;
--
2.35.3

View File

@ -0,0 +1,349 @@
From 83b2b88c96f87a3649b4440f43a088dc6e292181 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Tue, 12 Mar 2024 17:08:18 +0100
Subject: [PATCH 08/48] [gdb/tdep] Fix gdb.base/watch-bitfields.exp on aarch64
On aarch64-linux, with test-case gdb.base/watch-bitfields.exp I run into:
...
(gdb) continue^M
Continuing.^M
^M
Hardware watchpoint 2: -location q.a^M
^M
Old value = 1^M
New value = 0^M
main () at watch-bitfields.c:42^M
42 q.h--;^M
(gdb) FAIL: $exp: -location watch against bitfields: q.e: 0->5: continue
...
In a minimal form, if we step past line 37 which sets q.e, and we have a
watchpoint set on q.e, it triggers:
...
$ gdb -q -batch watch-bitfields -ex "b 37" -ex run -ex "watch q.e" -ex step
Breakpoint 1 at 0x410204: file watch-bitfields.c, line 37.
Breakpoint 1, main () at watch-bitfields.c:37
37 q.e = 5;
Hardware watchpoint 2: q.e
Hardware watchpoint 2: q.e
Old value = 0
New value = 5
main () at /home/vries/gdb/src/gdb/testsuite/gdb.base/watch-bitfields.c:38
38 q.f = 6;
...
However, if we set in addition a watchpoint on q.a, the watchpoint on q.e
doesn't trigger.
How does this happen?
Bitfield q.a is just bit 0 of byte 0, and bitfield q.e is bit 4..7 of byte 1
and bit 1 of byte 2. So, watch q.a should watch byte 0, and watch q.e should
watch bytes 1 and 2.
Using "maint set show-debug-regs on" (and some more detailed debug prints) we
get:
...
WP2: addr=0x440028 (orig=0x440029), ctrl=0x000000d5, ref.count=1
ctrl: enabled=1, offset=1, len=2
WP3: addr=0x440028 (orig=0x440028), ctrl=0x00000035, ref.count=1
ctrl: enabled=1, offset=0, len=1
...
which matches that.
When executing line 37, a hardware watchpoint trap triggers and we hit
aarch64_stopped_data_address with addr_trap == 0x440028:
...
(gdb) p /x addr_trap
$1 = 0x440028
....
and since the loop in aarch64_stopped_data_address walks backward, we check
WP3 first, which matches, and consequently target_stopped_by_watchpoint
returns true in watchpoints_triggered.
Likewise for target_stopped_data_address, which also returns addr == 0x440028.
Watchpoints_triggered matches watchpoint q.a to that address, and sets
watch_triggered_yes.
However, subsequently the value of q.a is checked, and it's the same value as
before (becase the insn in line 37 didn't change q.a), so the watchpoint
hardware trap is not reported to the user.
The problem originates from that fact that aarch64_stopped_data_address picked
WP3 instead of WP2.
There's something we can do about this. In the example above, both
target_stopped_by_watchpoint and target_stopped_data_address returned true.
Instead we can return true in target_stopped_by_watchpoint but false in
target_stopped_data_address. This lets watchpoints_triggered known that a
watchpoint was triggered, but we don't know where, and both watchpoints
get set to watch_triggered_unknown.
Subsequently, the values of both q.a and q.e are checked, and since q.e is not
the same value as before, the watchpoint hardware trap is reported to the user.
Note that this works well for regular (write) watchpoints (watch command), but
not for read watchpoints (rwatch command), because for those no value is
checked. Likewise for access watchpoints (awatch command).
So, fix this by:
- passing a nullptr in aarch64_fbsd_nat_target::stopped_by_watchpoint and
aarch64_linux_nat_target::stopped_by_watchpoint to make clear we're not
interested in the stop address,
- introducing a two-phase approach in aarch64_stopped_data_address, where:
- phase one handles access and read watchpoints, as before, and
- phase two handles write watchpoints, where multiple matches cause:
- return true if addr_p == null, and
- return false if addr_p != null.
Tested on aarch64-linux.
Approved-By: Luis Machado <luis.machado@arm.com>
PR tdep/31214
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31214
---
gdb/aarch64-fbsd-nat.c | 4 +-
gdb/aarch64-linux-nat.c | 4 +-
gdb/aarch64-nat.c | 132 ++++++++++++++++++++++++++-----------
gdb/nat/aarch64-hw-point.c | 25 +++++++
gdb/nat/aarch64-hw-point.h | 2 +
5 files changed, 123 insertions(+), 44 deletions(-)
diff --git a/gdb/aarch64-fbsd-nat.c b/gdb/aarch64-fbsd-nat.c
index 38fb093f139..58518248248 100644
--- a/gdb/aarch64-fbsd-nat.c
+++ b/gdb/aarch64-fbsd-nat.c
@@ -164,9 +164,7 @@ aarch64_fbsd_nat_target::stopped_data_address (CORE_ADDR *addr_p)
bool
aarch64_fbsd_nat_target::stopped_by_watchpoint ()
{
- CORE_ADDR addr;
-
- return stopped_data_address (&addr);
+ return stopped_data_address (nullptr);
}
/* Implement the "stopped_by_hw_breakpoint" target_ops method. */
diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
index c1d59b5d77c..768748a20db 100644
--- a/gdb/aarch64-linux-nat.c
+++ b/gdb/aarch64-linux-nat.c
@@ -972,9 +972,7 @@ aarch64_linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
bool
aarch64_linux_nat_target::stopped_by_watchpoint ()
{
- CORE_ADDR addr;
-
- return stopped_data_address (&addr);
+ return stopped_data_address (nullptr);
}
/* Implement the "can_do_single_step" target_ops method. */
diff --git a/gdb/aarch64-nat.c b/gdb/aarch64-nat.c
index ee8c5a1e21d..89d1ba6acc6 100644
--- a/gdb/aarch64-nat.c
+++ b/gdb/aarch64-nat.c
@@ -231,46 +231,102 @@ bool
aarch64_stopped_data_address (const struct aarch64_debug_reg_state *state,
CORE_ADDR addr_trap, CORE_ADDR *addr_p)
{
- int i;
-
- for (i = aarch64_num_wp_regs - 1; i >= 0; --i)
- {
- const unsigned int offset
- = aarch64_watchpoint_offset (state->dr_ctrl_wp[i]);
- const unsigned int len = aarch64_watchpoint_length (state->dr_ctrl_wp[i]);
- const CORE_ADDR addr_watch = state->dr_addr_wp[i] + offset;
- const CORE_ADDR addr_watch_aligned = align_down (state->dr_addr_wp[i], 8);
- const CORE_ADDR addr_orig = state->dr_addr_orig_wp[i];
-
- if (state->dr_ref_count_wp[i]
- && DR_CONTROL_ENABLED (state->dr_ctrl_wp[i])
- && addr_trap >= addr_watch_aligned
- && addr_trap < addr_watch + len)
- {
- /* ADDR_TRAP reports the first address of the memory range
- accessed by the CPU, regardless of what was the memory
- range watched. Thus, a large CPU access that straddles
- the ADDR_WATCH..ADDR_WATCH+LEN range may result in an
- ADDR_TRAP that is lower than the
- ADDR_WATCH..ADDR_WATCH+LEN range. E.g.:
-
- addr: | 4 | 5 | 6 | 7 | 8 |
- |---- range watched ----|
- |----------- range accessed ------------|
-
- In this case, ADDR_TRAP will be 4.
-
- To match a watchpoint known to GDB core, we must never
- report *ADDR_P outside of any ADDR_WATCH..ADDR_WATCH+LEN
- range. ADDR_WATCH <= ADDR_TRAP < ADDR_ORIG is a false
- positive on kernels older than 4.10. See PR
- external/20207. */
+ bool found = false;
+ for (int phase = 0; phase <= 1; ++phase)
+ for (int i = aarch64_num_wp_regs - 1; i >= 0; --i)
+ {
+ if (!(state->dr_ref_count_wp[i]
+ && DR_CONTROL_ENABLED (state->dr_ctrl_wp[i])))
+ {
+ /* Watchpoint disabled. */
+ continue;
+ }
+
+ const enum target_hw_bp_type type
+ = aarch64_watchpoint_type (state->dr_ctrl_wp[i]);
+ if (type == hw_execute)
+ {
+ /* Watchpoint disabled. */
+ continue;
+ }
+
+ if (phase == 0)
+ {
+ /* Phase 0: No hw_write. */
+ if (type == hw_write)
+ continue;
+ }
+ else
+ {
+ /* Phase 1: Only hw_write. */
+ if (type != hw_write)
+ continue;
+ }
+
+ const unsigned int offset
+ = aarch64_watchpoint_offset (state->dr_ctrl_wp[i]);
+ const unsigned int len
+ = aarch64_watchpoint_length (state->dr_ctrl_wp[i]);
+ const CORE_ADDR addr_watch = state->dr_addr_wp[i] + offset;
+ const CORE_ADDR addr_watch_aligned
+ = align_down (state->dr_addr_wp[i], 8);
+ const CORE_ADDR addr_orig = state->dr_addr_orig_wp[i];
+
+ /* ADDR_TRAP reports the first address of the memory range
+ accessed by the CPU, regardless of what was the memory
+ range watched. Thus, a large CPU access that straddles
+ the ADDR_WATCH..ADDR_WATCH+LEN range may result in an
+ ADDR_TRAP that is lower than the
+ ADDR_WATCH..ADDR_WATCH+LEN range. E.g.:
+
+ addr: | 4 | 5 | 6 | 7 | 8 |
+ |---- range watched ----|
+ |----------- range accessed ------------|
+
+ In this case, ADDR_TRAP will be 4. */
+ if (!(addr_trap >= addr_watch_aligned
+ && addr_trap < addr_watch + len))
+ {
+ /* Not a match. */
+ continue;
+ }
+
+ /* To match a watchpoint known to GDB core, we must never
+ report *ADDR_P outside of any ADDR_WATCH..ADDR_WATCH+LEN
+ range. ADDR_WATCH <= ADDR_TRAP < ADDR_ORIG is a false
+ positive on kernels older than 4.10. See PR
+ external/20207. */
+ if (addr_p != nullptr)
*addr_p = addr_orig;
- return true;
- }
- }
- return false;
+ if (phase == 0)
+ {
+ /* Phase 0: Return first match. */
+ return true;
+ }
+
+ /* Phase 1. */
+ if (addr_p == nullptr)
+ {
+ /* First match, and we don't need to report an address. No need
+ to look for other matches. */
+ return true;
+ }
+
+ if (!found)
+ {
+ /* First match, and we need to report an address. Look for other
+ matches. */
+ found = true;
+ continue;
+ }
+
+ /* More than one match, and we need to return an address. No need to
+ look for further matches. */
+ return false;
+ }
+
+ return found;
}
/* Define AArch64 maintenance commands. */
diff --git a/gdb/nat/aarch64-hw-point.c b/gdb/nat/aarch64-hw-point.c
index 6747e61e026..3b8cdcba23b 100644
--- a/gdb/nat/aarch64-hw-point.c
+++ b/gdb/nat/aarch64-hw-point.c
@@ -73,6 +73,31 @@ aarch64_watchpoint_length (unsigned int ctrl)
return retval;
}
+/* Utility function that returns the type of a watchpoint according to the
+ content of a hardware debug control register CTRL. */
+
+enum target_hw_bp_type
+aarch64_watchpoint_type (unsigned int ctrl)
+{
+ unsigned int type = DR_CONTROL_TYPE (ctrl);
+
+ switch (type)
+ {
+ case 1:
+ return hw_read;
+ case 2:
+ return hw_write;
+ case 3:
+ return hw_access;
+ case 0:
+ /* Reserved for a watchpoint. It must behave as if the watchpoint is
+ disabled. */
+ return hw_execute;
+ default:
+ gdb_assert_not_reached ("");
+ }
+}
+
/* Given the hardware breakpoint or watchpoint type TYPE and its
length LEN, return the expected encoding for a hardware
breakpoint/watchpoint control register. */
diff --git a/gdb/nat/aarch64-hw-point.h b/gdb/nat/aarch64-hw-point.h
index 2ff9ccb5c1c..71ae2864927 100644
--- a/gdb/nat/aarch64-hw-point.h
+++ b/gdb/nat/aarch64-hw-point.h
@@ -73,6 +73,7 @@
#define DR_CONTROL_ENABLED(ctrl) (((ctrl) & 0x1) == 1)
#define DR_CONTROL_MASK(ctrl) (((ctrl) >> 5) & 0xff)
+#define DR_CONTROL_TYPE(ctrl) (((ctrl) >> 3) & 0x3)
/* Structure for managing the hardware breakpoint/watchpoint resources.
DR_ADDR_* stores the address, DR_CTRL_* stores the control register
@@ -107,6 +108,7 @@ void aarch64_notify_debug_reg_change (ptid_t ptid, int is_watchpoint,
unsigned int aarch64_watchpoint_offset (unsigned int ctrl);
unsigned int aarch64_watchpoint_length (unsigned int ctrl);
+enum target_hw_bp_type aarch64_watchpoint_type (unsigned int ctrl);
int aarch64_handle_breakpoint (enum target_hw_bp_type type, CORE_ADDR addr,
int len, int is_insert, ptid_t ptid,
--
2.35.3

View File

@ -0,0 +1,262 @@
From 3efde6721b362fe0acad348443e4b961d7485717 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 14 Mar 2024 11:25:10 +0100
Subject: [PATCH 09/48] [gdb/tdep] Fix gdb.base/watchpoint-unaligned.exp on
aarch64
On aarch64-linux, with test-case gdb.base/watchpoint-unaligned.exp I run into:
...
(gdb) watch data.u.size8twice[1]^M
Hardware watchpoint 241: data.u.size8twice[1]^M
(gdb) PASS: gdb.base/watchpoint-unaligned.exp: watch data.u.size8twice[1]
continue^M
Continuing.^M
FAIL: gdb.base/watchpoint-unaligned.exp: continue (timeout)
FAIL: gdb.base/watchpoint-unaligned.exp: size8twice write
...
This happens as follows.
We start the exec and set an 8-byte hardware watchpoint on
data.u.size8twice[1] at address 0x440048:
...
(gdb) p sizeof (data.u.size8twice[1])
$1 = 8
(gdb) p &data.u.size8twice[1]
$2 = (uint64_t *) 0x440048 <data+16>
...
We continue execution, and a 16-byte write at address 0x440040 triggers the
hardware watchpoint:
...
4101c8: a9000801 stp x1, x2, [x0]
...
When checking whether a watchpoint has triggered in
aarch64_stopped_data_address, we check against address 0x440040 (passed in
parameter addr_trap). This behaviour is documented:
...
/* ADDR_TRAP reports the first address of the memory range
accessed by the CPU, regardless of what was the memory
range watched. ... */
...
and consequently the matching logic compares against an addr_watch_aligned:
...
&& addr_trap >= addr_watch_aligned
&& addr_trap < addr_watch + len)
...
However, the comparison fails:
...
(gdb) p /x addr_watch_aligned
$3 = 0x440048
(gdb) p addr_trap >= addr_watch_aligned
$4 = false
...
Consequently, aarch64_stopped_data_address returns false, and
stopped_by_watchpoint returns false, and watchpoints_triggered returns 0,
which make infrun think it's looking at a delayed hardware
breakpoint/watchpoint trap:
...
[infrun] handle_signal_stop: stop_pc=0x4101c8
[infrun] handle_signal_stop: delayed hardware breakpoint/watchpoint trap, ignoring
...
Infrun then ignores the trap and continues, but runs into the same situation
again and again, causing a hang which then causes the test timeout.
Fix this by allowing a match 8 bytes below addr_watch_aligned. This
introduces the possibility for false positives, so we only do this for regular
"value changed" watchpoints.
An earlier version of this patch worked by aligning addr_watch_aligned to 16
instead of 8:
...
- const CORE_ADDR addr_watch_aligned = align_down (state->dr_addr_wp[i], 8);
+ const CORE_ADDR addr_watch_aligned = align_down (state->dr_addr_wp[i], 16);
...
but while that fixed the test-case, it didn't fix the problem completely, so
extend the test-case to check more scenarios.
Tested on aarch64-linux.
Tested-By: Luis Machado <luis.machado@arm.com>
Approved-By: Luis Machado <luis.machado@arm.com>
PR tdep/29423
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29423
---
gdb/aarch64-nat.c | 17 +++-
gdb/testsuite/gdb.base/watchpoint-unaligned.c | 11 +--
.../gdb.base/watchpoint-unaligned.exp | 78 ++++++++++++-------
3 files changed, 68 insertions(+), 38 deletions(-)
diff --git a/gdb/aarch64-nat.c b/gdb/aarch64-nat.c
index 89d1ba6acc6..a173e4e18d5 100644
--- a/gdb/aarch64-nat.c
+++ b/gdb/aarch64-nat.c
@@ -269,7 +269,7 @@ aarch64_stopped_data_address (const struct aarch64_debug_reg_state *state,
= aarch64_watchpoint_length (state->dr_ctrl_wp[i]);
const CORE_ADDR addr_watch = state->dr_addr_wp[i] + offset;
const CORE_ADDR addr_watch_aligned
- = align_down (state->dr_addr_wp[i], 8);
+ = align_down (state->dr_addr_wp[i], AARCH64_HWP_MAX_LEN_PER_REG);
const CORE_ADDR addr_orig = state->dr_addr_orig_wp[i];
/* ADDR_TRAP reports the first address of the memory range
@@ -283,8 +283,19 @@ aarch64_stopped_data_address (const struct aarch64_debug_reg_state *state,
|---- range watched ----|
|----------- range accessed ------------|
- In this case, ADDR_TRAP will be 4. */
- if (!(addr_trap >= addr_watch_aligned
+ In this case, ADDR_TRAP will be 4.
+
+ The access size also can be larger than that of the watchpoint
+ itself. For instance, the access size of an stp instruction is 16.
+ So, if we use stp to store to address p, and set a watchpoint on
+ address p + 8, the reported ADDR_TRAP can be p + 8 (observed on
+ RK3399 SOC). But it also can be p (observed on M1 SOC). Checking
+ for this situation introduces the possibility of false positives,
+ so we only do this for hw_write watchpoints. */
+ const CORE_ADDR max_access_size = type == hw_write ? 16 : 8;
+ const CORE_ADDR addr_watch_base = addr_watch_aligned -
+ (max_access_size - AARCH64_HWP_MAX_LEN_PER_REG);
+ if (!(addr_trap >= addr_watch_base
&& addr_trap < addr_watch + len))
{
/* Not a match. */
diff --git a/gdb/testsuite/gdb.base/watchpoint-unaligned.c b/gdb/testsuite/gdb.base/watchpoint-unaligned.c
index b60025a64f4..d854c376be9 100644
--- a/gdb/testsuite/gdb.base/watchpoint-unaligned.c
+++ b/gdb/testsuite/gdb.base/watchpoint-unaligned.c
@@ -29,7 +29,7 @@ static volatile struct
uint32_t size4[2];
uint16_t size2[4];
uint8_t size1[8];
- uint64_t size8twice[2];
+ uint64_t size8twice[3];
}
u;
} data;
@@ -44,13 +44,14 @@ write_size8twice (void)
static const uint64_t second = 2;
#ifdef __aarch64__
+ volatile void *p = &data.u.size8twice[offset];
asm volatile ("stp %1, %2, [%0]"
: /* output */
- : "r" (data.u.size8twice), "r" (first), "r" (second) /* input */
+ : "r" (p), "r" (first), "r" (second) /* input */
: "memory" /* clobber */);
#else
- data.u.size8twice[0] = first;
- data.u.size8twice[1] = second;
+ data.u.size8twice[offset] = first;
+ data.u.size8twice[offset + 1] = second;
#endif
}
@@ -59,7 +60,7 @@ main (void)
{
volatile uint64_t local;
- assert (sizeof (data) == 8 + 2 * 8);
+ assert (sizeof (data) == 8 + 3 * 8);
write_size8twice ();
diff --git a/gdb/testsuite/gdb.base/watchpoint-unaligned.exp b/gdb/testsuite/gdb.base/watchpoint-unaligned.exp
index d31a9cdc2c8..c58704d033d 100644
--- a/gdb/testsuite/gdb.base/watchpoint-unaligned.exp
+++ b/gdb/testsuite/gdb.base/watchpoint-unaligned.exp
@@ -151,38 +151,56 @@ foreach wpcount {4 7} {
gdb_assert $got_hit $test
}
-if ![runto_main] {
- return -1
-}
-gdb_breakpoint [gdb_get_line_number "final_return"] "Breakpoint $decimal at $hex" "final_return"
-set test {watch data.u.size8twice[1]}
-set wpnum 0
-gdb_test_multiple $test $test {
- -re "Hardware watchpoint (\[0-9\]+): .*\r\n$gdb_prompt $" {
- set wpnum $expect_out(1,string)
- pass $gdb_test_name
- }
- -re "Watchpoint (\[0-9\]+): .*\r\n$gdb_prompt $" {
- if {[istarget "arm*-*-*"]} {
- untested $gdb_test_name
- } else {
- fail $gdb_test_name
- }
- }
-}
-if {$wpnum} {
- set test "continue"
- set got_hit 0
- gdb_test_multiple $test $test {
- -re "\r\nCould not insert hardware watchpoint .*\r\n$gdb_prompt $" {
+# We've got an array with 3 8-byte elements. Do a store of 16 bytes,
+# to:
+# - elements 0 and 1 (offset == 0), and
+# - elements 1 and 2 (offset == 1).
+# For each case, check setting a watchpoint at:
+# - the first written element (index == 0), and
+# - the second element (index == 1).
+foreach_with_prefix offset { 0 1 } {
+ foreach_with_prefix index { 0 1 } {
+
+ clean_restart $binfile
+
+ if ![runto_main] {
+ return -1
}
- -re "Hardware watchpoint $wpnum:.*New value = .*\r\n$gdb_prompt $" {
- set got_hit 1
- send_gdb "continue\n"
- exp_continue
+
+ gdb_test_no_output "set var offset = $offset"
+ gdb_breakpoint [gdb_get_line_number "final_return"] \
+ "Breakpoint $decimal at $hex" "final_return"
+ set watch_index [expr $offset + $index]
+ set test "watch data.u.size8twice\[$watch_index\]"
+ set wpnum 0
+ gdb_test_multiple $test $test {
+ -re "Hardware watchpoint (\[0-9\]+): .*\r\n$gdb_prompt $" {
+ set wpnum $expect_out(1,string)
+ pass $gdb_test_name
+ }
+ -re "Watchpoint (\[0-9\]+): .*\r\n$gdb_prompt $" {
+ if {[istarget "arm*-*-*"]} {
+ untested $gdb_test_name
+ } else {
+ fail $gdb_test_name
+ }
+ }
}
- -re " final_return .*\r\n$gdb_prompt $" {
+ if {$wpnum} {
+ set test "continue"
+ set got_hit 0
+ gdb_test_multiple $test $test {
+ -re "\r\nCould not insert hardware watchpoint .*\r\n$gdb_prompt $" {
+ }
+ -re "Hardware watchpoint $wpnum:.*New value = .*\r\n$gdb_prompt $" {
+ set got_hit 1
+ send_gdb "continue\n"
+ exp_continue
+ }
+ -re " final_return .*\r\n$gdb_prompt $" {
+ }
+ }
+ gdb_assert $got_hit "size8twice write"
}
}
- gdb_assert $got_hit "size8twice write"
}
--
2.35.3

View File

@ -0,0 +1,80 @@
From b8a8f319b30149f94823302d9120d83b9eee01a4 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Tue, 13 Feb 2024 09:10:54 +0100
Subject: [PATCH 23/48] [gdb/tdep] Fix reverse execution of LDR(immediate) T4
When running test-case gdb.reverse/func-map-to-same-line.exp on arm-linux with
target board unix/-mthumb, we run into:
...
(gdb) reverse-step
func2 () at func-map-to-same-line.c:26
26 {
(gdb) FAIL: gdb.reverse/func-map-to-same-line.exp: \
column_info_flag=column-info: step-test: reverse-step into func2
...
The FAIL is caused by incorrect recording of this insn:
...
4f6: f85d 7b04 ldr.w r7, [sp], #4
...
The insn updates the sp, but we don't record this:
...
$ gdb -q -batch func-map-to-same-line \
-ex "b *func2+8" \
-ex run \
-ex record \
-ex "set debug record 2" \
-ex stepi
Breakpoint 1 at 0x4f6: file func-map-to-same-line.c, line 27.
Breakpoint 1, 0xaaaaa4f6 in func2 () at func-map-to-same-line.c:27
27 } /* END FUNC2 */
Process record: arm_process_record addr = 0xaaaaa4f6
Process record: add register num = 15 to record list.
Process record: record_full_arch_list_add 0xabc6c460.
Process record: add register num = 7 to record list.
Process record: record_full_arch_list_add 0xabc3b868.
Process record: add register num = 25 to record list.
...
[ Note that sp is r13, and we see here only r15 (pc), r7, and r25 (ps). ]
The problem is that the specific insn, an LDR(immediate) T4, is not handled in
thumb2_record_ld_word.
Fix this by detecting the insn in thumb2_record_ld_word, and recording the
updated base register.
Tested on arm-linux.
Reported-By: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
Approved-By: Luis Machado <luis.machado@arm.com>
PR tdep/31278
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31278
---
gdb/arm-tdep.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 04392115848..3b1682a2aea 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -14156,6 +14156,14 @@ thumb2_record_ld_word (arm_insn_decode_record *thumb2_insn_r)
record_buf[1] = ARM_PS_REGNUM;
thumb2_insn_r->reg_rec_count = 2;
+ if ((thumb2_insn_r->arm_insn & 0xfff00900) == 0xf8500900)
+ {
+ /* Detected LDR(immediate), T4, with write-back bit set. Record Rn
+ update. */
+ record_buf[2] = bits (thumb2_insn_r->arm_insn, 16, 19);
+ thumb2_insn_r->reg_rec_count++;
+ }
+
REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
record_buf);
return ARM_RECORD_SUCCESS;
--
2.35.3

View File

@ -1,8 +1,7 @@
From e9faa078c28b14386609a12d307471cb142547d6 Mon Sep 17 00:00:00 2001
From 6de9111c512de99fd8cb3ea89f9890b1d72f6ef0 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Fri, 21 Apr 2023 09:12:35 +0200
Subject: [PATCH 2/5] [gdb/testsuite] Compile ada hello world for
skip_ada_tests
Subject: [PATCH] Compile ada hello world for skip_ada_tests
For openSUSE Leap 15.0 with gcc-PIE installed (which makes gcc create PIE
executables by default) we get:
@ -38,14 +37,14 @@ gdb/testsuite/ChangeLog:
(skip_ada_tests): Return 1 if !gdb_can_compile_ada.
---
gdb/testsuite/lib/ada.exp | 31 +++++++++++++++++++++++++++++++
gdb/testsuite/lib/gdb.exp | 6 ++++++
2 files changed, 37 insertions(+)
gdb/testsuite/lib/gdb.exp | 8 ++++++++
2 files changed, 39 insertions(+)
diff --git a/gdb/testsuite/lib/ada.exp b/gdb/testsuite/lib/ada.exp
index f5bf2dcbb71..48dcd00bbe3 100644
index 4bf1368f29f..7d8fbf01fbd 100644
--- a/gdb/testsuite/lib/ada.exp
+++ b/gdb/testsuite/lib/ada.exp
@@ -85,12 +85,43 @@ proc gdb_compile_ada_1 {source dest type options} {
@@ -90,12 +90,43 @@ proc gdb_compile_ada_1 {source dest type options} {
# compile was successful.
proc gdb_compile_ada {source dest type options} {
@ -60,7 +59,7 @@ index f5bf2dcbb71..48dcd00bbe3 100644
return $result
}
+gdb_caching_proc gdb_can_compile_ada {
+gdb_caching_proc gdb_can_compile_ada {} {
+ set name "hello"
+ set dir "[pwd]/tmp-ada-hello-[pid]"
+ set src "$dir/$name.adb"
@ -90,10 +89,10 @@ index f5bf2dcbb71..48dcd00bbe3 100644
# used a different naming convention from many of the other gdb tests,
# and this difference was preserved during the conversion to
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 31856fa3721..85c0bfb897f 100644
index 990d0c8a70f..6c1f59ef4a6 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -137,6 +137,7 @@ load_lib cache.exp
@@ -145,6 +145,7 @@ load_lib cache.exp
load_lib gdb-utils.exp
load_lib memory.exp
load_lib check-test-names.exp
@ -101,18 +100,22 @@ index 31856fa3721..85c0bfb897f 100644
# The path to the GDB binary to test.
global GDB
@@ -2450,6 +2451,11 @@ proc skip_fortran_tests {} {
# Return a 1 if I don't even want to try to test ada.
proc skip_ada_tests {} {
@@ -2538,6 +2539,13 @@ proc allow_ada_tests {} {
# Currently gdb_ada_compile doesn't support remote host.
return 0
}
+
+ if { [gdb_can_compile_ada] == 0 } {
+ global gdb_test_file_name
+ unsupported "$gdb_test_file_name"
+ return 1
+ return 0
+ }
return 0
+
return 1
}
base-commit: af4a87e2b3c2ac5acae1e6f4405fc59e1218de74
--
2.35.3

View File

@ -1,80 +0,0 @@
From f54470964a1781c0e5a92b5ff2f1979a79b4a4b1 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Mon, 24 Apr 2023 14:48:06 +0200
Subject: [PATCH 1/9] [gdb/testsuite] Add basic lmap for tcl < 8.6
With test-case gdb.dwarf2/dw2-abs-hi-pc.exp and tcl 8.5, I run into:
...
ERROR: tcl error sourcing gdb/testsuite/gdb.dwarf2/dw2-abs-hi-pc.exp.
ERROR: invalid command name "lmap"
while executing
"::gdb_tcl_unknown lmap i {dw2-abs-hi-pc.c dw2-abs-hi-pc-hello.c \
dw2-abs-hi-pc-world.c} { expr { "$srcdir/$subdir/$i" } }"
...
Fix this by adding basic lmap support for tcl version < 8.6.
Tested on x86_64-linux.
---
gdb/testsuite/gdb.testsuite/lmap.exp | 20 ++++++++++++++++++++
gdb/testsuite/lib/gdb.exp | 15 +++++++++++++++
2 files changed, 35 insertions(+)
create mode 100644 gdb/testsuite/gdb.testsuite/lmap.exp
diff --git a/gdb/testsuite/gdb.testsuite/lmap.exp b/gdb/testsuite/gdb.testsuite/lmap.exp
new file mode 100644
index 00000000000..501e18bdd92
--- /dev/null
+++ b/gdb/testsuite/gdb.testsuite/lmap.exp
@@ -0,0 +1,20 @@
+# Copyright 2023 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/>.
+
+set one 1
+set l1 { $one 2 }
+set res1 [lmap item $l1 {expr $item + 1}]
+gdb_assert { [lindex $res1 0] == 2 }
+gdb_assert { [lindex $res1 1] == 3 }
+gdb_assert { $item == 2 }
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index b6e30204371..0b8a15f61cb 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -1524,6 +1524,21 @@ if { [tcl_version_at_least 8 5] == 0 } {
}
}
+if { [tcl_version_at_least 8 6] == 0 } {
+ # lmap was added in tcl 8.6. Only add if missing.
+
+ # Note that we only implement the simple variant for now.
+ proc lmap { varname list body } {
+ set res {}
+ foreach val $list {
+ uplevel 1 "set $varname $val"
+ lappend res [uplevel 1 $body]
+ }
+
+ return $res
+ }
+}
+
# gdb_test_no_output [-prompt PROMPT_REGEXP] [-nopass] COMMAND [MESSAGE]
# Send a command to GDB and verify that this command generated no output.
#
base-commit: fdf0253385db9239c44ea5a4ec879eeeae12fca1
--
2.35.3

View File

@ -0,0 +1,128 @@
From 088088cf78b937cff973c95ec6da2d86ea173b48 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Sun, 24 Sep 2023 12:30:10 +0200
Subject: [PATCH 07/13] [gdb/testsuite] Add
gdb.dwarf2/backward-spec-inter-cu.exp
Add another regression test for PR symtab/30846.
Tested on x86_64-linux.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30846
---
.../gdb.dwarf2/backward-spec-inter-cu.exp | 103 ++++++++++++++++++
1 file changed, 103 insertions(+)
create mode 100644 gdb/testsuite/gdb.dwarf2/backward-spec-inter-cu.exp
diff --git a/gdb/testsuite/gdb.dwarf2/backward-spec-inter-cu.exp b/gdb/testsuite/gdb.dwarf2/backward-spec-inter-cu.exp
new file mode 100644
index 00000000000..59b3db50dbb
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/backward-spec-inter-cu.exp
@@ -0,0 +1,103 @@
+# Copyright 2023 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 the DWARF reader works with a a DW_AT_specification that
+# refers to an earlier DIE. Inter-cu variant of forward-spec.exp.
+
+load_lib dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+require dwarf2_support
+
+standard_testfile main.c -debug.S
+
+# Set up the DWARF for the test.
+set asm_file [standard_output_file $srcfile2]
+Dwarf::assemble $asm_file {
+ global srcfile
+
+ declare_labels spec
+
+ cu {} {
+ DW_TAG_compile_unit {
+ {DW_AT_language @DW_LANG_C_plus_plus}
+ } {
+ declare_labels myint
+
+ myint: DW_TAG_base_type {
+ {DW_AT_byte_size 4 DW_FORM_sdata}
+ {DW_AT_encoding @DW_ATE_signed}
+ {DW_AT_name myint}
+ }
+
+ DW_TAG_namespace {
+ {DW_AT_name ns}
+ } {
+ spec: DW_TAG_variable {
+ {DW_AT_name v}
+ {DW_AT_type :$myint}
+ {DW_AT_declaration 1 DW_FORM_flag_present}
+ }
+ }
+ }
+ }
+
+ cu {} {
+ DW_TAG_compile_unit {
+ {DW_AT_language @DW_LANG_C_plus_plus}
+ } {
+ # The new indexer has special code to compute the full
+ # name of an object that uses a specification that appears
+ # later in the DWARF.
+ DW_TAG_variable {
+ {DW_AT_specification %$spec}
+ {DW_AT_location {
+ DW_OP_const1u 23
+ DW_OP_stack_value
+ } SPECIAL_expr}
+ }
+ }
+ }
+}
+
+if {[build_executable "failed to build executable" ${testfile} \
+ [list $srcfile $asm_file] {nodebug}]} {
+ return -1
+}
+
+set eol "\r\n"
+set ws "\[ \t\]"
+
+set worker_threads_list {}
+
+# Exercises the intra-shard case.
+lappend worker_threads_list 0
+
+# Might exercise the inter-shard case.
+lappend worker_threads_list default
+
+foreach_with_prefix worker_threads $worker_threads_list {
+
+ clean_restart
+
+ if { $worker_threads != "default" } {
+ gdb_test_no_output "maint set worker-threads $worker_threads"
+ }
+
+ gdb_load $binfile
+
+ gdb_test "maint print objfiles" "$eol$ws+qualified:$ws+ns::v$eol.*" \
+ "v has parent ns"
+}
--
2.35.3

View File

@ -0,0 +1,128 @@
From a022afb07305b50fd6372015bef6c51ae461c6a9 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Sun, 24 Sep 2023 12:33:59 +0200
Subject: [PATCH 06/13] [gdb/testsuite] Add
gdb.dwarf2/forward-spec-inter-cu.exp
Add a regression test for PR symtab/30846.
Tested on x86_64-linux.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30846
---
.../gdb.dwarf2/forward-spec-inter-cu.exp | 103 ++++++++++++++++++
1 file changed, 103 insertions(+)
create mode 100644 gdb/testsuite/gdb.dwarf2/forward-spec-inter-cu.exp
diff --git a/gdb/testsuite/gdb.dwarf2/forward-spec-inter-cu.exp b/gdb/testsuite/gdb.dwarf2/forward-spec-inter-cu.exp
new file mode 100644
index 00000000000..d8367b0a162
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/forward-spec-inter-cu.exp
@@ -0,0 +1,103 @@
+# Copyright 2023 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 the DWARF reader works with a a DW_AT_specification that
+# refers to a later DIE. Inter-cu variant of forward-spec.exp.
+
+load_lib dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+require dwarf2_support
+
+standard_testfile main.c -debug.S
+
+# Set up the DWARF for the test.
+set asm_file [standard_output_file $srcfile2]
+Dwarf::assemble $asm_file {
+ global srcfile
+
+ declare_labels spec
+
+ cu {} {
+ DW_TAG_compile_unit {
+ {DW_AT_language @DW_LANG_C_plus_plus}
+ } {
+ # The new indexer has special code to compute the full
+ # name of an object that uses a specification that appears
+ # later in the DWARF.
+ DW_TAG_variable {
+ {DW_AT_specification %$spec}
+ {DW_AT_location {
+ DW_OP_const1u 23
+ DW_OP_stack_value
+ } SPECIAL_expr}
+ }
+ }
+ }
+
+ cu {} {
+ DW_TAG_compile_unit {
+ {DW_AT_language @DW_LANG_C_plus_plus}
+ } {
+ declare_labels myint
+
+ myint: DW_TAG_base_type {
+ {DW_AT_byte_size 4 DW_FORM_sdata}
+ {DW_AT_encoding @DW_ATE_signed}
+ {DW_AT_name myint}
+ }
+
+ DW_TAG_namespace {
+ {DW_AT_name ns}
+ } {
+ spec: DW_TAG_variable {
+ {DW_AT_name v}
+ {DW_AT_type :$myint}
+ {DW_AT_declaration 1 DW_FORM_flag_present}
+ }
+ }
+ }
+ }
+}
+
+if {[build_executable "failed to build executable" ${testfile} \
+ [list $srcfile $asm_file] {nodebug}]} {
+ return -1
+}
+
+set eol "\r\n"
+set ws "\[ \t\]"
+
+set worker_threads_list {}
+
+# Exercises the intra-shard case.
+lappend worker_threads_list 0
+
+# Might exercise the inter-shard case.
+lappend worker_threads_list default
+
+foreach_with_prefix worker_threads $worker_threads_list {
+
+ clean_restart
+
+ if { $worker_threads != "default" } {
+ gdb_test_no_output "maint set worker-threads $worker_threads"
+ }
+
+ gdb_load $binfile
+
+ gdb_test "maint print objfiles" "$eol$ws+qualified:$ws+ns::v$eol.*" \
+ "v has parent ns"
+}
--
2.35.3

View File

@ -1,148 +0,0 @@
From f26e9f1ce8e47bca399116a99ffdbf0aff9f2080 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Mon, 12 Jun 2023 18:00:10 +0200
Subject: [PATCH 3/9] [gdb/testsuite] Add have_host_locale
With test-case gdb.tui/pr30056.exp, I run into:
...
sh: warning: setlocale: LC_ALL: cannot change locale (C.UTF-8)^M
...
and then subsequently into:
...
WARNING: timeout in accept_gdb_output
FAIL: gdb.tui/pr30056.exp: Control-C
...
This is on a CentOS 7 distro for powerpc64le.
Either it has no C.UTF-8 support, or it's not installed:
...
$ locale -a | grep ^C
C
$
...
Fix this by:
- adding a new proc have_host_locale, and
- using it in all test-cases using setenv LC_ALL.
Tested on powerpc64le-linux and x86_64-linux.
---
gdb/testsuite/gdb.ada/non-ascii-latin-1.exp | 1 +
gdb/testsuite/gdb.ada/non-ascii-latin-3.exp | 1 +
gdb/testsuite/gdb.ada/non-ascii-utf-8.exp | 1 +
gdb/testsuite/gdb.base/utf8-identifiers.exp | 2 ++
gdb/testsuite/gdb.rust/unicode.exp | 1 +
gdb/testsuite/lib/gdb.exp | 36 +++++++++++++++++++++
6 files changed, 42 insertions(+)
diff --git a/gdb/testsuite/gdb.ada/non-ascii-latin-1.exp b/gdb/testsuite/gdb.ada/non-ascii-latin-1.exp
index ad4ccde625b..472e049737b 100644
--- a/gdb/testsuite/gdb.ada/non-ascii-latin-1.exp
+++ b/gdb/testsuite/gdb.ada/non-ascii-latin-1.exp
@@ -18,6 +18,7 @@
load_lib "ada.exp"
if { [skip_ada_tests] } { return -1 }
+if { ![have_host_locale C.UTF-8] } { return -1 }
# Enable basic use of UTF-8. LC_ALL gets reset for each testfile. We
# want this despite the program itself using Latin-1, as this test is
diff --git a/gdb/testsuite/gdb.ada/non-ascii-latin-3.exp b/gdb/testsuite/gdb.ada/non-ascii-latin-3.exp
index f2bdd99d243..6f826427ad3 100644
--- a/gdb/testsuite/gdb.ada/non-ascii-latin-3.exp
+++ b/gdb/testsuite/gdb.ada/non-ascii-latin-3.exp
@@ -18,6 +18,7 @@
load_lib "ada.exp"
if { [skip_ada_tests] } { return -1 }
+if { ![have_host_locale C.UTF-8] } { return -1 }
# Enable basic use of UTF-8. LC_ALL gets reset for each testfile. We
# want this despite the program itself using Latin-1, as this test is
diff --git a/gdb/testsuite/gdb.ada/non-ascii-utf-8.exp b/gdb/testsuite/gdb.ada/non-ascii-utf-8.exp
index d3c1ac4d0cf..7dcfb71bbb3 100644
--- a/gdb/testsuite/gdb.ada/non-ascii-utf-8.exp
+++ b/gdb/testsuite/gdb.ada/non-ascii-utf-8.exp
@@ -18,6 +18,7 @@
load_lib "ada.exp"
if { [skip_ada_tests] } { return -1 }
+if { ![have_host_locale C.UTF-8] } { return -1 }
# Enable basic use of UTF-8. LC_ALL gets reset for each testfile.
setenv LC_ALL C.UTF-8
diff --git a/gdb/testsuite/gdb.base/utf8-identifiers.exp b/gdb/testsuite/gdb.base/utf8-identifiers.exp
index a6ef80fb0bd..7babe237dfb 100644
--- a/gdb/testsuite/gdb.base/utf8-identifiers.exp
+++ b/gdb/testsuite/gdb.base/utf8-identifiers.exp
@@ -21,6 +21,8 @@
load_lib completion-support.exp
+if { ![have_host_locale C.UTF-8] } { return -1 }
+
standard_testfile
# Enable basic use of UTF-8. LC_ALL gets reset for each testfile.
diff --git a/gdb/testsuite/gdb.rust/unicode.exp b/gdb/testsuite/gdb.rust/unicode.exp
index 63ed8d1250c..185eae008f6 100644
--- a/gdb/testsuite/gdb.rust/unicode.exp
+++ b/gdb/testsuite/gdb.rust/unicode.exp
@@ -19,6 +19,7 @@ load_lib rust-support.exp
if {[skip_rust_tests]} {
return
}
+if { ![have_host_locale C.UTF-8] } { return }
# Non-ASCII identifiers were allowed starting in 1.53.
set v [split [rust_compiler_version] .]
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 0b8a15f61cb..cd043ce3436 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -9452,5 +9452,41 @@ proc have_syscall { name } {
return [gdb_can_simple_compile have_syscall_$name $src object]
}
+# Return a list of supported host locales.
+
+gdb_caching_proc host_locales {
+ set result [remote_exec host "locale -a"]
+ set status [lindex $result 0]
+ set output [lindex $result 1]
+
+ if { $status != 0 } {
+ return {}
+ }
+
+ # Split into list.
+ set output [string trim $output]
+ set l [split $output \n]
+
+ # Trim items.
+ set l [lmap v $l { string trim $v }]
+
+ # Normalize items to lower-case.
+ set l [lmap v $l { string tolower $v }]
+
+ return $l
+}
+
+# Return 1 if host locale LOCALE is supported.
+
+proc have_host_locale { locale } {
+ # Normalize to lower-case.
+ set locale [string tolower $locale]
+ # Normalize to without dash.
+ set locale [string map { "-" "" } $locale]
+
+ set idx [lsearch [host_locales] $locale]
+ return [expr $idx != -1]
+}
+
# Always load compatibility stuff.
load_lib future.exp
--
2.35.3

View File

@ -1,108 +0,0 @@
From 0b29bc75761b11387f89912ce827311b8eac18a6 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Sun, 1 Oct 2023 15:10:32 +0200
Subject: [PATCH 04/12] [gdb/testsuite] Add KFAIL for PR ada/30908
With gcc 13.2.1, I run into a cluster of fails:
...
FAIL: gdb.ada/str_binop_equal.exp: print my_str = "ABCD"
FAIL: gdb.ada/widewide.exp: print my_wws = " helo"
FAIL: gdb.ada/widewide.exp: print my_ws = "wide"
...
The problem is that the debug info contains information about function
ada.strings.maps."=", and gdb uses it to implement the comparison.
The function is supposed to compare two char sets, not strings, so gdb
shouldn't use it. This is PR ada/30908.
I don't see the same problem with gcc 7.5.0, because the exec doesn't contain
the debug info for the function, because the corresponding object is not
linked in. Adter adding "with Ada.Strings.Maps; use Ada.Strings.Maps;" to
gdb.ada/widewide/foo.adb I run into the same problem with gcc 7.5.0.
Add KFAILs for the PR.
Tested on x86_64-linux:
- openSUSE Leap 15.4 (using gcc 7.5.0), and
- openSUSE Tumbleweed (using gcc 13.2.1).
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30908
---
gdb/testsuite/gdb.ada/str_binop_equal.exp | 20 ++++++++++++++--
gdb/testsuite/gdb.ada/widewide.exp | 28 +++++++++++++++++++++--
2 files changed, 44 insertions(+), 4 deletions(-)
diff --git a/gdb/testsuite/gdb.ada/str_binop_equal.exp b/gdb/testsuite/gdb.ada/str_binop_equal.exp
index 5eb531c1453..2c1b8414c5c 100644
--- a/gdb/testsuite/gdb.ada/str_binop_equal.exp
+++ b/gdb/testsuite/gdb.ada/str_binop_equal.exp
@@ -31,8 +31,24 @@ runto "foo_p211_061.adb:$bp_location"
gdb_test "print my_str = my_str" \
" = true"
-gdb_test "print my_str = \"ABCD\"" \
- " = true"
+set kfail_re \
+ [multi_line \
+ [string_to_regexp {Symbol: ada.strings.maps."="}] \
+ ".*" \
+ "\\$$decimal = false"]
+
+gdb_test_no_output "set debug expr 1"
+
+gdb_test_multiple {print my_str = "ABCD"} "" {
+ -re -wrap " = true" {
+ pass $gdb_test_name
+ }
+ -re -wrap $kfail_re {
+ kfail ada/30908 $gdb_test_name
+ }
+}
+
+gdb_test "set debug expr 0"
gdb_test "print my_str = \"EFGH\"" \
" = false"
diff --git a/gdb/testsuite/gdb.ada/widewide.exp b/gdb/testsuite/gdb.ada/widewide.exp
index 5de5d52b8cb..b91b6bc746b 100644
--- a/gdb/testsuite/gdb.ada/widewide.exp
+++ b/gdb/testsuite/gdb.ada/widewide.exp
@@ -42,9 +42,33 @@ gdb_test "print my_wws(1)" "= 32 ' '"
gdb_test "print my_wws(2)" "= 104 'h'"
-gdb_test "print my_wws = \" helo\"" " = true"
+set kfail_re \
+ [multi_line \
+ [string_to_regexp {Symbol: ada.strings.maps."="}] \
+ ".*" \
+ "\\$$decimal = false"]
+
+gdb_test_no_output "set debug expr 1"
+
+gdb_test_multiple {print my_wws = " helo"} "" {
+ -re -wrap " = true" {
+ pass $gdb_test_name
+ }
+ -re -wrap $kfail_re {
+ kfail ada/30908 $gdb_test_name
+ }
+}
+gdb_test_multiple {print my_ws = "wide"} "" {
+ -re -wrap " = true" {
+ pass $gdb_test_name
+ }
+ -re -wrap $kfail_re {
+ kfail ada/30908 $gdb_test_name
+ }
+}
+
+gdb_test "set debug expr 0"
-gdb_test "print my_ws = \"wide\"" " = true"
gdb_test "print my_ws = \"nope\"" " = false"
gdb_test "print \"x\" & my_ws & \"y\"" " = \"xwidey\""
--
2.35.3

View File

@ -0,0 +1,51 @@
From 4e9077b7e451bd87e48e9868519079a5a7070106 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Tue, 2 Apr 2024 16:22:46 +0200
Subject: [PATCH 29/48] [gdb/testsuite] Add missing include in
gdb.base/ctf-ptype.c
On fedora rawhide, when running test-case gdb.base/ctf-ptype.exp, I get:
...
gdb compile failed, ctf-ptype.c: In function 'main':
ctf-ptype.c:242:29: error: implicit declaration of function 'malloc' \
[-Wimplicit-function-declaration]
242 | v_char_pointer = (char *) malloc (1);
| ^~~~~~
ctf-ptype.c:1:1: note: include '<stdlib.h>' or provide a declaration of 'malloc'
+++ |+#include <stdlib.h>
1 | /* This test program is part of GDB, the GNU debugger.
...
Fix this by adding the missing include.
Tested on aarch64-linux.
---
gdb/testsuite/gdb.base/ctf-ptype.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/gdb/testsuite/gdb.base/ctf-ptype.c b/gdb/testsuite/gdb.base/ctf-ptype.c
index cc4e98a234f..0cea44701b9 100644
--- a/gdb/testsuite/gdb.base/ctf-ptype.c
+++ b/gdb/testsuite/gdb.base/ctf-ptype.c
@@ -24,6 +24,8 @@
* First the basic C types.
*/
+#include <stdlib.h>
+
#if !defined (__STDC__) && !defined (_AIX)
#define signed /**/
#endif
@@ -234,9 +236,6 @@ func_type v_func_type;
int main ()
{
- /* Ensure that malloc is a pointer type; avoid use of "void" and any include files. */
-/* extern char *malloc();*/
-
/* Some of the tests in ptype.exp require invoking malloc, so make
sure it is linked in to this program. */
v_char_pointer = (char *) malloc (1);
--
2.35.3

View File

@ -0,0 +1,47 @@
From a2889f1e3f71589fee9454c0aa772ce1bc540db3 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 28 Mar 2024 06:51:59 +0100
Subject: [PATCH 35/48] [gdb/testsuite] Add missing include in
gdb.base/rtld-step.exp
On fedora rawhide, with test-case gdb.base/rtld-step.exp I get:
...
static-pie-static-libc.c: In function '_start':^M
static-pie-static-libc.c:1:22: error: \
implicit declaration of function '_exit' [-Wimplicit-function-declaration]^M
1 | void _start (void) { _exit (0); }^M
| ^~~~~^M
compiler exited with status 1
...
UNTESTED: gdb.base/rtld-step.exp: failed to compile \
(-static-pie not supported or static libc missing)
...
Fix this by adding the missing include.
Tested on aarch64-linux.
Approved-by: Kevin Buettner <kevinb@redhat.com>
---
gdb/testsuite/gdb.base/rtld-step.exp | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/gdb/testsuite/gdb.base/rtld-step.exp b/gdb/testsuite/gdb.base/rtld-step.exp
index 9a6c76d191a..bd3f89769b8 100644
--- a/gdb/testsuite/gdb.base/rtld-step.exp
+++ b/gdb/testsuite/gdb.base/rtld-step.exp
@@ -86,7 +86,10 @@ set rtld_flags [list debug additional_flags=[list -static-pie -fPIE \
-nostdlib -static -lc]]
if { ![gdb_can_simple_compile static-pie-static-libc \
- "void _start (void) { _exit (0); }" \
+ {
+ #include <unistd.h>
+ void _start (void) { _exit (0); }
+ } \
executable $rtld_flags] } {
set reason "-static-pie not supported or static libc missing"
untested "failed to compile ($reason)"
--
2.35.3

View File

@ -0,0 +1,60 @@
From 4a08080ba59f4f66bf062a9015f9e51c765b05b5 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Fri, 29 Mar 2024 07:47:30 +0100
Subject: [PATCH 31/48] [gdb/testsuite] Add missing includes in
gdb.trace/collection.c
On fedora rawhide, with test-case gdb.trace/collection.exp, I get:
...
gdb compile failed, collection.c: In function 'strings_test_func':
collection.c:227:13: error: implicit declaration of function 'malloc' \
[-Wimplicit-function-declaration]
227 | longloc = malloc(500);
| ^~~~~~
collection.c:1:1: note: \
include '<stdlib.h>' or provide a declaration of 'malloc'
+++ |+#include <stdlib.h>
1 | /* This testcase is part of GDB, the GNU debugger.
collection.c:228:3: error: implicit declaration of function 'strcpy' \
[-Wimplicit-function-declaration]
228 | strcpy(longloc, ... );
| ^~~~~~
collection.c:1:1: note: include '<string.h>' or provide a declaration of \
'strcpy'
+++ |+#include <string.h>
1 | /* This testcase is part of GDB, the GNU debugger.
collection.c:230:8: error: implicit declaration of function 'strlen' \
[-Wimplicit-function-declaration]
230 | i += strlen (locstr);
| ^~~~~~
collection.c:230:8: note: include '<string.h>' or provide a declaration of \
'strlen'
...
Fix this by adding the missing includes.
Tested on aarch64-linux.
Approved-By: John Baldwin <jhb@FreeBSD.org>
---
gdb/testsuite/gdb.trace/collection.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/gdb/testsuite/gdb.trace/collection.c b/gdb/testsuite/gdb.trace/collection.c
index 3b5484748af..4ef93a3fa33 100644
--- a/gdb/testsuite/gdb.trace/collection.c
+++ b/gdb/testsuite/gdb.trace/collection.c
@@ -19,6 +19,9 @@
* Test program for trace collection
*/
+#include <string.h>
+#include <stdlib.h>
+
/*
* Typedefs
*/
--
2.35.3

View File

@ -0,0 +1,167 @@
From fb2b155e33f5a21259c52685ee9b24f75ac66e75 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Wed, 20 Mar 2024 19:23:48 +0100
Subject: [PATCH 10/48] [gdb/testsuite] Add PR gdb/26967 KFAIL in two more
test-cases
On aarch64-linux (debian 12), when running test-case
gdb.base/longjmp-until-in-main.exp, I run into:
...
(gdb) until 33^M
warning: Breakpoint address adjusted from 0x70f727c678928489 to 0xfff727c678928489.^M
Warning:^M
Cannot insert breakpoint 0.^M
Cannot access memory at address 0xfff727c678928489^M
^M
0x0000fffff7e3a580 in siglongjmp () from /lib/aarch64-linux-gnu/libc.so.6^M
(gdb) FAIL: gdb.base/longjmp-until-in-main.exp: until $line, in main
...
This is PR gdb/26967: no longjmp probe is available:
...
(gdb) info probes stap libc ^longjmp$^M
No probes matched.^M
...
and glibc applies pointer mangling which makes it fairly difficult for gdb to
get the longjmp target.
There's a KFAIL for this in test-case gdb.base/longjmp.exp, added in commit
b5e7cd5cd3d ("[gdb/testsuite] Add KFAILs in gdb.base/longjmp.exp").
Factor out new proc have_longjmp_probe, and use it to add similar KFAIL in
this and one more test-case.
Tested on aarch64-linux.
Approved-By: Tom Tromey <tom@tromey.com>
---
.../gdb.base/longjmp-until-in-main.exp | 24 ++++++++++++++++---
gdb/testsuite/gdb.base/longjmp.exp | 11 +--------
.../premature-dummy-frame-removal.exp | 22 ++++++++++++++++-
gdb/testsuite/lib/gdb.exp | 19 +++++++++++++++
4 files changed, 62 insertions(+), 14 deletions(-)
diff --git a/gdb/testsuite/gdb.base/longjmp-until-in-main.exp b/gdb/testsuite/gdb.base/longjmp-until-in-main.exp
index c0635f23345..6167989319a 100644
--- a/gdb/testsuite/gdb.base/longjmp-until-in-main.exp
+++ b/gdb/testsuite/gdb.base/longjmp-until-in-main.exp
@@ -35,10 +35,28 @@ if {![runto_main]} {
return
}
+set have_longjmp_probe [have_longjmp_probe]
+
delete_breakpoints
set until_to_line [gdb_get_line_number "until to here"]
-gdb_test "until $until_to_line" \
- " until to here .*" \
- "until \$line, in main"
+set re_cannot_insert_bp \
+ [multi_line \
+ "Warning:" \
+ "Cannot insert breakpoint $::decimal\\." \
+ "Cannot access memory at address $::hex"]
+
+set test "until \$line, in main"
+gdb_test_multiple "until $until_to_line" $test {
+ -re -wrap "\r\n$re_cannot_insert_bp\r\n.*" {
+ if { $have_longjmp_probe } {
+ fail $gdb_test_name
+ } else {
+ kfail gdb/26967 $gdb_test_name
+ }
+ }
+ -re -wrap " until to here .*" {
+ pass $gdb_test_name
+ }
+}
diff --git a/gdb/testsuite/gdb.base/longjmp.exp b/gdb/testsuite/gdb.base/longjmp.exp
index f74891aa7ca..0420f4df675 100644
--- a/gdb/testsuite/gdb.base/longjmp.exp
+++ b/gdb/testsuite/gdb.base/longjmp.exp
@@ -62,16 +62,7 @@ proc do_test { with_probes } {
#
# We detect the different failure modes and kfail these.
- set have_longjmp_probe 0
- gdb_test_multiple "info probes stap libc ^longjmp$" "" {
- -re -wrap "No probes matched\\." {
- pass $gdb_test_name
- }
- -re -wrap "\r\nstap\[ \t\]+libc\[ \t\]+longjmp\[ \t\]+.*" {
- pass $gdb_test_name
- set have_longjmp_probe 1
- }
- }
+ set have_longjmp_probe [have_longjmp_probe]
if { $with_probes } {
if { !$have_longjmp_probe } {
diff --git a/gdb/testsuite/gdb.base/premature-dummy-frame-removal.exp b/gdb/testsuite/gdb.base/premature-dummy-frame-removal.exp
index fe906cefb14..6979345ee45 100644
--- a/gdb/testsuite/gdb.base/premature-dummy-frame-removal.exp
+++ b/gdb/testsuite/gdb.base/premature-dummy-frame-removal.exp
@@ -49,7 +49,27 @@ if {![runto_main]} {
set pyfile [gdb_remote_download host ${srcdir}/${subdir}/${testfile}.py]
gdb_test_no_output "source ${pyfile}" "load python file"
-gdb_test "p some_func ()" " = 0"
+set have_longjmp_probe [have_longjmp_probe]
+
+set re_cannot_insert_bp \
+ [multi_line \
+ "Warning:" \
+ "Cannot insert breakpoint $::decimal\\." \
+ "Cannot access memory at address $::hex"]
+
+gdb_test_multiple "p some_func ()" "" {
+ -re -wrap "\r\n$re_cannot_insert_bp\r\n.*" {
+ if { $have_longjmp_probe } {
+ fail $gdb_test_name
+ } else {
+ kfail gdb/26967 $gdb_test_name
+ return 0
+ }
+ }
+ -re -wrap " = 0" {
+ pass $gdb_test_name
+ }
+}
# When frame debugging is turned on, this test has (previously)
# revealed some crashes due to the Python frame unwinder trying to
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 21967550cf6..70c2db4ac84 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -4615,6 +4615,25 @@ proc skip_libstdcxx_probe_tests {} {
return [skip_libstdcxx_probe_tests_prompt "$gdb_prompt $"]
}
+# Return 1 if libc supports the longjmp probe. Note that we're not using
+# gdb_caching_proc because the probe may have been disabled.
+
+proc have_longjmp_probe {} {
+ set have_probe -1
+ gdb_test_multiple "info probes stap libc ^longjmp$" "" {
+ -re -wrap "No probes matched\\." {
+ set have_probe 0
+ }
+ -re -wrap "\r\nstap\[ \t\]+libc\[ \t\]+longjmp\[ \t\]+.*" {
+ set have_probe 1
+ }
+ }
+ if { $have_probe == -1 } {
+ error "failed to get libc longjmp probe status"
+ }
+ return $have_probe
+}
+
# Helper for gdb_is_target_* procs. TARGET_NAME is the name of the target
# we're looking for (used to build the test name). TARGET_STACK_REGEXP
# is a regexp that will match the output of "maint print target-stack" if
--
2.35.3

View File

@ -1,49 +0,0 @@
From 028d19e262b4086bc266b2657edd566bb4757927 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Mon, 13 Nov 2023 11:33:23 +0100
Subject: [PATCH 5/6] [gdb/testsuite] Add wait_for_msg arg to Term::resize fix
From commit deb1ba4e38b ("[gdb/tui] Fix TUI resizing for TERM=ansi").
Required for "[gdb/tui] Fix resizing of terminal to 1 or 2 lines".
---
gdb/testsuite/lib/tuiterm.exp | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/gdb/testsuite/lib/tuiterm.exp b/gdb/testsuite/lib/tuiterm.exp
index 591c4ca9c4c..eaac09581e9 100644
--- a/gdb/testsuite/lib/tuiterm.exp
+++ b/gdb/testsuite/lib/tuiterm.exp
@@ -1066,7 +1066,7 @@ namespace eval Term {
}
}
- proc resize {rows cols} {
+ proc resize {rows cols {wait_for_msg 1}} {
variable _rows
variable _cols
variable _resize_count
@@ -1080,14 +1080,18 @@ namespace eval Term {
# Due to the strange column resizing behavior, and because we
# don't care about this intermediate resize, we don't check
# the size here.
- wait_for "@@ resize done $_resize_count"
+ if { $wait_for_msg } {
+ wait_for "@@ resize done $_resize_count"
+ }
incr _resize_count
# Somehow the number of columns transmitted to gdb is one less
# than what we request from expect. We hide this weird
# details from the caller.
_do_resize $_rows $cols
stty columns [expr {$_cols + 1}] < $::gdb_tty_name
- wait_for "@@ resize done $_resize_count, size = ${_cols}x${rows}"
+ if { $wait_for_msg } {
+ wait_for "@@ resize done $_resize_count, size = ${_cols}x${rows}"
+ }
incr _resize_count
}
}
--
2.35.3

View File

@ -1,57 +0,0 @@
From 835a10f8541c7c4150098c82e097c4f606475cfa Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Mon, 20 Feb 2023 11:16:02 +0100
Subject: [PATCH] [gdb/testsuite] Add xfail case in
gdb.python/py-record-btrace.exp
I came across:
...
gdb) PASS: gdb.python/py-record-btrace.exp: prepare record: stepi 100
python insn = r.instruction_history^M
warning: Non-contiguous trace at instruction 1 (offset = 0x3e10).^M
(gdb) FAIL: gdb.python/py-record-btrace.exp: prepare record: python insn = r.i\
nstruction_history
...
I'm assuming it's the same root cause as for the already present XFAIL.
Fix this by recognizing above warning in the xfail regexp.
Tested on x86_64-linux, although sofar I was not able to trigger the warning
again.
Approved-By: Markus T. Metzger <markus.t.metzger@intel.com>
---
gdb/testsuite/gdb.python/py-record-btrace.exp | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/gdb/testsuite/gdb.python/py-record-btrace.exp b/gdb/testsuite/gdb.python/py-record-btrace.exp
index ca8740bc967..a930d17264d 100644
--- a/gdb/testsuite/gdb.python/py-record-btrace.exp
+++ b/gdb/testsuite/gdb.python/py-record-btrace.exp
@@ -86,6 +86,11 @@ with_test_prefix "prepare record" {
"warning: Decode error \\($nonl_re*\\) at instruction $decimal" \
"\\(offset = $hex, pc = $hex\\):" \
"$nonl_re*\\."]]
+ set xfail_re_2 \
+ [join \
+ [list \
+ "warning: Non-contiguous trace at instruction $decimal" \
+ "\\(offset = $hex\\)\\."]]
set got_xfail 0
set cmd "python insn = r.instruction_history"
@@ -93,7 +98,7 @@ with_test_prefix "prepare record" {
-re "^[string_to_regexp $cmd]\r\n$::gdb_prompt $" {
pass $gdb_test_name
}
- -re -wrap "$xfail_re" {
+ -re -wrap "($xfail_re|$xfail_re_2)" {
if { $have_xfail } {
xfail $gdb_test_name
set got_xfail 1
base-commit: f168a48adf97a36c88c65a075b42e6b7083063df
--
2.35.3

View File

@ -1,65 +0,0 @@
From ebceffa1196651683a7a6d31abb4b3b5adc6c168 Mon Sep 17 00:00:00 2001
From: Simon Marchi <simon.marchi@efficios.com>
Date: Thu, 7 Sep 2023 21:53:55 -0400
Subject: [PATCH 12/12] gdb/testsuite: add xfail for gdb/29965 in
gdb.threads/process-exit-status-is-leader-exit-status.exp
Bug 29965 shows on a Linux kernel >= 6.1, that test fails consistently
with:
FAIL: gdb.threads/process-exit-status-is-leader-exit-status.exp: iteration=0: continue (the program exited)
...
FAIL: gdb.threads/process-exit-status-is-leader-exit-status.exp: iteration=9: continue (the program exited)
This is due to a change in Linux kernel behavior [1] that affects
exactly what this test tests. That is, if multiple threads (including
the leader) call SYS_exit, the exit status of the process should be the
exit status of the leader. After that change in the kernel, it is no
longer the case.
Add an xfail in the test, based on the Linux kernel version. The goal
is that if a regression is introduced in GDB regarding this feature, it
should be caught if running on an older kernel where the behavior was
consistent.
[1] https://bugzilla.suse.com/show_bug.cgi?id=1206926
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29965
Change-Id: If6ab7171c92bfc1a3b961c7179e26611773969eb
Approved-By: Tom de Vries <tdevries@suse.de>
---
...cess-exit-status-is-leader-exit-status.exp | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/gdb/testsuite/gdb.threads/process-exit-status-is-leader-exit-status.exp b/gdb/testsuite/gdb.threads/process-exit-status-is-leader-exit-status.exp
index f64d6a73dea..e470fe29110 100644
--- a/gdb/testsuite/gdb.threads/process-exit-status-is-leader-exit-status.exp
+++ b/gdb/testsuite/gdb.threads/process-exit-status-is-leader-exit-status.exp
@@ -41,6 +41,23 @@ for {set iteration 0} {$iteration < 10} {incr iteration} {
return
}
- gdb_test "continue" "\\\[Inferior 1 \\(.*\\) exited with code 01\\\]"
+ gdb_test_multiple "continue" "" {
+ -re -wrap "\\\[Inferior 1 \\(.*\\) exited with code 01\\\]" {
+ pass $gdb_test_name
+ }
+
+ -re -wrap "\\\[Inferior 1 \\(.*\\) exited with code $::decimal\\\]" {
+ set lkv [linux_kernel_version]
+
+ if { [llength $lkv] != 0 } {
+ if { [version_compare {6 1 0} <= $lkv] } {
+ xfail "$gdb_test_name (PR 29965)"
+ return
+ }
+ }
+
+ fail $gdb_test_name
+ }
+ }
}
}
--
2.35.3

View File

@ -1,154 +0,0 @@
From 090d15fb9c7f7a48210783bddcf1d620bce6bf2a Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Fri, 21 Apr 2023 17:57:05 +0200
Subject: [PATCH 3/5] [gdb/testsuite] Add xfail in gdb.arch/i386-pkru.exp
On a x86_64-linux machine with pkru register, I run into:
...
(gdb) PASS: gdb.arch/i386-pkru.exp: set pkru value
info register pkru^M
pkru 0x12345678 305419896^M
(gdb) FAIL: gdb.arch/i386-pkru.exp: read value after setting value
...
This is a regression due to kernel commit e84ba47e313d ("x86/fpu: Hook up PKRU
onto ptrace()"). This is fixed by recent kernel commit 4a804c4f8356
("x86/fpu: Allow PKRU to be (once again) written by ptrace.").
The regression occurs for kernel versions v5.14-rc1 (the first tag containing
the regression) up to but excluding v6.2-rc1 (the first tag containing the fix).
Fix this by adding an xfail for the appropriate kernel versions.
Tested on x86_64-linux.
PR testsuite/29790
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29790
---
gdb/testsuite/gdb.arch/i386-pkru.exp | 45 +++++++++++++++++++++++---
gdb/testsuite/lib/gdb-utils.exp | 48 ++++++++++++++++++++++++++++
2 files changed, 89 insertions(+), 4 deletions(-)
diff --git a/gdb/testsuite/gdb.arch/i386-pkru.exp b/gdb/testsuite/gdb.arch/i386-pkru.exp
index f5d74380a61..5d2b1a24a15 100644
--- a/gdb/testsuite/gdb.arch/i386-pkru.exp
+++ b/gdb/testsuite/gdb.arch/i386-pkru.exp
@@ -58,6 +58,26 @@ if { !$supports_pkru } {
return
}
+# Linux kernel versions 5.14.0 to 6.1.x contain a regression related to writing
+# the PKRU using ptrace, see commit 4a804c4f8356 ("x86/fpu: Allow PKRU to be
+# (once again) written by ptrace.").
+set have_xfail 0
+if { [istarget *-*-linux*] } {
+ set res [remote_exec target "uname -r"]
+ set status [lindex $res 0]
+ set output [lindex $res 1]
+
+ set re ^($decimal)\\.($decimal)\\.($decimal)
+ if { $status == 0
+ && [regexp $re $output dummy v1 v2 v3] == 1 } {
+ set v [list $v1 $v2 $v3]
+ set have_xfail \
+ [expr \
+ [version_compare [list 5 14 0] <= $v] \
+ && [version_compare $v < [list 6 2 0]]]
+ }
+}
+
# Test pkru register at startup
gdb_test "print /x \$pkru" "= $default_pkru_re" "pkru register"
@@ -65,11 +85,28 @@ gdb_test "print /x \$pkru" "= $default_pkru_re" "pkru register"
gdb_breakpoint [ gdb_get_line_number "break here 1" ]
gdb_continue_to_breakpoint "break here 1" ".*break here 1.*"
-gdb_test "info register pkru" ".*pkru.*0x12345678.*" "read pkru register"
-gdb_test "print /x \$pkru = 0x44444444" "= 0x44444444" "set pkru value"
-gdb_test "info register pkru" ".*pkru.*0x44444444.*" "read value after setting value"
+set val1 0x12345678
+gdb_test "info register pkru" ".*pkru.*$val1.*" "read pkru register"
+
+set val2 0x44444444
+gdb_test "print /x \$pkru = $val2" "= $val2" "set pkru value"
+
+set xval $val2
+gdb_test_multiple "info register pkru" "read value after setting value" {
+ -re -wrap ".*pkru.*$val2.*" {
+ pass $gdb_test_name
+ }
+ -re -wrap ".*pkru.*$val1.*" {
+ if { $have_xfail } {
+ xfail $gdb_test_name
+ } else {
+ fail $gdb_test_name
+ }
+ set xval $val1
+ }
+}
gdb_breakpoint [ gdb_get_line_number "break here 2" ]
gdb_continue_to_breakpoint "break here 2" ".*break here 2.*"
-gdb_test "print /x rd_value" "= 0x44444444" "variable after reading pkru"
+gdb_test "print /x rd_value" "= $xval" "variable after reading pkru"
diff --git a/gdb/testsuite/lib/gdb-utils.exp b/gdb/testsuite/lib/gdb-utils.exp
index 78724f8b622..2757050fdfd 100644
--- a/gdb/testsuite/lib/gdb-utils.exp
+++ b/gdb/testsuite/lib/gdb-utils.exp
@@ -100,3 +100,51 @@ proc gdb_get_bp_addr { num } {
}
return ""
}
+
+# Compare the version numbers in L1 to those in L2 using OP, and return
+# 1 if the comparison is true.
+
+proc version_compare { l1 op l2 } {
+ set len [llength $l1]
+ if { $len != [llength $l2] } {
+ error "l2 not the same length as l1"
+ }
+
+ switch -exact $op {
+ "==" -
+ "<" {}
+ "<=" { return [expr [version_compare $l1 < $l2] \
+ || [version_compare $l1 == $l2]]}
+ default { error "unsupported op: $op" }
+ }
+
+ # Handle ops < and ==.
+ set idx 0
+ foreach v1 $l1 {
+ set v2 [lindex $l2 $idx]
+ incr idx
+ set last [expr $len == $idx]
+
+ set cmp [expr $v1 $op $v2]
+ if { $op == "==" } {
+ if { $cmp } {
+ continue
+ } else {
+ return 0
+ }
+ } else {
+ # $op == "<".
+ if { $cmp } {
+ return 1
+ } else {
+ if { !$last && $v1 == $v2 } {
+ continue
+ }
+ return 0
+ }
+ }
+ }
+
+ return 1
+}
+
--
2.35.3

View File

@ -1,98 +0,0 @@
From 221ecdef7cc008b01832840d1fbd25d94f8abdd1 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Tue, 14 Feb 2023 13:15:49 +0100
Subject: [PATCH 04/11] [gdb/testsuite] Add xfail in
gdb.python/py-record-btrace.exp
There's a HW bug affecting Processor Trace on some Intel processors
(Ice Lake to Raptor Lake microarchitectures).
The bug was exposed by linux kernel commit 670638477aed
("perf/x86/intel/pt: Opportunistically use single range output mode"),
added in version v5.5.0, and was worked around by commit ce0d998be927
("perf/x86/intel/pt: Fix sampling using single range output") in version
6.1.0.
The bug manifests (on a Performance-core of an i7-1250U, an Alder Lake cpu) in
a single test-case:
...
(gdb) python insn = r.instruction_history^M
warning: Decode error (-20) at instruction 33 (offset = 0x3d6a, \
pc = 0x400501): compressed return without call.^M
(gdb) FAIL: gdb.python/py-record-btrace.exp: prepare record: \
python insn = r.instruction_history
...
Add a corresponding XFAIL.
Note that the i7-1250U has both Performance-cores and Efficient-cores, and on
an Efficient-Core the test-case runs without any problems, so if the testsuite
run is not pinned to a specific cpu, the test may either PASS or XFAIL.
Tested on x86_64-linux:
- openSUSE Leap 15.4 with linux kernel version 5.14.21
- openSUSE Tumbleweed with linux kernel version 6.1.8
PR testsuite/30075
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30075
---
gdb/testsuite/gdb.python/py-record-btrace.exp | 43 ++++++++++++++++++-
1 file changed, 42 insertions(+), 1 deletion(-)
diff --git a/gdb/testsuite/gdb.python/py-record-btrace.exp b/gdb/testsuite/gdb.python/py-record-btrace.exp
index 8204577b866..ca8740bc967 100644
--- a/gdb/testsuite/gdb.python/py-record-btrace.exp
+++ b/gdb/testsuite/gdb.python/py-record-btrace.exp
@@ -64,7 +64,48 @@ with_test_prefix "prepare record" {
gdb_test "python print(r.method)" "btrace"
gdb_test "python print(r.format)" "pt|bts"
gdb_test "stepi 100" ".*"
- gdb_test_no_output "python insn = r.instruction_history"
+
+ # There's a HW bug affecting Processor Trace on some Intel processors.
+ # The bug was exposed by linux kernel commit 670638477aed
+ # ("perf/x86/intel/pt: Opportunistically use single range output mode"),
+ # added in version v5.5.0, and was worked around by commit ce0d998be927
+ # ("perf/x86/intel/pt: Fix sampling using single range output") in version
+ # 6.1.0. Detect the kernel version range for which the problem may
+ # manifest.
+ set have_xfail 0
+ set v [linux_kernel_version]
+ if { $v != {} } {
+ set have_xfail \
+ [expr [version_compare [list 5 5 0] <= $v] \
+ && [version_compare $v < [list 6 1 0]]]
+ }
+ set nonl_re \[^\r\n\]
+ set xfail_re \
+ [join \
+ [list \
+ "warning: Decode error \\($nonl_re*\\) at instruction $decimal" \
+ "\\(offset = $hex, pc = $hex\\):" \
+ "$nonl_re*\\."]]
+
+ set got_xfail 0
+ set cmd "python insn = r.instruction_history"
+ gdb_test_multiple $cmd "" {
+ -re "^[string_to_regexp $cmd]\r\n$::gdb_prompt $" {
+ pass $gdb_test_name
+ }
+ -re -wrap "$xfail_re" {
+ if { $have_xfail } {
+ xfail $gdb_test_name
+ set got_xfail 1
+ } else {
+ fail $gdb_test_name
+ }
+ }
+ }
+ if { $got_xfail } {
+ return
+ }
+
gdb_test_no_output "python call = r.function_call_history"
gdb_test_no_output "python i = insn\[0\]"
gdb_test_no_output "python c = call\[0\]"
--
2.35.3

View File

@ -0,0 +1,39 @@
From dedb6d4ce0478d053b7e786d73f298c8e72f1f99 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 18 Jan 2024 11:14:19 +0100
Subject: [PATCH 44/48] [gdb/testsuite] Call ldd --version in
gdb.testsuite/dump-system-info.exp
Once in a while I'm looking at the gdb.log of an entire testsuite run, and I'm
trying to establish what glibc version is used. Sometimes this is possible,
sometimes not.
Make this easy by calling ldd --version in test-case
gdb.testsuite/dump-system-info.exp, which for instance on openSUSE Leap 15.4
gives:
...
$ ldd --version
ldd (GNU libc) 2.31
...
$
...
Tested on x86_64-linux.
Approved-By: Tom Tromey <tom@tromey.com>
---
gdb/testsuite/gdb.testsuite/dump-system-info.exp | 1 +
1 file changed, 1 insertion(+)
diff --git a/gdb/testsuite/gdb.testsuite/dump-system-info.exp b/gdb/testsuite/gdb.testsuite/dump-system-info.exp
index 1a28b29b1c7..e3eb9eee73a 100644
--- a/gdb/testsuite/gdb.testsuite/dump-system-info.exp
+++ b/gdb/testsuite/gdb.testsuite/dump-system-info.exp
@@ -36,3 +36,4 @@ proc dump_info {cmd {what ""}} {
dump_info "cat /proc/cpuinfo" "Cpuinfo"
dump_info "uname -a"
dump_info "lsb_release -a"
+dump_info "ldd --version"
--
2.35.3

View File

@ -1,39 +0,0 @@
From f3a7b8d3d63005e9e0b680688d0cde0e5d4e1de9 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Mon, 24 Apr 2023 14:48:06 +0200
Subject: [PATCH 7/9] [gdb/testsuite] Don't use string cat in
gdb.dwarf2/dw2-abs-hi-pc.exp
Test-case gdb.dwarf2/dw2-abs-hi-pc.exp uses string cat:
...
set sources [lmap i $sources { string cat "${srcdir}/${subdir}/" $i }]
...
but that's only supported starting tcl 8.6.
Fix this by using "expr" instead:
...
set sources [lmap i $sources { expr { "$srcdir/$subdir/$i" } }]
...
Tested on x86_64-linux.
---
gdb/testsuite/gdb.dwarf2/dw2-abs-hi-pc.exp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-abs-hi-pc.exp b/gdb/testsuite/gdb.dwarf2/dw2-abs-hi-pc.exp
index 397cb38ceef..6e4b570c86d 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-abs-hi-pc.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-abs-hi-pc.exp
@@ -26,7 +26,8 @@ set sources \
${testfile}.c \
${testfile}-hello.c \
${testfile}-world.c]
-set sources [lmap i $sources { string cat "${srcdir}/${subdir}/" $i }]
+set sources [lmap i $sources { expr { "$srcdir/$subdir/$i" } }]
+
lassign [function_range hello $sources] \
hello_start hello_len
lassign [function_range world $sources] \
--
2.35.3

View File

@ -0,0 +1,98 @@
From 2e5c943519de45144a880b8ce0d693dfd13f4650 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Sat, 4 May 2024 10:41:09 +0200
Subject: [PATCH 16/48] [gdb/testsuite] Factor out proc get_portnum
In gdbserver_start, we have some code that determines what port number to use:
...
# Port id -- either specified in baseboard file, or managed here.
if [target_info exists gdb,socketport] {
set portnum [target_info gdb,socketport]
} else {
# Bump the port number to avoid conflicts with hung ports.
incr portnum
}
...
Factor this out into a new proc get_portnum.
Tested on aarch64-linux.
Approved-By: Tom Tromey <tom@tromey.com>
---
gdb/testsuite/lib/gdbserver-support.exp | 40 ++++++++++++++++++-------
1 file changed, 29 insertions(+), 11 deletions(-)
diff --git a/gdb/testsuite/lib/gdbserver-support.exp b/gdb/testsuite/lib/gdbserver-support.exp
index 30d94fd7eb6..8aaca946b7d 100644
--- a/gdb/testsuite/lib/gdbserver-support.exp
+++ b/gdb/testsuite/lib/gdbserver-support.exp
@@ -129,8 +129,31 @@ proc gdb_target_cmd { args } {
return [expr $res == 0 ? 0 : 1]
}
-global portnum
-set portnum "2345"
+# Return a usable port number.
+
+proc get_portnum {} {
+ if { [target_info exists gdb,socketport] } {
+ # Hard-coded in target board.
+ return [target_info gdb,socketport]
+ }
+
+ # Not hard-coded in target board. Return increasing port numbers,
+ # starting at $initial_portnum, to avoid conflicts with hung ports.
+ set initial_portnum 2345
+
+ # Currently available port number.
+ global portnum
+
+ # Initialize, if necessary.
+ if { ![info exists portnum] } {
+ set portnum $initial_portnum
+ }
+
+ # Return currently available port number, and update it.
+ set res $portnum
+ incr portnum
+ return $res
+}
# Locate the gdbserver binary. Returns "" if gdbserver could not be found.
@@ -247,16 +270,10 @@ proc gdbserver_default_get_comm_port { port } {
# Returns the target protocol and socket to connect to.
proc gdbserver_start { options arguments } {
- global portnum
global GDB_TEST_SOCKETHOST
# Port id -- either specified in baseboard file, or managed here.
- if [target_info exists gdb,socketport] {
- set portnum [target_info gdb,socketport]
- } else {
- # Bump the port number to avoid conflicts with hung ports.
- incr portnum
- }
+ set portnum [get_portnum]
# Extract the local and remote host ids from the target board struct.
if { [info exists GDB_TEST_SOCKETHOST] } {
@@ -372,10 +389,11 @@ proc gdbserver_start { options arguments } {
-re "Listening on" { }
-re "Can't (bind address|listen on socket): Address already in use\\.\r\n" {
verbose -log "Port $portnum is already in use."
- if ![target_info exists gdb,socketport] {
+ set other_portnum [get_portnum]
+ if { $other_portnum != $portnum } {
# Bump the port number to avoid the conflict.
wait -i $expect_out(spawn_id)
- incr portnum
+ set portnum $other_portnum
continue
}
}
--
2.35.3

Some files were not shown because too many files have changed in this diff Show More