]> granicus.if.org Git - strace/commitdiff
Eliminate many SCNO_IS_VALID checks
authorDenys Vlasenko <vda.linux@googlemail.com>
Thu, 21 Feb 2013 15:13:47 +0000 (16:13 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Thu, 21 Feb 2013 15:13:47 +0000 (16:13 +0100)
By adding tcp->s_ent pointer tot syscall table entry,
we can replace sysent[tcp->scno] references by tcp->s_ent.
More importantly, we may ensure that tcp->s_ent is always valid,
regardless of tcp->scno value. This allows us to drop
SCNO_IS_VALID(tcp->scno) checks before we access syscall
table entry.

We can optimize (qual_flags[tcp->scno] & QUAL_foo) checks
with a similar technique.

Resulting code shrink:
   text    data     bss     dec     hex filename
 245975     700   19072  265747   40e13 strace.t3/strace
 245703     700   19072  265475   40d03 strace.t4/strace

* count.c (count_syscall): Use cheaper SCNO_IN_RANGE() check.
* defs.h: Add "int qual_flg" and "const struct sysent *s_ent"
to struct tcb. Remove "int u_nargs" from it.
Add UNDEFINED_SCNO constant which will mark undefined scnos
in tcp->qual_flg.
* pathtrace.c (pathtrace_match): Drop SCNO_IS_VALID check.
Use tcp->s_ent instead of sysent[tcp->scno].
* process.c (sys_prctl): Use tcp->s_ent->nargs instead of tcp->u_nargs.
(sys_waitid): Likewise.
* strace.c (init): Add compile-time check that DEFAULT_QUAL_FLAGS
constant is consistent with init code.
* syscall.c (decode_socket_subcall): Use tcp->s_ent->nargs
instead of tcp->u_nargs. Set tcp->qual_flg and tcp->s_ent.
(decode_ipc_subcall): Likewise.
(printargs): Use tcp->s_ent->nargs instead of tcp->u_nargs.
(printargs_lu): Likewise.
(printargs_ld): Likewise.
(get_scno): [MIPS,ALPHA] Use cheaper SCNO_IN_RANGE() check.
If !SCNO_IS_VALID, set tcp->s_ent and tcp->qual_flg to default values.
(internal_fork): Use tcp->s_ent instead of sysent[tcp->scno].
(syscall_fixup_for_fork_exec): Remove SCNO_IS_VALID check.
Use tcp->s_ent instead of sysent[tcp->scno].
(get_syscall_args): Likewise.
(get_error): Drop SCNO_IS_VALID check where it is redundant.
(dumpio): Drop SCNO_IS_VALID check where it is redundant.
Use tcp->s_ent instead of sysent[tcp->scno].
(trace_syscall_entering): Use (tcp->qual_flg & UNDEFINED_SCNO) instead
of SCNO_IS_VALID check. Use tcp->s_ent instead of sysent[tcp->scno].
Drop SCNO_IS_VALID check where it is redundant.
Print undefined syscall name with undefined_scno_name(tcp).
(trace_syscall_exiting): Likewise.
* util.c (setbpt): Use tcp->s_ent instead of sysent[tcp->scno].

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
count.c
defs.h
pathtrace.c
process.c
strace.c
syscall.c
util.c

diff --git a/count.c b/count.c
index 9405fd1b1aceb9cc0ac5848b766fab68f12db98d..6c9b1c20c90e3c2682a6ecdf1b4d77ec62350353 100644 (file)
--- a/count.c
+++ b/count.c
@@ -48,7 +48,9 @@ static struct timeval shortest = { 1000000, 0 };
 void
 count_syscall(struct tcb *tcp, struct timeval *tv)
 {
-       if (!SCNO_IS_VALID(tcp->scno))
+       unsigned long scno = tcp->scno;
+
+       if (!SCNO_IN_RANGE(scno))
                return;
 
        if (!counts) {
@@ -57,9 +59,9 @@ count_syscall(struct tcb *tcp, struct timeval *tv)
                        die_out_of_memory();
        }
 
-       counts[tcp->scno].calls++;
+       counts[scno].calls++;
        if (tcp->u_error)
-               counts[tcp->scno].errors++;
+               counts[scno].errors++;
 
        tv_sub(tv, tv, &tcp->etime);
        if (tv_cmp(tv, &tcp->dtime) > 0) {
@@ -87,7 +89,7 @@ count_syscall(struct tcb *tcp, struct timeval *tv)
        }
        if (tv_cmp(tv, &shortest) < 0)
                shortest = *tv;
-       tv_add(&counts[tcp->scno].time, &counts[tcp->scno].time, tv);
+       tv_add(&counts[scno].time, &counts[scno].time, tv);
 }
 
 static int
diff --git a/defs.h b/defs.h
index fc8f8e7856d9ac05d1d907fe9173abceb6aecb5e..855a312208fc9ba18f9febb83393bb1aeaa76842 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -366,11 +366,24 @@ extern struct pt_regs arm_regs;
 extern struct pt_regs tile_regs;
 #endif
 
+struct sysent {
+       unsigned nargs;
+       int     sys_flags;
+       int     (*sys_func)();
+       const char *sys_name;
+};
+
+struct ioctlent {
+       const char *doth;
+       const char *symbol;
+       unsigned long code;
+};
+
 /* Trace Control Block */
 struct tcb {
        int flags;              /* See below for TCB_ values */
        int pid;                /* Process Id of this entry */
-       int u_nargs;            /* System call argument count */
+       int qual_flg;           /* qual_flags[scno] or DEFAULT_QUAL_FLAGS + RAW */
        int u_error;            /* Error code */
        long scno;              /* System call number */
        long u_arg[MAX_ARGS];   /* System call arguments */
@@ -385,6 +398,7 @@ struct tcb {
        int curcol;             /* Output column for this process */
        FILE *outf;             /* Output file for this process */
        const char *auxstr;     /* Auxiliary info from syscall (see RVAL_STR) */
+       const struct sysent *s_ent; /* sysent[scno] or dummy struct for bad scno */
        struct timeval stime;   /* System time usage as of last process wait */
        struct timeval dtime;   /* Delta for system time usage */
        struct timeval etime;   /* Syscall entry time */
@@ -447,14 +461,17 @@ struct tcb {
 #endif
 
 /* qualifier flags */
-#define QUAL_TRACE     0001    /* this system call should be traced */
-#define QUAL_ABBREV    0002    /* abbreviate the structures of this syscall */
-#define QUAL_VERBOSE   0004    /* decode the structures of this syscall */
-#define QUAL_RAW       0010    /* print all args in hex for this syscall */
-#define QUAL_SIGNAL    0020    /* report events with this signal */
-#define QUAL_FAULT     0040    /* report events with this fault */
-#define QUAL_READ      0100    /* dump data read on this file descriptor */
-#define QUAL_WRITE     0200    /* dump data written to this file descriptor */
+#define QUAL_TRACE     0x001   /* this system call should be traced */
+#define QUAL_ABBREV    0x002   /* abbreviate the structures of this syscall */
+#define QUAL_VERBOSE   0x004   /* decode the structures of this syscall */
+#define QUAL_RAW       0x008   /* print all args in hex for this syscall */
+#define QUAL_SIGNAL    0x010   /* report events with this signal */
+#define QUAL_FAULT     0x020   /* report events with this fault */
+#define QUAL_READ      0x040   /* dump data read on this file descriptor */
+#define QUAL_WRITE     0x080   /* dump data written to this file descriptor */
+#define UNDEFINED_SCNO 0x100   /* Used only in tcp->qual_flg */
+
+#define DEFAULT_QUAL_FLAGS (QUAL_TRACE | QUAL_ABBREV | QUAL_VERBOSE)
 
 #define entering(tcp)  (!((tcp)->flags & TCB_INSYSCALL))
 #define exiting(tcp)   ((tcp)->flags & TCB_INSYSCALL)
@@ -728,19 +745,6 @@ extern unsigned current_wordsize;
 # define widen_to_long(v) ((long)(v))
 #endif
 
-struct sysent {
-       unsigned nargs;
-       int     sys_flags;
-       int     (*sys_func)();
-       const char *sys_name;
-};
-
-struct ioctlent {
-       const char *doth;
-       const char *symbol;
-       unsigned long code;
-};
-
 extern const struct sysent *sysent;
 extern unsigned nsyscalls;
 extern const char *const *errnoent;
index 33c9b75d78a17a5b7ca46e28b9642972a2bff8aa..7f90dd5c68051f82d95117603521f170b298ca36 100644 (file)
@@ -162,10 +162,7 @@ pathtrace_match(struct tcb *tcp)
        if (selected[0] == NULL)
                return 1;
 
-       if (!SCNO_IS_VALID(tcp->scno))
-               return 0;
-
-       s = &sysent[tcp->scno];
+       s = tcp->s_ent;
 
        if (!(s->sys_flags & (TRACE_FILE | TRACE_DESC)))
                return 0;
index 0b702e771cfdea3587d91e2a20bdf8cbf7771a3a..a1f963e633397900297f603468d2865445e5ac49 100644 (file)
--- a/process.c
+++ b/process.c
@@ -302,7 +302,7 @@ sys_prctl(struct tcb *tcp)
                        break;
 #endif
                default:
-                       for (i = 1; i < tcp->u_nargs; i++)
+                       for (i = 1; i < tcp->s_ent->nargs; i++)
                                tprintf(", %#lx", tcp->u_arg[i]);
                        break;
                }
@@ -1137,7 +1137,7 @@ sys_waitid(struct tcb *tcp)
                /* options */
                tprints(", ");
                printflags(wait4_options, tcp->u_arg[3], "W???");
-               if (tcp->u_nargs > 4) {
+               if (tcp->s_ent->nargs > 4) {
                        /* usage */
                        tprints(", ");
                        if (!tcp->u_arg[4])
index 1052a8850920470952ed2ce0c674979530a11b5e..8d7ee74d6486cca8ce5a0071bd8bbee3a0ff4c54 100644 (file)
--- a/strace.c
+++ b/strace.c
@@ -1543,6 +1543,9 @@ init(int argc, char *argv[])
        qualify("trace=all");
        qualify("abbrev=all");
        qualify("verbose=all");
+#if DEFAULT_QUAL_FLAGS != (QUAL_TRACE | QUAL_ABBREV | QUAL_VERBOSE)
+# error Bug in DEFAULT_QUAL_FLAGS
+#endif
        qualify("signal=all");
        while ((c = getopt(argc, argv,
                "+bcCdfFhiqrtTvVxyz"
index b1a407b0eff4807fcacf1144d51134fb51486f9c..fa06156b11f01dbbe3e4099bccbf051437c5b73c 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -556,16 +556,18 @@ static void
 decode_socket_subcall(struct tcb *tcp)
 {
        unsigned long addr;
-       unsigned int i, size;
+       unsigned int i, n, size;
 
        if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= SYS_socket_nsubcalls)
                return;
 
        tcp->scno = SYS_socket_subcall + tcp->u_arg[0];
+       tcp->qual_flg = qual_flags[tcp->scno];
+       tcp->s_ent = &sysent[tcp->scno];
        addr = tcp->u_arg[1];
-       tcp->u_nargs = sysent[tcp->scno].nargs;
        size = current_wordsize;
-       for (i = 0; i < tcp->u_nargs; ++i) {
+       n = tcp->s_ent->nargs;
+       for (i = 0; i < n; ++i) {
                if (size == sizeof(int)) {
                        unsigned int arg;
                        if (umove(tcp, addr, &arg) < 0)
@@ -587,14 +589,16 @@ decode_socket_subcall(struct tcb *tcp)
 static void
 decode_ipc_subcall(struct tcb *tcp)
 {
-       unsigned int i;
+       unsigned int i, n;
 
        if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= SYS_ipc_nsubcalls)
                return;
 
        tcp->scno = SYS_ipc_subcall + tcp->u_arg[0];
-       tcp->u_nargs = sysent[tcp->scno].nargs;
-       for (i = 0; i < tcp->u_nargs; i++)
+       tcp->qual_flg = qual_flags[tcp->scno];
+       tcp->s_ent = &sysent[tcp->scno];
+       n = tcp->s_ent->nargs;
+       for (i = 0; i < n; i++)
                tcp->u_arg[i] = tcp->u_arg[i + 1];
 }
 #endif
@@ -604,8 +608,8 @@ printargs(struct tcb *tcp)
 {
        if (entering(tcp)) {
                int i;
-
-               for (i = 0; i < tcp->u_nargs; i++)
+               int n = tcp->s_ent->nargs;
+               for (i = 0; i < n; i++)
                        tprintf("%s%#lx", i ? ", " : "", tcp->u_arg[i]);
        }
        return 0;
@@ -616,8 +620,8 @@ printargs_lu(struct tcb *tcp)
 {
        if (entering(tcp)) {
                int i;
-
-               for (i = 0; i < tcp->u_nargs; i++)
+               int n = tcp->s_ent->nargs;
+               for (i = 0; i < n; i++)
                        tprintf("%s%lu", i ? ", " : "", tcp->u_arg[i]);
        }
        return 0;
@@ -628,8 +632,8 @@ printargs_ld(struct tcb *tcp)
 {
        if (entering(tcp)) {
                int i;
-
-               for (i = 0; i < tcp->u_nargs; i++)
+               int n = tcp->s_ent->nargs;
+               for (i = 0; i < n; i++)
                        tprintf("%s%ld", i ? ", " : "", tcp->u_arg[i]);
        }
        return 0;
@@ -1305,7 +1309,7 @@ get_scno(struct tcb *tcp)
        mips_r2 = regs[REG_V0];
 
        scno = mips_r2;
-       if (!SCNO_IS_VALID(scno)) {
+       if (!SCNO_IN_RANGE(scno)) {
                if (mips_a3 == 0 || mips_a3 == -1) {
                        if (debug_flag)
                                fprintf(stderr, "stray syscall exit: v0 = %ld\n", scno);
@@ -1318,7 +1322,7 @@ get_scno(struct tcb *tcp)
        if (upeek(tcp, REG_V0, &scno) < 0)
                return -1;
 
-       if (!SCNO_IS_VALID(scno)) {
+       if (!SCNO_IN_RANGE(scno)) {
                if (mips_a3 == 0 || mips_a3 == -1) {
                        if (debug_flag)
                                fprintf(stderr, "stray syscall exit: v0 = %ld\n", scno);
@@ -1335,7 +1339,7 @@ get_scno(struct tcb *tcp)
         * Do some sanity checks to figure out if it's
         * really a syscall entry
         */
-       if (!SCNO_IS_VALID(scno)) {
+       if (!SCNO_IN_RANGE(scno)) {
                if (alpha_a3 == 0 || alpha_a3 == -1) {
                        if (debug_flag)
                                fprintf(stderr, "stray syscall exit: r0 = %ld\n", scno);
@@ -1453,6 +1457,19 @@ get_scno(struct tcb *tcp)
 #endif
 
        tcp->scno = scno;
+       if (SCNO_IS_VALID(tcp->scno)) {
+               tcp->s_ent = &sysent[scno];
+               tcp->qual_flg = qual_flags[scno];
+       } else {
+               static const struct sysent unknown = {
+                       .nargs = MAX_ARGS,
+                       .sys_flags = 0,
+                       .sys_func = printargs,
+                       .sys_name = "unknown", /* not used */
+               };
+               tcp->s_ent = &unknown;
+               tcp->qual_flg = UNDEFINED_SCNO | QUAL_RAW | DEFAULT_QUAL_FLAGS;
+       }
        return 1;
 }
 
@@ -1567,8 +1584,9 @@ internal_fork(struct tcb *tcp)
                 * CLONE_UNTRACED, so we keep the same logic with that option
                 * and don't trace it.
                 */
-               if ((sysent[tcp->scno].sys_func == sys_clone) &&
-                   (tcp->u_arg[ARG_FLAGS] & CLONE_UNTRACED))
+               if ((tcp->s_ent->sys_func == sys_clone)
+                && (tcp->u_arg[ARG_FLAGS] & CLONE_UNTRACED)
+               )
                        return;
                setbpt(tcp);
        } else {
@@ -1603,10 +1621,7 @@ syscall_fixup_for_fork_exec(struct tcb *tcp)
         */
        int (*func)();
 
-       if (!SCNO_IS_VALID(tcp->scno))
-               return;
-
-       func = sysent[tcp->scno].sys_func;
+       func = tcp->s_ent->sys_func;
 
        if (   sys_fork == func
            || sys_vfork == func
@@ -1634,10 +1649,7 @@ get_syscall_args(struct tcb *tcp)
 {
        int i, nargs;
 
-       if (SCNO_IS_VALID(tcp->scno))
-               nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
-       else
-               nargs = tcp->u_nargs = MAX_ARGS;
+       nargs = tcp->s_ent->nargs;
 
 #if defined(S390) || defined(S390X)
        for (i = 0; i < nargs; ++i)
@@ -1874,10 +1886,10 @@ trace_syscall_entering(struct tcb *tcp)
                printleader(tcp);
                if (scno_good != 1)
                        tprints("????" /* anti-trigraph gap */ "(");
-               else if (!SCNO_IS_VALID(tcp->scno))
+               else if (tcp->qual_flg & UNDEFINED_SCNO)
                        tprintf("%s(", undefined_scno_name(tcp));
                else
-                       tprintf("%s(", sysent[tcp->scno].sys_name);
+                       tprintf("%s(", tcp->s_ent->sys_name);
                /*
                 * " <unavailable>" will be added later by the code which
                 * detects ptrace errors.
@@ -1886,29 +1898,29 @@ trace_syscall_entering(struct tcb *tcp)
        }
 
 #if defined(SYS_socket_subcall) || defined(SYS_ipc_subcall)
-       while (SCNO_IS_VALID(tcp->scno)) {
+       while (1) {
 # ifdef SYS_socket_subcall
-               if (sysent[tcp->scno].sys_func == sys_socketcall) {
+               if (tcp->s_ent->sys_func == sys_socketcall) {
                        decode_socket_subcall(tcp);
                        break;
                }
 # endif
 # ifdef SYS_ipc_subcall
-               if (sysent[tcp->scno].sys_func == sys_ipc) {
+               if (tcp->s_ent->sys_func == sys_ipc) {
                        decode_ipc_subcall(tcp);
                        break;
                }
 # endif
                break;
        }
-#endif /* SYS_socket_subcall || SYS_ipc_subcall */
+#endif
 
        if (need_fork_exec_workarounds)
                syscall_fixup_for_fork_exec(tcp);
 
-       if ((SCNO_IS_VALID(tcp->scno) &&
-            !(qual_flags[tcp->scno] & QUAL_TRACE)) ||
-           (tracing_paths && !pathtrace_match(tcp))) {
+       if (!(tcp->qual_flg & QUAL_TRACE)
+        || (tracing_paths && !pathtrace_match(tcp))
+       ) {
                tcp->flags |= TCB_INSYSCALL | TCB_FILTERED;
                return 0;
        }
@@ -1921,16 +1933,14 @@ trace_syscall_entering(struct tcb *tcp)
        }
 
        printleader(tcp);
-       if (!SCNO_IS_VALID(tcp->scno))
+       if (tcp->qual_flg & UNDEFINED_SCNO)
                tprintf("%s(", undefined_scno_name(tcp));
        else
-               tprintf("%s(", sysent[tcp->scno].sys_name);
-       if (!SCNO_IS_VALID(tcp->scno) ||
-           ((qual_flags[tcp->scno] & QUAL_RAW) &&
-            sysent[tcp->scno].sys_func != sys_exit))
+               tprintf("%s(", tcp->s_ent->sys_name);
+       if ((tcp->qual_flg & QUAL_RAW) && tcp->s_ent->sys_func != sys_exit)
                res = printargs(tcp);
        else
-               res = (*sysent[tcp->scno].sys_func)(tcp);
+               res = tcp->s_ent->sys_func(tcp);
 
        fflush(tcp->outf);
  ret:
@@ -2102,9 +2112,7 @@ get_error(struct tcb *tcp)
 {
        int u_error = 0;
        int check_errno = 1;
-       if (SCNO_IN_RANGE(tcp->scno)
-        && (sysent[tcp->scno].sys_flags & SYSCALL_NEVER_FAILS)
-       ) {
+       if (tcp->s_ent->sys_flags & SYSCALL_NEVER_FAILS) {
                check_errno = 0;
        }
 #if defined(S390) || defined(S390X)
@@ -2333,31 +2341,32 @@ get_error(struct tcb *tcp)
 static void
 dumpio(struct tcb *tcp)
 {
+       int (*func)();
+
        if (syserror(tcp))
                return;
-       if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= MAX_QUALS)
-               return;
-       if (!SCNO_IS_VALID(tcp->scno))
+       if ((unsigned long) tcp->u_arg[0] >= MAX_QUALS)
                return;
-       if (sysent[tcp->scno].sys_func == printargs)
+       func = tcp->s_ent->sys_func;
+       if (func == printargs)
                return;
        if (qual_flags[tcp->u_arg[0]] & QUAL_READ) {
-               if (sysent[tcp->scno].sys_func == sys_read ||
-                   sysent[tcp->scno].sys_func == sys_pread ||
-                   sysent[tcp->scno].sys_func == sys_recv ||
-                   sysent[tcp->scno].sys_func == sys_recvfrom)
+               if (func == sys_read ||
+                   func == sys_pread ||
+                   func == sys_recv ||
+                   func == sys_recvfrom)
                        dumpstr(tcp, tcp->u_arg[1], tcp->u_rval);
-               else if (sysent[tcp->scno].sys_func == sys_readv)
+               else if (func == sys_readv)
                        dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
                return;
        }
        if (qual_flags[tcp->u_arg[0]] & QUAL_WRITE) {
-               if (sysent[tcp->scno].sys_func == sys_write ||
-                   sysent[tcp->scno].sys_func == sys_pwrite ||
-                   sysent[tcp->scno].sys_func == sys_send ||
-                   sysent[tcp->scno].sys_func == sys_sendto)
+               if (func == sys_write ||
+                   func == sys_pwrite ||
+                   func == sys_send ||
+                   func == sys_sendto)
                        dumpstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
-               else if (sysent[tcp->scno].sys_func == sys_writev)
+               else if (func == sys_writev)
                        dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
                return;
        }
@@ -2408,10 +2417,10 @@ trace_syscall_exiting(struct tcb *tcp)
        if ((followfork < 2 && printing_tcp != tcp) || (tcp->flags & TCB_REPRINT)) {
                tcp->flags &= ~TCB_REPRINT;
                printleader(tcp);
-               if (!SCNO_IS_VALID(tcp->scno))
+               if (tcp->qual_flg & UNDEFINED_SCNO)
                        tprintf("<... %s resumed> ", undefined_scno_name(tcp));
                else
-                       tprintf("<... %s resumed> ", sysent[tcp->scno].sys_name);
+                       tprintf("<... %s resumed> ", tcp->s_ent->sys_name);
        }
        printing_tcp = tcp;
 
@@ -2426,8 +2435,7 @@ trace_syscall_exiting(struct tcb *tcp)
        }
 
        sys_res = 0;
-       if (!SCNO_IS_VALID(tcp->scno)
-           || (qual_flags[tcp->scno] & QUAL_RAW)) {
+       if (tcp->qual_flg & QUAL_RAW) {
                /* sys_res = printargs(tcp); - but it's nop on sysexit */
        } else {
        /* FIXME: not_failing_only (IOW, option -z) is broken:
@@ -2440,14 +2448,13 @@ trace_syscall_exiting(struct tcb *tcp)
         */
                if (not_failing_only && tcp->u_error)
                        goto ret;       /* ignore failed syscalls */
-               sys_res = (*sysent[tcp->scno].sys_func)(tcp);
+               sys_res = tcp->s_ent->sys_func(tcp);
        }
 
        tprints(") ");
        tabto();
        u_error = tcp->u_error;
-       if (!SCNO_IS_VALID(tcp->scno) ||
-           qual_flags[tcp->scno] & QUAL_RAW) {
+       if (tcp->qual_flg & QUAL_RAW) {
                if (u_error)
                        tprintf("= -1 (errno %ld)", u_error);
                else
diff --git a/util.c b/util.c
index f0d024d46292332db96e6f346fbf969062d54326..4c22c5fd0c4b8f253ab99d818f6f42c60d872b28 100644 (file)
--- a/util.c
+++ b/util.c
@@ -1332,8 +1332,8 @@ setbpt(struct tcb *tcp)
                        }
        }
 
-       if (sysent[tcp->scno].sys_func == sys_fork ||
-           sysent[tcp->scno].sys_func == sys_vfork) {
+       if (tcp->s_ent->sys_func == sys_fork ||
+           tcp->s_ent->sys_func == sys_vfork) {
                if (arg_setup(tcp, &state) < 0
                    || get_arg0(tcp, &state, &tcp->inst[0]) < 0
                    || get_arg1(tcp, &state, &tcp->inst[1]) < 0
@@ -1349,7 +1349,7 @@ setbpt(struct tcb *tcp)
                return 0;
        }
 
-       if (sysent[tcp->scno].sys_func == sys_clone) {
+       if (tcp->s_ent->sys_func == sys_clone) {
                /* ia64 calls directly `clone (CLONE_VFORK | CLONE_VM)'
                   contrary to x86 vfork above.  Even on x86 we turn the
                   vfork semantics into plain fork - each application must not