Some syscall improvements:

- made pre_mem_read etc. calls more concise by improving the macros used
- made printing calls more concise by renaming the macro used
- updated README_MISSING_SYSCALL_OR_IOCTL
- improved --trace-syscalls=yes;  a bit neater, and now prints return values
  for all syscalls.
- introduced LOHI64 macro for 64-bit args that are created from 2 32-bit args
- 64-bit cleanness tweaks for *xattr* syscall printing


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2941
This commit is contained in:
Nicholas Nethercote 2004-11-06 15:38:43 +00:00
parent 05dfa7bb25
commit 7fbab350e1
4 changed files with 836 additions and 995 deletions

View File

@ -49,16 +49,16 @@ Removing the debug printing clutter, it looks like this:
PRE(time)
{
/* time_t time(time_t *t); */
MAYBE_PRINTF("time ( %p )\n",arg1);
if (arg1 != (UInt)NULL) {
SYSCALL_TRACK( pre_mem_write, tid, "time", arg1, sizeof(time_t) );
PRINT("time ( %p )",arg1);
if (arg1 != (UWord)NULL) {
PRE_MEM_WRITE( "time", arg1, sizeof(time_t) );
}
}
POST(time)
{
if (arg1 != (UInt)NULL) {
VG_TRACK( post_mem_write, arg1, sizeof(time_t) );
if (arg1 != (UWord)NULL) {
POST_MEM_WRITE( arg1, sizeof(vki_time_t) );
}
}
@ -66,8 +66,8 @@ The first thing we do happens before the syscall occurs, in the PRE() function:
if a non-NULL buffer is passed in as the argument, tell the tool that the
buffer is about to be written to:
if (arg1 != (UInt)NULL) {
SYSCALL_TRACK( pre_mem_write, tst, "time", arg1, sizeof(time_t) );
if (arg1 != (UWord)NULL) {
PRE_MEM_WRITE( "time", arg1, sizeof(vki_time_t) );
}
Finally, the really important bit, after the syscall occurs, in the POST()
@ -75,7 +75,7 @@ function: if, and only if, the system call was successful, tell the tool that
the memory was written:
if (arg1 != (UInt)NULL) {
VG_TRACK( post_mem_write, arg1, sizeof(time_t) );
POST_MEM_WRITE( arg1, sizeof(vki_time_t) );
}
The POST() function won't be called if the syscall failed, so you
@ -85,6 +85,11 @@ they "fail" - for example, nanosleep returns the amount of unslept
time if interrupted. TODO: add another per-syscall flag for this
case.)
Note that we use the type 'vki_time_t'. This is a copy of the kernel
type, with 'vki_' prefixed. Our copies of such types are kept in the
appropriate vki*.h file(s). We don't include kernel headers or glibc headers
directly.
Writing your own syscall wrappers (see below for ioctl wrappers)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -98,6 +103,7 @@ following:
This should tell you something like __NR_mysyscallname.
Copy this entry to coregrind/$(VG_PLATFORM)/vki_unistd.h.
2. Do 'man 2 mysyscallname' to get some idea of what the syscall
does. Note that the actual kernel interface can differ from this,
so you might also want to check a version of the Linux kernel
@ -112,13 +118,13 @@ following:
coregrind/vg_syscalls.c. For each in-memory parameter which is
read or written by the syscall, do one of
SYSCALL_TRACK( pre_mem_read, ... )
SYSCALL_TRACK( pre_mem_read_asciiz, ... )
SYSCALL_TRACK( pre_mem_write, ... )
PRE_MEM_READ( ... )
PRE_MEM_RASCIIZ( ... )
PRE_MEM_WRITE( ... )
for that parameter. Then do the syscall. Then, if the syscall
succeeds, issue suitable VG_TRACK( post_mem_write, ... ) calls.
(There's no need for post_mem_read calls.)
succeeds, issue suitable POST_MEM_WRITE( ... ) calls.
(There's no need for POST_MEM_READ calls.)
Also, add it to the sys_info[] array; use SYSBA if it requires a
PRE() and POST() function, and SYSB_ if it only requires a PRE()
@ -137,7 +143,7 @@ following:
Test it.
Note that a common error is to call VG_TRACK( post_mem_write, ... )
Note that a common error is to call POST_MEM_WRITE( ... )
with 0 (NULL) as the first (address) argument. This usually means
your logic is slightly inadequate. It's a sufficiently common bug
that there's a built-in check for it, and you'll get a "probably

View File

@ -1014,15 +1014,16 @@ static void sys_wait_results(Bool block, ThreadId tid, enum RequestType reqtype,
case PX_SetSigmask:
/* Don't need to do anything */
if (VG_(clo_trace_signals) || VG_(clo_trace_syscalls))
VG_(message)(Vg_DebugMsg, "sys_wait_results: got PX_SetSigmask for TID %d",
VG_(printf)("sys_wait_results: got PX_SetSigmask for TID %d\n",
res.tid);
break;
case PX_RunSyscall:
if (VG_(clo_trace_syscalls))
VG_(message)(Vg_DebugMsg, "sys_wait_results: got PX_RunSyscall for TID %d: syscall %d result %lld",
res.tid, tst->syscallno,
(ULong)PLATFORM_SYSCALL_RET(tst->arch));
VG_(printf)("sys_wait_results: got PX_RunSyscall for SYSCALL[%d,%d](%3d) --> %lld (%llx)\n",
VG_(getpid)(), res.tid, tst->syscallno,
(Long)(Word)PLATFORM_SYSCALL_RET(tst->arch),
(ULong)PLATFORM_SYSCALL_RET(tst->arch));
if (tst->status != VgTs_WaitSys)
VG_(printf)("tid %d in status %d\n",
@ -1055,8 +1056,8 @@ static void sys_wait_results(Bool block, ThreadId tid, enum RequestType reqtype,
}
if (VG_(clo_trace_signals) || VG_(clo_trace_syscalls))
VG_(message)(Vg_DebugMsg, "sys_wait_results: got PX_Signal for TID %d, signal %d",
res.tid, res.u.siginfo.si_signo);
VG_(printf)("sys_wait_results: got PX_Signal for TID %d, signal %d\n",
res.tid, res.u.siginfo.si_signo);
vg_assert(res.u.siginfo.si_signo != 0);
if (VG_(threads)[res.tid].proxy &&

File diff suppressed because it is too large Load Diff

View File

@ -110,7 +110,7 @@ extern Addr VG_(do_useseg) ( UInt seg_selector, Addr virtual_addr );
#define PLATFORM_GET_MMAP_ARGS(tst, a1, a2, a3, a4, a5, a6) do {\
UInt *arg_block = (UInt*)PLATFORM_SYSCALL_ARG1(tst->arch); \
SYSCALL_TRACK( pre_mem_read, tst->tid, "mmap(args)", arg1, 6*sizeof(UWord) ); \
PRE_MEM_READ( "mmap(args)", arg1, 6*sizeof(UWord) ); \
a1 = arg_block[0]; \
a2 = arg_block[1]; \
a3 = arg_block[2]; \