]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Fix signals reported for faults on Solaris
authorRainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
Thu, 12 Sep 2019 08:40:59 +0000 (10:40 +0200)
committerRainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
Thu, 12 Sep 2019 08:40:59 +0000 (10:40 +0200)
It's been a long-standing nuisance that gdb reported unaligned accesses
on Solaris/SPARC as SIGSEGV, contrary to the shells and truss which
correctly report SIGBUS instead.

I could trace this down to the fault handling code in procfs.c
(procfs_target::wait): when pr_why is set to PR_FAULTED, the current
code sets the signal based on the fault number.  For one, the code gets
this wrong for FLTACCESS (the unaligned access case) where it uses
SIGSEGV.  What's worse, it's completely unnecessary to make up the
signal number inside gdb.  Instead, it should just take what procfs
reports to avoid mismatches, which is what this patch does.  I've
completely removed the explicit handling of the various fault codes: for
one, the list has already been incomplete, lacking FLTCPCOVF which
existed since at least Solaris 8.  Besides, there's no reason to error
out on unknown fault codes: either the fault causes a signal which can
then be reported from procfs, or it doesn't (as for FLTPAGE) and no
reporting is necessary.

Tested on sparcv9-sun-solaris2.11 and x86_64-pc-solaris2.11.  Also
spot-checked manually for a couple of cases (unaligned access, division
by 0, NULL pointer dereference).

* procfs.c (procfs_target::wait) <PR_FAULTED>: Get signal from
prstatus.pr_lwp.pr_info instead of making it up.

gdb/ChangeLog
gdb/procfs.c

index 4c354700c4525c49becf1863522ca9c100495a33..6d5f19d04bbf9046c9df418c0824864da03f9d76 100644 (file)
@@ -1,3 +1,8 @@
+2019-09-12  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
+
+       * procfs.c (procfs_target::wait) <PR_FAULTED>: Get signal from
+       prstatus.pr_lwp.pr_info instead of making it up.
+
 2019-09-11  Christian Biesinger  <cbiesinger@google.com>
 
        * auto-load.c (auto_load_expand_dir_vars): Update.
index 5bc1c3b28a56419612049d1f57a6a5b684ec250d..848ac7d6e751281c7df12d8e73eca3c3567c16d8 100644 (file)
@@ -2476,40 +2476,12 @@ wait_again:
                wstat = (what << 8) | 0177;
                break;
              case PR_FAULTED:
-               switch (what) {
-               case FLTWATCH:
-                 wstat = (SIGTRAP << 8) | 0177;
-                 break;
-                 /* FIXME: use si_signo where possible.  */
-               case FLTPRIV:
-               case FLTILL:
-                 wstat = (SIGILL << 8) | 0177;
-                 break;
-               case FLTBPT:
-               case FLTTRACE:
-                 wstat = (SIGTRAP << 8) | 0177;
-                 break;
-               case FLTSTACK:
-               case FLTACCESS:
-               case FLTBOUNDS:
-                 wstat = (SIGSEGV << 8) | 0177;
-                 break;
-               case FLTIOVF:
-               case FLTIZDIV:
-               case FLTFPE:
-                 wstat = (SIGFPE << 8) | 0177;
-                 break;
-               case FLTPAGE:   /* Recoverable page fault */
-               default:        /* FIXME: use si_signo if possible for
-                                  fault.  */
-                 retval = ptid_t (-1);
-                 printf_filtered ("procfs:%d -- ", __LINE__);
-                 printf_filtered (_("child stopped for unknown reason:\n"));
-                 proc_prettyprint_why (why, what, 1);
-                 error (_("... giving up..."));
-                 break;
+               {
+                 int signo = pi->prstatus.pr_lwp.pr_info.si_signo;
+                 if (signo != 0)
+                   wstat = (signo << 8) | 0177;
                }
-               break;  /* case PR_FAULTED: */
+               break;
              default:  /* switch (why) unmatched */
                printf_filtered ("procfs:%d -- ", __LINE__);
                printf_filtered (_("child stopped for unknown reason:\n"));