#define TP TRACE_PROCESS
#define TS TRACE_SIGNAL
#define TM TRACE_MEMORY
-#define TSC TRACE_SCHED
-#define TCL TRACE_CLOCK
#define TSF TRACE_STATFS
#define NF SYSCALL_NEVER_FAILS
#define MA MAX_ARGS
#undef TP
#undef TS
#undef TM
-#undef TSC
-#undef TCL
#undef TSF
#undef NF
#undef MA
get_regs_error = -1;
}
+static void get_regs(pid_t pid);
static int get_syscall_args(struct tcb *);
static int get_syscall_result(struct tcb *);
static int arch_get_scno(struct tcb *tcp);
static int
trace_syscall_entering(struct tcb *tcp, unsigned int *sig)
{
- int res, scno_good;
-
- scno_good = res = get_scno(tcp);
+ int res = get_scno(tcp);
if (res == 0)
return res;
+
+ int scno_good = res;
if (res == 1)
res = get_syscall_args(tcp);
static int
trace_syscall_exiting(struct tcb *tcp)
{
- int sys_res;
struct timeval tv;
- int res;
- unsigned long u_error;
- const char *u_error_str;
/* Measure the exit time as early as possible to avoid errors. */
- if (Tflag || cflag)
+ if ((Tflag || cflag) && !(filtered(tcp) || hide_log(tcp)))
gettimeofday(&tv, NULL);
#ifdef USE_LIBUNWIND
}
#endif
+ if (filtered(tcp) || hide_log(tcp))
+ goto ret;
+
+ get_regs(tcp->pid);
#if SUPPORTED_PERSONALITIES > 1
update_personality(tcp, tcp->currpers);
#endif
- res = (get_regs_error ? -1 : get_syscall_result(tcp));
- if (filtered(tcp) || hide_log(tcp))
- goto ret;
+ int res = (get_regs_error ? -1 : get_syscall_result(tcp));
if (syserror(tcp) && syscall_tampered(tcp))
tamper_with_syscall_exiting(tcp);
}
tcp->s_prev_ent = tcp->s_ent;
- sys_res = 0;
+ int sys_res = 0;
if (tcp->qual_flg & QUAL_RAW) {
/* sys_res = printargs(tcp); - but it's nop on sysexit */
} else {
tprints(") ");
tabto();
- u_error = tcp->u_error;
+ unsigned long u_error = tcp->u_error;
if (tcp->qual_flg & QUAL_RAW) {
if (u_error) {
tprints(" (INJECTED)");
}
else if (!(sys_res & RVAL_NONE) && u_error) {
+ const char *u_error_str;
+
switch (u_error) {
/* Blocked signals do not interrupt any syscalls.
* In this case syscalls don't return ERESTARTfoo codes.
#else
# error Neither ARCH_PC_REG nor ARCH_PC_PEEK_ADDR is defined
#endif
+ get_regs(tcp->pid);
if (get_regs_error || ARCH_GET_PC)
tprints(current_wordsize == 4 ? "[????????] "
: "[????????????????] ");
#endif /* ARCH_REGS_FOR_GETREGSET || ARCH_REGS_FOR_GETREGS */
-void
+static void
get_regs(pid_t pid)
{
#undef USE_GET_SYSCALL_RESULT_REGS
#ifdef ptrace_getregset_or_getregs
+ if (get_regs_error != -1)
+ return;
+
# ifdef HAVE_GETREGS_OLD
/*
* Try PTRACE_GETREGSET/PTRACE_GETREGS first,
int
get_scno(struct tcb *tcp)
{
+ get_regs(tcp->pid);
+
if (get_regs_error)
return -1;