237 lines
7.1 KiB
Diff
237 lines
7.1 KiB
Diff
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
|
From: Fedora GDB patches <invalid@email.com>
|
|
Date: Fri, 27 Oct 2017 21:07:50 +0200
|
|
Subject: gdb-gnat-dwarf-crash-3of3.patch
|
|
|
|
;; Fix crash of -readnow /usr/lib/debug/usr/bin/gnatbind.debug (BZ 1069211).
|
|
;;=push+jan
|
|
|
|
http://sourceware.org/ml/gdb-patches/2014-02/msg00731.html
|
|
|
|
--6TrnltStXW4iwmi0
|
|
Content-Type: text/plain; charset=us-ascii
|
|
Content-Disposition: inline
|
|
|
|
Hi,
|
|
|
|
PR 16581:
|
|
GDB crash on inherit_abstract_dies infinite recursion
|
|
https://sourceware.org/bugzilla/show_bug.cgi?id=16581
|
|
|
|
fixed crash from an infinite recursion. But in rare cases the new code can
|
|
now gdb_assert() due to weird DWARF file.
|
|
|
|
I do not yet fully understand why the DWARF is as it is but just GDB should
|
|
never crash due to invalid DWARF anyway. The "invalid" DWARF I see only in
|
|
Fedora GCC build, not in FSF GCC build, more info at:
|
|
https://bugzilla.redhat.com/show_bug.cgi?id=1069382
|
|
http://people.redhat.com/jkratoch/gcc-debuginfo-4.8.2-7.fc20.x86_64-gnatbind.debug
|
|
|
|
Thanks,
|
|
Jan
|
|
|
|
--6TrnltStXW4iwmi0
|
|
Content-Type: text/plain; charset=us-ascii
|
|
Content-Disposition: inline; filename="complaint.patch"
|
|
|
|
gdb/
|
|
2014-02-24 Jan Kratochvil <jan.kratochvil@redhat.com>
|
|
|
|
* dwarf2read.c (process_die): Change gdb_assert to complaint.
|
|
|
|
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
|
|
--- a/gdb/dwarf2read.c
|
|
+++ b/gdb/dwarf2read.c
|
|
@@ -10499,6 +10499,13 @@ private:
|
|
static void
|
|
process_die (struct die_info *die, struct dwarf2_cu *cu)
|
|
{
|
|
+ if (die->in_process)
|
|
+ {
|
|
+ complaint (_("DIE at 0x%s attempted to be processed twice"),
|
|
+ sect_offset_str (die->sect_off));
|
|
+ return;
|
|
+ }
|
|
+
|
|
process_die_scope scope (die, cu);
|
|
|
|
switch (die->tag)
|
|
diff --git a/gdb/infrun.c b/gdb/infrun.c
|
|
--- a/gdb/infrun.c
|
|
+++ b/gdb/infrun.c
|
|
@@ -607,6 +607,13 @@ holding the child stopped. Try \"set detach-on-fork\" or \
|
|
target_pid_to_str (process_ptid));
|
|
}
|
|
|
|
+#ifdef NEED_DETACH_SIGSTOP
|
|
+ /* We should check PID_WAS_STOPPED and detach it stopped accordingly.
|
|
+ In this point of code it cannot be 1 as we would not get FORK
|
|
+ executed without CONTINUE first which resets PID_WAS_STOPPED.
|
|
+ We would have to first TARGET_STOP and WAITPID it as with running
|
|
+ inferior PTRACE_DETACH, SIGSTOP will ignore the signal. */
|
|
+#endif
|
|
target_detach (parent_inf, 0);
|
|
}
|
|
|
|
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
|
|
--- a/gdb/linux-nat.c
|
|
+++ b/gdb/linux-nat.c
|
|
@@ -191,6 +191,12 @@ struct linux_nat_target *linux_target;
|
|
/* Does the current host support PTRACE_GETREGSET? */
|
|
enum tribool have_ptrace_getregset = TRIBOOL_UNKNOWN;
|
|
|
|
+#ifdef NEED_DETACH_SIGSTOP
|
|
+/* PID of the inferior stopped by SIGSTOP before attaching (or zero). */
|
|
+static pid_t pid_was_stopped;
|
|
+
|
|
+#endif
|
|
+
|
|
/* The saved to_close method, inherited from inf-ptrace.c.
|
|
Called by our to_close. */
|
|
static void (*super_close) (struct target_ops *);
|
|
@@ -1027,6 +1033,9 @@ linux_nat_post_attach_wait (ptid_t ptid, int *signalled)
|
|
if (debug_linux_nat)
|
|
fprintf_unfiltered (gdb_stdlog,
|
|
"LNPAW: Attaching to a stopped process\n");
|
|
+#ifdef NEED_DETACH_SIGSTOP
|
|
+ pid_was_stopped = ptid.pid ();
|
|
+#endif
|
|
|
|
/* The process is definitely stopped. It is in a job control
|
|
stop, unless the kernel predates the TASK_STOPPED /
|
|
@@ -1359,6 +1368,25 @@ get_detach_signal (struct lwp_info *lp)
|
|
return gdb_signal_to_host (signo);
|
|
}
|
|
|
|
+#ifdef NEED_DETACH_SIGSTOP
|
|
+ /* Workaround RHEL-5 kernel which has unreliable PTRACE_DETACH, SIGSTOP (that
|
|
+ many TIDs are left unstopped). See RH Bug 496732. */
|
|
+ if (lp->ptid.pid () == pid_was_stopped)
|
|
+ {
|
|
+ int err;
|
|
+
|
|
+ errno = 0;
|
|
+ err = kill_lwp (lp->ptid.lwp (), SIGSTOP);
|
|
+ if (debug_linux_nat)
|
|
+ {
|
|
+ fprintf_unfiltered (gdb_stdlog,
|
|
+ "SC: lwp kill %d %s\n",
|
|
+ err,
|
|
+ errno ? safe_strerror (errno) : "ERRNO-OK");
|
|
+ }
|
|
+ }
|
|
+
|
|
+#endif
|
|
return 0;
|
|
}
|
|
|
|
@@ -1507,6 +1535,10 @@ linux_nat_target::detach (inferior *inf, int from_tty)
|
|
detach_one_lwp (main_lwp, &signo);
|
|
|
|
detach_success (inf);
|
|
+
|
|
+#ifdef NEED_DETACH_SIGSTOP
|
|
+ pid_was_stopped = 0;
|
|
+#endif
|
|
}
|
|
}
|
|
|
|
@@ -1765,6 +1797,16 @@ linux_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
|
|
return;
|
|
}
|
|
|
|
+#ifdef NEED_DETACH_SIGSTOP
|
|
+ /* At this point, we are going to resume the inferior and if we
|
|
+ have attached to a stopped process, we no longer should leave
|
|
+ it as stopped if the user detaches. PTID variable has PID set to LWP
|
|
+ while we need to check the real PID here. */
|
|
+
|
|
+ if (!step && lp && pid_was_stopped == lp->ptid.pid ())
|
|
+ pid_was_stopped = 0;
|
|
+
|
|
+#endif
|
|
if (resume_many)
|
|
iterate_over_lwps (ptid, linux_nat_resume_callback, lp);
|
|
|
|
@@ -3761,6 +3803,10 @@ linux_nat_target::mourn_inferior ()
|
|
|
|
/* Let the arch-specific native code know this process is gone. */
|
|
linux_target->low_forget_process (pid);
|
|
+#ifdef NEED_DETACH_SIGSTOP
|
|
+
|
|
+ pid_was_stopped = 0;
|
|
+#endif
|
|
}
|
|
|
|
/* Convert a native/host siginfo object, into/from the siginfo in the
|
|
diff --git a/gdb/testsuite/gdb.threads/attach-stopped.exp b/gdb/testsuite/gdb.threads/attach-stopped.exp
|
|
--- a/gdb/testsuite/gdb.threads/attach-stopped.exp
|
|
+++ b/gdb/testsuite/gdb.threads/attach-stopped.exp
|
|
@@ -56,7 +56,65 @@ proc corefunc { threadtype } {
|
|
gdb_reinitialize_dir $srcdir/$subdir
|
|
gdb_load ${binfile}
|
|
|
|
- # Verify that we can attach to the stopped process.
|
|
+ # Verify that we can attach to the process by first giving its
|
|
+ # executable name via the file command, and using attach with the
|
|
+ # process ID.
|
|
+
|
|
+ set test "$threadtype: set file, before attach1 to stopped process"
|
|
+ gdb_test_multiple "file $binfile" "$test" {
|
|
+ -re "Load new symbol table from.*y or n. $" {
|
|
+ gdb_test "y" "Reading symbols from $escapedbinfile\.\.\.*done." \
|
|
+ "$test (re-read)"
|
|
+ }
|
|
+ -re "Reading symbols from $escapedbinfile\.\.\.*done.*$gdb_prompt $" {
|
|
+ pass "$test"
|
|
+ }
|
|
+ }
|
|
+
|
|
+ set test "$threadtype: attach1 to stopped, after setting file"
|
|
+ gdb_test_multiple "attach $testpid" "$test" {
|
|
+ -re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*$gdb_prompt $" {
|
|
+ pass "$test"
|
|
+ }
|
|
+ }
|
|
+
|
|
+ # ".*sleep.*clone.*" would fail on s390x as bt stops at START_THREAD there.
|
|
+ if {[string equal $threadtype threaded]} {
|
|
+ gdb_test "thread apply all bt" ".*sleep.*start_thread.*" "$threadtype: attach1 to stopped bt"
|
|
+ } else {
|
|
+ gdb_test "bt" ".*sleep.*main.*" "$threadtype: attach1 to stopped bt"
|
|
+ }
|
|
+
|
|
+ # Exit and detach the process.
|
|
+
|
|
+ gdb_exit
|
|
+
|
|
+ # Avoid some race:
|
|
+ sleep 2
|
|
+
|
|
+ if [catch {open /proc/${testpid}/status r} fileid] {
|
|
+ set line2 "NOTFOUND"
|
|
+ } else {
|
|
+ gets $fileid line1;
|
|
+ gets $fileid line2;
|
|
+ close $fileid;
|
|
+ }
|
|
+
|
|
+ set test "$threadtype: attach1, exit leaves process stopped"
|
|
+ if {[string match "*(stopped)*" $line2]} {
|
|
+ pass $test
|
|
+ } else {
|
|
+ fail $test
|
|
+ }
|
|
+
|
|
+ # At this point, the process should still be stopped
|
|
+
|
|
+ gdb_start
|
|
+ gdb_reinitialize_dir $srcdir/$subdir
|
|
+ gdb_load ${binfile}
|
|
+
|
|
+ # Verify that we can attach to the process just by giving the
|
|
+ # process ID.
|
|
|
|
set test "$threadtype: attach2 to stopped, after setting file"
|
|
gdb_test_multiple "attach $testpid" "$test" {
|