From: Dmitry V. Levin Date: Fri, 27 Mar 2015 23:28:15 +0000 (+0000) Subject: signal.c: move siginfo_t parsers to a separate file X-Git-Tag: v4.11~536 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=537c964fe9ad96b5b4c779af7a53a2b0850ade4e;p=strace signal.c: move siginfo_t parsers to a separate file * printsiginfo.c: New file. * Makefile.am (strace_SOURCES): Add it. * defs.h (printsiginfo): Change second argument's type from int to bool. * signal.c: Stop defining siginfo_t related constants. Move inclusion of xlat/sig*_codes.h files to printsiginfo.c (printsigsource, printsigval, printsiginfo_at): Move to printsiginfo.c. (printsiginfo): Change second argument's type from int to bool, split, and move to printsiginfo.c. --- diff --git a/Makefile.am b/Makefile.am index c4c0138b..8193c9e1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -77,6 +77,7 @@ strace_SOURCES = \ personality.c \ prctl.c \ printmode.c \ + printsiginfo.c \ printstat.h \ process.c \ process_vm.c \ diff --git a/defs.h b/defs.h index 38bc015a..1d3d41d9 100644 --- a/defs.h +++ b/defs.h @@ -490,7 +490,7 @@ extern void printtv_bitness(struct tcb *, long, enum bitness_t, int); extern char *sprinttv(char *, struct tcb *, long, enum bitness_t, int special); extern void print_timespec(struct tcb *, long); extern void sprint_timespec(char *, struct tcb *, long); -extern void printsiginfo(const siginfo_t *, int); +extern void printsiginfo(const siginfo_t *, bool); extern void printsiginfo_at(struct tcb *tcp, long addr); extern void printfd(struct tcb *, int); extern bool print_sockaddr_by_inode(const unsigned long, const char *); diff --git a/printsiginfo.c b/printsiginfo.c new file mode 100644 index 00000000..4e234532 --- /dev/null +++ b/printsiginfo.c @@ -0,0 +1,201 @@ +#include "defs.h" + +#include "xlat/sigbus_codes.h" +#include "xlat/sigchld_codes.h" +#include "xlat/sigfpe_codes.h" +#include "xlat/sigill_codes.h" +#include "xlat/siginfo_codes.h" +#include "xlat/sigpoll_codes.h" +#include "xlat/sigprof_codes.h" +#include "xlat/sigsegv_codes.h" +#include "xlat/sigsys_codes.h" +#include "xlat/sigtrap_codes.h" + +#ifdef SIGEMT +# include "xlat/sigemt_codes.h" +#endif + +#ifndef SI_FROMUSER +# define SI_FROMUSER(sip) ((sip)->si_code <= 0) +#endif + +static void +printsigsource(const siginfo_t *sip) +{ + tprintf(", si_pid=%lu, si_uid=%lu", + (unsigned long) sip->si_pid, + (unsigned long) sip->si_uid); +} + +static void +printsigval(const siginfo_t *sip, bool verbose) +{ + if (!verbose) + tprints(", ..."); + else + tprintf(", si_value={int=%u, ptr=%#lx}", + sip->si_int, + (unsigned long) sip->si_ptr); +} + +static void +print_si_code(int si_signo, int si_code) +{ + const char *code = xlookup(siginfo_codes, si_code); + + if (!code) { + switch (si_signo) { + case SIGTRAP: + code = xlookup(sigtrap_codes, si_code); + break; + case SIGCHLD: + code = xlookup(sigchld_codes, si_code); + break; + case SIGPOLL: + code = xlookup(sigpoll_codes, si_code); + break; + case SIGPROF: + code = xlookup(sigprof_codes, si_code); + break; + case SIGILL: + code = xlookup(sigill_codes, si_code); + break; +#ifdef SIGEMT + case SIGEMT: + code = xlookup(sigemt_codes, si_code); + break; +#endif + case SIGFPE: + code = xlookup(sigfpe_codes, si_code); + break; + case SIGSEGV: + code = xlookup(sigsegv_codes, si_code); + break; + case SIGBUS: + code = xlookup(sigbus_codes, si_code); + break; + case SIGSYS: + code = xlookup(sigsys_codes, si_code); + break; + } + } + + if (code) + tprints(code); + else + tprintf("%#x", si_code); +} + +static void +print_si_info(const siginfo_t *sip, bool verbose) +{ + if (sip->si_errno) { + tprints(", si_errno="); + if ((unsigned) sip->si_errno < nerrnos + && errnoent[sip->si_errno]) + tprints(errnoent[sip->si_errno]); + else + tprintf("%d", sip->si_errno); + } + + if (SI_FROMUSER(sip)) { + switch (sip->si_code) { + case SI_USER: + printsigsource(sip); + break; + case SI_TKILL: + printsigsource(sip); + break; +#if defined HAVE_SIGINFO_T_SI_TIMERID && defined HAVE_SIGINFO_T_SI_OVERRUN + case SI_TIMER: + tprintf(", si_timerid=%#x, si_overrun=%d", + sip->si_timerid, sip->si_overrun); + printsigval(sip, verbose); + break; +#endif + default: + printsigsource(sip); + if (sip->si_ptr) + printsigval(sip, verbose); + break; + } + } else { + switch (sip->si_signo) { + case SIGCHLD: + printsigsource(sip); + tprints(", si_status="); + if (sip->si_code == CLD_EXITED) + tprintf("%d", sip->si_status); + else + printsignal(sip->si_status); + if (!verbose) + tprints(", ..."); + else + tprintf(", si_utime=%llu, si_stime=%llu", + (unsigned long long) sip->si_utime, + (unsigned long long) sip->si_stime); + break; + case SIGILL: case SIGFPE: + case SIGSEGV: case SIGBUS: + tprintf(", si_addr=%#lx", + (unsigned long) sip->si_addr); + break; + case SIGPOLL: + switch (sip->si_code) { + case POLL_IN: case POLL_OUT: case POLL_MSG: + tprintf(", si_band=%ld", + (long) sip->si_band); + break; + } + break; +#ifdef HAVE_SIGINFO_T_SI_SYSCALL + case SIGSYS: + tprintf(", si_call_addr=%#lx, si_syscall=%d, si_arch=%u", + (unsigned long) sip->si_call_addr, + sip->si_syscall, sip->si_arch); + break; +#endif + default: + if (sip->si_pid || sip->si_uid) + printsigsource(sip); + if (sip->si_ptr) + printsigval(sip, verbose); + } + } +} + +void +printsiginfo(const siginfo_t *sip, bool verbose) +{ + if (sip->si_signo == 0) { + tprints("{}"); + return; + } + tprints("{si_signo="); + printsignal(sip->si_signo); + + tprints(", si_code="); + print_si_code(sip->si_signo, sip->si_code); + +#ifdef SI_NOINFO + if (sip->si_code != SI_NOINFO) +#endif + print_si_info(sip, verbose); + + tprints("}"); +} + +void +printsiginfo_at(struct tcb *tcp, long addr) +{ + siginfo_t si; + if (!addr) { + tprints("NULL"); + return; + } + if (syserror(tcp) || umove(tcp, addr, &si) < 0) { + tprintf("%#lx", addr); + return; + } + printsiginfo(&si, verbose(tcp)); +} diff --git a/signal.c b/signal.c index 99fc44e9..0b52ddb6 100644 --- a/signal.c +++ b/signal.c @@ -249,258 +249,6 @@ print_sigset_addr_len(struct tcb *tcp, long addr, long len) tprints(sprintsigmask_n("", mask, len)); } -#ifndef ILL_ILLOPC -#define ILL_ILLOPC 1 /* illegal opcode */ -#define ILL_ILLOPN 2 /* illegal operand */ -#define ILL_ILLADR 3 /* illegal addressing mode */ -#define ILL_ILLTRP 4 /* illegal trap */ -#define ILL_PRVOPC 5 /* privileged opcode */ -#define ILL_PRVREG 6 /* privileged register */ -#define ILL_COPROC 7 /* coprocessor error */ -#define ILL_BADSTK 8 /* internal stack error */ -#define FPE_INTDIV 1 /* integer divide by zero */ -#define FPE_INTOVF 2 /* integer overflow */ -#define FPE_FLTDIV 3 /* floating point divide by zero */ -#define FPE_FLTOVF 4 /* floating point overflow */ -#define FPE_FLTUND 5 /* floating point underflow */ -#define FPE_FLTRES 6 /* floating point inexact result */ -#define FPE_FLTINV 7 /* floating point invalid operation */ -#define FPE_FLTSUB 8 /* subscript out of range */ -#define SEGV_MAPERR 1 /* address not mapped to object */ -#define SEGV_ACCERR 2 /* invalid permissions for mapped object */ -#define BUS_ADRALN 1 /* invalid address alignment */ -#define BUS_ADRERR 2 /* non-existant physical address */ -#define BUS_OBJERR 3 /* object specific hardware error */ -#define SYS_SECCOMP 1 /* seccomp triggered */ -#define TRAP_BRKPT 1 /* process breakpoint */ -#define TRAP_TRACE 2 /* process trace trap */ -#define CLD_EXITED 1 /* child has exited */ -#define CLD_KILLED 2 /* child was killed */ -#define CLD_DUMPED 3 /* child terminated abnormally */ -#define CLD_TRAPPED 4 /* traced child has trapped */ -#define CLD_STOPPED 5 /* child has stopped */ -#define CLD_CONTINUED 6 /* stopped child has continued */ -#define POLL_IN 1 /* data input available */ -#define POLL_OUT 2 /* output buffers available */ -#define POLL_MSG 3 /* input message available */ -#define POLL_ERR 4 /* i/o error */ -#define POLL_PRI 5 /* high priority input available */ -#define POLL_HUP 6 /* device disconnected */ -#define SI_KERNEL 0x80 /* sent by kernel */ -#define SI_USER 0 /* sent by kill, sigsend, raise */ -#define SI_QUEUE -1 /* sent by sigqueue */ -#define SI_TIMER -2 /* sent by timer expiration */ -#define SI_MESGQ -3 /* sent by real time mesq state change */ -#define SI_ASYNCIO -4 /* sent by AIO completion */ -#define SI_SIGIO -5 /* sent by SIGIO */ -#define SI_TKILL -6 /* sent by tkill */ -#define SI_DETHREAD -7 /* sent by execve killing subsidiary threads */ -#define SI_ASYNCNL -60 /* sent by asynch name lookup completion */ -#endif - -#ifndef SI_FROMUSER -# define SI_FROMUSER(sip) ((sip)->si_code <= 0) -#endif - -#include "xlat/siginfo_codes.h" -#include "xlat/sigill_codes.h" -#include "xlat/sigfpe_codes.h" -#include "xlat/sigtrap_codes.h" -#include "xlat/sigchld_codes.h" -#include "xlat/sigpoll_codes.h" -#include "xlat/sigprof_codes.h" - -#ifdef SIGEMT -#include "xlat/sigemt_codes.h" -#endif - -#include "xlat/sigsegv_codes.h" -#include "xlat/sigbus_codes.h" - -#ifndef SYS_SECCOMP -# define SYS_SECCOMP 1 -#endif -#include "xlat/sigsys_codes.h" - -static void -printsigsource(const siginfo_t *sip) -{ - tprintf(", si_pid=%lu, si_uid=%lu", - (unsigned long) sip->si_pid, - (unsigned long) sip->si_uid); -} - -static void -printsigval(const siginfo_t *sip, int verbose) -{ - if (!verbose) - tprints(", ..."); - else - tprintf(", si_value={int=%u, ptr=%#lx}", - sip->si_int, - (unsigned long) sip->si_ptr); -} - -void -printsiginfo(const siginfo_t *sip, int verbose) -{ - const char *code; - - if (sip->si_signo == 0) { - tprints("{}"); - return; - } - tprints("{si_signo="); - printsignal(sip->si_signo); - code = xlookup(siginfo_codes, sip->si_code); - if (!code) { - switch (sip->si_signo) { - case SIGTRAP: - code = xlookup(sigtrap_codes, sip->si_code); - break; - case SIGCHLD: - code = xlookup(sigchld_codes, sip->si_code); - break; - case SIGPOLL: - code = xlookup(sigpoll_codes, sip->si_code); - break; - case SIGPROF: - code = xlookup(sigprof_codes, sip->si_code); - break; - case SIGILL: - code = xlookup(sigill_codes, sip->si_code); - break; -#ifdef SIGEMT - case SIGEMT: - code = xlookup(sigemt_codes, sip->si_code); - break; -#endif - case SIGFPE: - code = xlookup(sigfpe_codes, sip->si_code); - break; - case SIGSEGV: - code = xlookup(sigsegv_codes, sip->si_code); - break; - case SIGBUS: - code = xlookup(sigbus_codes, sip->si_code); - break; - case SIGSYS: - code = xlookup(sigsys_codes, sip->si_code); - break; - } - } - if (code) - tprintf(", si_code=%s", code); - else - tprintf(", si_code=%#x", sip->si_code); -#ifdef SI_NOINFO - if (sip->si_code != SI_NOINFO) -#endif - { - if (sip->si_errno) { - tprints(", si_errno="); - if ((unsigned) sip->si_errno < nerrnos - && errnoent[sip->si_errno]) - tprints(errnoent[sip->si_errno]); - else - tprintf("%d", sip->si_errno); - } -#ifdef SI_FROMUSER - if (SI_FROMUSER(sip)) { - switch (sip->si_code) { -#ifdef SI_USER - case SI_USER: - printsigsource(sip); - break; -#endif -#ifdef SI_TKILL - case SI_TKILL: - printsigsource(sip); - break; -#endif -#if defined SI_TIMER \ - && defined HAVE_SIGINFO_T_SI_TIMERID && defined HAVE_SIGINFO_T_SI_OVERRUN - case SI_TIMER: - tprintf(", si_timerid=%#x, si_overrun=%d", - sip->si_timerid, sip->si_overrun); - printsigval(sip, verbose); - break; -#endif - default: - printsigsource(sip); - if (sip->si_ptr) - printsigval(sip, verbose); - break; - } - } - else -#endif /* SI_FROMUSER */ - { - switch (sip->si_signo) { - case SIGCHLD: - printsigsource(sip); - tprints(", si_status="); - if (sip->si_code == CLD_EXITED) - tprintf("%d", sip->si_status); - else - printsignal(sip->si_status); - if (!verbose) - tprints(", ..."); - else - tprintf(", si_utime=%llu, si_stime=%llu", - (unsigned long long) sip->si_utime, - (unsigned long long) sip->si_stime); - break; - case SIGILL: case SIGFPE: - case SIGSEGV: case SIGBUS: - tprintf(", si_addr=%#lx", - (unsigned long) sip->si_addr); - break; - case SIGPOLL: - switch (sip->si_code) { - case POLL_IN: case POLL_OUT: case POLL_MSG: - tprintf(", si_band=%ld", - (long) sip->si_band); - break; - } - break; -#ifdef HAVE_SIGINFO_T_SI_SYSCALL - case SIGSYS: - tprintf(", si_call_addr=%#lx, si_syscall=%d, si_arch=%u", - (unsigned long) sip->si_call_addr, - sip->si_syscall, sip->si_arch); - break; -#endif - default: - if (sip->si_pid || sip->si_uid) - printsigsource(sip); - if (sip->si_ptr) - printsigval(sip, verbose); - } - } - } - tprints("}"); -} - -void -printsiginfo_at(struct tcb *tcp, long addr) -{ - siginfo_t si; - if (!addr) { - tprints("NULL"); - return; - } - if (syserror(tcp)) { - tprintf("%#lx", addr); - return; - } - if (umove(tcp, addr, &si) < 0) { - tprints("{???}"); - return; - } - printsiginfo(&si, verbose(tcp)); -} - int sys_sigsetmask(struct tcb *tcp) {