summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Syromyatnikov <evgsyr@gmail.com>2022-08-03 13:57:10 +0200
committerEugene Syromyatnikov <evgsyr@gmail.com>2022-08-09 10:34:31 +0200
commit8495c8b757c5ff66500fe09326a5ee1fc1aea26c (patch)
tree649574963e062553224dff87d0a610069c937ddb
parentfee0f9d880ab17a2e71424ed9f2c5bdf0cf9bd92 (diff)
downloadstrace-8495c8b757c5ff66500fe09326a5ee1fc1aea26c.tar.gz
printsiginfo: print si_addr_lsb for BUS_MCEERR_A[RO] signals
* configure.ac (AC_CHECK_MEMBERS): Add siginfo_t.si_addr_lsb check. * src/printsiginfo.c (print_si_info) [!BUS_OPFETCH && HAVE_SIGINFO_T_SI_ADDR_LSB] <case SIGBUS>: Print si_addr_lsb field is si_code is equal to BUS_MCEERR_AR or BUS_MCEERR_AO. * tests/ptrace.c: Add checks. * NEWS: Mention it.
-rw-r--r--NEWS1
-rw-r--r--configure.ac3
-rw-r--r--src/printsiginfo.c9
-rw-r--r--tests/ptrace.c48
4 files changed, 54 insertions, 7 deletions
diff --git a/NEWS b/NEWS
index bef4f5650..c59a53a4c 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,7 @@ Noteworthy changes in release ?.?? (????-??-??)
INET_DIAG_PROTOCOL, INET_DIAG_REQ_PROTOCOL, INET_DIAG_SHUTDOWN,
INET_DIAG_SK_BPF_STORAGES, INET_DIAG_SOCKOPT, and INET_DIAG_ULP_INFO
NETLINK_SOCK_DIAG netlink attributes.
+ * Enhanced siginfo_t decoding.
* Updated decoding of struct rtnl_link_stats64.
* Updated lists of DEVCONF_*, FAN_MARK_*, GPIO_V2_LINE_FLAG_*, IORING_*,
KEXEC_*, LANDLOCK_*, NET_IPV4_CONF_*, NLM_F_*, NT_*, PR_*, SECCOMP_*,
diff --git a/configure.ac b/configure.ac
index 51f27b186..30dab8eea 100644
--- a/configure.ac
+++ b/configure.ac
@@ -424,7 +424,8 @@ AC_CHECK_MEMBERS(m4_normalize([
siginfo_t.si_syscall,
siginfo_t.si_timerid,
siginfo_t.si_overrun,
- siginfo_t.si_pkey
+ siginfo_t.si_pkey,
+ siginfo_t.si_addr_lsb
]),,, [#include <signal.h>])
AC_CHECK_HEADERS(m4_normalize([
diff --git a/src/printsiginfo.c b/src/printsiginfo.c
index 083845ec1..c49bf0163 100644
--- a/src/printsiginfo.c
+++ b/src/printsiginfo.c
@@ -166,6 +166,15 @@ print_si_info(struct tcb *tcp, const siginfo_t *sip)
case SIGBUS:
tprint_struct_next();
PRINT_FIELD_PTR(*sip, si_addr);
+#if !defined(BUS_OPFETCH) && defined(HAVE_SIGINFO_T_SI_ADDR_LSB)
+ switch (sip->si_code) {
+ case BUS_MCEERR_AR:
+ case BUS_MCEERR_AO:
+ tprint_struct_next();
+ PRINT_FIELD_X(*sip, si_addr_lsb);
+ break;
+ }
+#endif /* !BUS_OPFETCH && HAVE_SIGINFO_T_SI_ADDR_LSB */
break;
case SIGSEGV:
tprint_struct_next();
diff --git a/tests/ptrace.c b/tests/ptrace.c
index 00d8807d9..c22403ec9 100644
--- a/tests/ptrace.c
+++ b/tests/ptrace.c
@@ -33,6 +33,12 @@
#undef XLAT_MACROS_ONLY
#include "xlat/audit_arch.h"
+struct valstraux {
+ int val;
+ const char *str;
+ const char *aux;
+};
+
static const char *errstr;
static long
@@ -1827,18 +1833,48 @@ main(void)
XLAT_ARGS(SIGFPE), XLAT_ARGS(FPE_INTDIV), XLAT_ARGS(ENOENT),
sip->si_addr, errstr);
+ /* SIGBUS */
+ struct valstraux bus_codes[] = {
+ { ARG_XLAT_KNOWN(0x1, "BUS_ADRALN") },
+ { ARG_XLAT_KNOWN(0x2, "BUS_ADRERR") },
+ { ARG_XLAT_KNOWN(0x3, "BUS_OBJERR") },
+#ifdef BUS_OPFETCH
+ { ARG_XLAT_KNOWN(0x4, "BUS_OPFETCH") },
+#else
+ { ARG_XLAT_KNOWN(0x4, "BUS_MCEERR_AR"),
+# ifdef HAVE_SIGINFO_T_SI_ADDR_LSB
+ ", si_addr_lsb=0xdead"
+# endif
+ },
+#endif
+ { ARG_XLAT_KNOWN(0x5, "BUS_MCEERR_AO"),
+# if !defined(BUS_OPFETCH) && defined(HAVE_SIGINFO_T_SI_ADDR_LSB)
+ ", si_addr_lsb=0xdead"
+# endif
+ },
+ { ARG_STR(0x6) },
+ { ARG_STR(0x499602d2) },
+ };
+
memset(sip, -1, sizeof(*sip));
sip->si_signo = SIGBUS;
sip->si_code = 1;
sip->si_errno = -2;
sip->si_addr = (void *) (unsigned long) 0xfacefeeddeadbeefULL;
+#ifdef HAVE_SIGINFO_T_SI_ADDR_LSB
+ sip->si_addr_lsb = 0xdead;
+#endif
+ for (size_t i = 0; i < ARRAY_SIZE(bus_codes); i++) {
+ sip->si_code = bus_codes[i].val;
- do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (uintptr_t) sip);
- printf("ptrace(" XLAT_FMT ", %d, %#lx, {si_signo=" XLAT_FMT_U
- ", si_code=" XLAT_FMT ", si_errno=%u, si_addr=%p}) = %s\n",
- XLAT_ARGS(PTRACE_SETSIGINFO), pid, bad_request,
- XLAT_ARGS(SIGBUS), XLAT_ARGS(BUS_ADRALN),
- sip->si_errno, sip->si_addr, errstr);
+ do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (uintptr_t) sip);
+ printf("ptrace(" XLAT_FMT ", %d, %#lx, {si_signo=" XLAT_FMT_U
+ ", si_code=%s, si_errno=%u, si_addr=%p%s}) = %s\n",
+ XLAT_ARGS(PTRACE_SETSIGINFO), pid, bad_request,
+ XLAT_ARGS(SIGBUS), bus_codes[i].str,
+ sip->si_errno, sip->si_addr, bus_codes[i].aux ?: "",
+ errstr);
+ }
memset(sip, -1, sizeof(*sip));
sip->si_signo = SIGPROF;