Eliminate many SCNO_IS_VALID checks
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>
This commit is contained in:
parent
7270de551c
commit
74ec14f968
10
count.c
10
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
|
||||
|
48
defs.h
48
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;
|
||||
|
@ -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;
|
||||
|
@ -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])
|
||||
|
3
strace.c
3
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"
|
||||
|
135
syscall.c
135
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)
|
||||
if ((unsigned long) tcp->u_arg[0] >= MAX_QUALS)
|
||||
return;
|
||||
if (!SCNO_IS_VALID(tcp->scno))
|
||||
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
|
||||
|
6
util.c
6
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user