This extends the -e fault capability with a :signal option which
delivers a signal on entry of the specified syscall.
:error and :signal are mutually exclusive; it does not make sense to
interrupt a syscall with a signal and stipulate an error code.
Currently :signal has greater precedence than :error.

Signed-off-by: Seraphime Kirkovski <kirkser...@gmail.com>
---
 defs.h    |  4 +++-
 qualify.c |  6 ++++++
 strace.c  |  4 +++-
 syscall.c | 16 +++++++++-------
 4 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/defs.h b/defs.h
index 0a4c616..597bdd3 100644
--- a/defs.h
+++ b/defs.h
@@ -218,6 +218,7 @@ struct fault_opts {
        uint16_t first;
        uint16_t step;
        uint16_t err;
+       int16_t signo;
 };
 
 #if defined LINUX_MIPSN32 || defined X32
@@ -457,13 +458,14 @@ extern int read_int_from_file(const char *, int *);
 extern void set_sortby(const char *);
 extern void set_overhead(int);
 extern void print_pc(struct tcb *);
-extern int trace_syscall(struct tcb *);
+extern int trace_syscall(struct tcb *, unsigned int *);
 extern void count_syscall(struct tcb *, const struct timeval *);
 extern void call_summary(FILE *);
 
 extern void clear_regs(void);
 extern void get_regs(pid_t pid);
 extern int get_scno(struct tcb *tcp);
+
 /**
  * Convert syscall number to syscall name.
  *
diff --git a/qualify.c b/qualify.c
index a7d276c..972fa53 100644
--- a/qualify.c
+++ b/qualify.c
@@ -414,6 +414,11 @@ parse_fault_token(const char *const token, struct 
fault_opts *const fopts)
                if (intval < 1)
                        return false;
                fopts->err = intval;
+       } else if ((val = strip_prefix("signal=", token))) {
+               intval = sigstr_to_uint(val);
+               if (intval < 0)
+                       return false;
+               fopts->signo = intval;
        } else {
                return false;
        }
@@ -494,6 +499,7 @@ qualify_fault(const char *const str)
        struct fault_opts opts = {
                .first = 1,
                .step = 1,
+               .signo = -1,
                .err = 0
        };
        char *buf = NULL;
diff --git a/strace.c b/strace.c
index 4659ddb..23ca108 100644
--- a/strace.c
+++ b/strace.c
@@ -2447,7 +2447,8 @@ show_stopsig:
         * This should be syscall entry or exit.
         * Handle it.
         */
-       if (trace_syscall(tcp) < 0) {
+       sig = 0;
+       if (trace_syscall(tcp, &sig) < 0) {
                /*
                 * ptrace() failed in trace_syscall().
                 * Likely a result of process disappearing mid-flight.
@@ -2461,6 +2462,7 @@ show_stopsig:
                 */
                return true;
        }
+       goto restart_tracee;
 
 restart_tracee_with_sig_0:
        sig = 0;
diff --git a/syscall.c b/syscall.c
index 63d3b00..16a1072 100644
--- a/syscall.c
+++ b/syscall.c
@@ -573,7 +573,7 @@ tcb_fault_opts(struct tcb *tcp)
 
 
 static long
-inject_syscall_fault_entering(struct tcb *tcp)
+inject_syscall_fault_entering(struct tcb *tcp, unsigned int *signo)
 {
        if (!tcp->fault_vec[current_personality]) {
                tcp->fault_vec[current_personality] =
@@ -595,7 +595,9 @@ inject_syscall_fault_entering(struct tcb *tcp)
 
        opts->first = opts->step;
 
-       if (!arch_set_scno(tcp, -1))
+       if (opts->signo != -1)
+               *signo = opts->signo;
+       else if (!arch_set_scno(tcp, -1))
                tcp->flags |= TCB_FAULT_INJ;
 
        return 0;
@@ -617,7 +619,7 @@ update_syscall_fault_exiting(struct tcb *tcp)
 }
 
 static int
-trace_syscall_entering(struct tcb *tcp)
+trace_syscall_entering(struct tcb *tcp, unsigned int *sig)
 {
        int res, scno_good;
 
@@ -688,7 +690,7 @@ trace_syscall_entering(struct tcb *tcp)
        }
 
        if (tcp->qual_flg & QUAL_FAULT)
-               inject_syscall_fault_entering(tcp);
+               inject_syscall_fault_entering(tcp, sig);
 
        if (cflag == CFLAG_ONLY_STATS) {
                res = 0;
@@ -716,7 +718,7 @@ trace_syscall_entering(struct tcb *tcp)
        /* Measure the entrance time as late as possible to avoid errors. */
        if (Tflag || cflag)
                gettimeofday(&tcp->etime, NULL);
-       return res;
+       return 0;
 }
 
 static bool
@@ -981,10 +983,10 @@ trace_syscall_exiting(struct tcb *tcp)
 }
 
 int
-trace_syscall(struct tcb *tcp)
+trace_syscall(struct tcb *tcp, unsigned int *signo)
 {
        return exiting(tcp) ?
-               trace_syscall_exiting(tcp) : trace_syscall_entering(tcp);
+               trace_syscall_exiting(tcp) : trace_syscall_entering(tcp, signo);
 }
 
 bool
-- 
2.10.2


------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today.http://sdm.link/intel
_______________________________________________
Strace-devel mailing list
Strace-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/strace-devel

Reply via email to