* 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
318 lines
13 KiB
Diff
318 lines
13 KiB
Diff
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
|
|
|