Add helper functions to clear/restore syserror

* defs.h (temporarily_clear_syserror, restore_cleared_syserror):
New prototypes.
* syscall.c (saved_u_error): New variable.
(temporarily_clear_syserror, restore_cleared_syserror): New functions.
* aio.c (sys_io_getevents): Use temporarily_clear_syserror
and restore_cleared_syserror.
* mq.c (sys_mq_timedreceive): Likewise.
* signal.c (sys_rt_sigtimedwait): Likewise.
This commit is contained in:
Дмитрий Левин 2015-09-18 01:54:59 +00:00
parent 593602ce5a
commit 3858b93ad9
5 changed files with 41 additions and 0 deletions

7
aio.c
View File

@ -244,7 +244,14 @@ SYS_FUNC(io_getevents)
tprints("], ");
}
/*
* Since the timeout parameter is read by the kernel
* on entering syscall, it has to be decoded the same way
* whether the syscall has failed or not.
*/
temporarily_clear_syserror(tcp);
print_timespec(tcp, tcp->u_arg[4]);
restore_cleared_syserror(tcp);
}
return 0;
}

3
defs.h
View File

@ -538,6 +538,9 @@ extern void get_regs(pid_t pid);
extern int get_scno(struct tcb *tcp);
extern const char *syscall_name(long scno);
extern void temporarily_clear_syserror(struct tcb *);
extern void restore_cleared_syserror(struct tcb *);
extern int umoven(struct tcb *, long, unsigned int, void *);
#define umove(pid, addr, objp) \
umoven((pid), (addr), sizeof(*(objp)), (void *) (objp))

7
mq.c
View File

@ -59,7 +59,14 @@ SYS_FUNC(mq_timedreceive)
else {
printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
tprintf(", %lu, %ld, ", tcp->u_arg[2], tcp->u_arg[3]);
/*
* Since the timeout parameter is read by the kernel
* on entering syscall, it has to be decoded the same way
* whether the syscall has failed or not.
*/
temporarily_clear_syserror(tcp);
printtv(tcp, tcp->u_arg[4]);
restore_cleared_syserror(tcp);
}
return 0;
}

View File

@ -673,7 +673,16 @@ SYS_FUNC(rt_sigtimedwait)
/* syscall exit, and u_arg[1] was NULL */
return 0;
}
/*
* Since the timeout parameter is read by the kernel
* on entering syscall, it has to be decoded the same way
* whether the syscall has failed or not.
*/
temporarily_clear_syserror(tcp);
print_timespec(tcp, tcp->u_arg[2]);
restore_cleared_syserror(tcp);
tprintf(", %lu", tcp->u_arg[3]);
return 0;
};

View File

@ -1131,6 +1131,21 @@ trace_syscall(struct tcb *tcp)
trace_syscall_exiting(tcp) : trace_syscall_entering(tcp);
}
static int saved_u_error;
void
temporarily_clear_syserror(struct tcb *tcp)
{
saved_u_error = tcp->u_error;
tcp->u_error = 0;
}
void
restore_cleared_syserror(struct tcb *tcp)
{
tcp->u_error = saved_u_error;
}
/*
* Cannot rely on __kernel_[u]long_t being defined,
* it is quite a recent feature of <asm/posix_types.h>.