Fix signals reported for faults on Solaris
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.
This commit is contained in:
parent
19d16d8789
commit
7a28970742
@ -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.
|
||||
|
38
gdb/procfs.c
38
gdb/procfs.c
@ -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"));
|
||||
|
Loading…
Reference in New Issue
Block a user