On 2011-02-16, Dmitry V. Levin <[email protected]> wrote:
> Even with these complications, readlink-based approach seems to be
> more reliable and easy to implement and support.
I agree. I've tossed out the fd-tracking code.
Once again, premature optimization proves to be a mistake.
> Another issue is how to match paths reliably without introducing code
> into every parser function. The approach implemented in your
> pathtrace_match() is not capable to handle syscalls that take several
> pathname arguments like rename(2), or pathname argument along with
> descriptor argument like openat(2).
Right. I've extended pathtrace_match so it explicity handles cases
other than a single fd/path in arg[0].
> Possible solution could be extending struct sysent with more generic
> information about syscalls, e.g. with two 8-bit bitsets describing
> pathname-like and descriptor-like arguments.
That's the approach used by the python version of strace: the "sysent"
table contains type and name information about each argument.
It would be cleaner than my approach and keep info on systemcalls more
localized.
Below is the pathtrace_match() function I'm currently using. I don't
like it much because adds another place that contains sycall-specific
information.
Would people be agreeable to adding argument type info (or argument
format function pointers) to the sysent table? In addition to making
the fd/path match function simpler, it might allow the "printargs"
function to handle many more cases.
----------------------------------------------------------------------
// return true if syscall accesses a selected path (or if no paths
// have been specified for tracing).
int pathtrace_match(struct tcb *tcp)
{
char path[1024];
const struct sysent *s;
if (selected[0] == NULL)
return 1;
s = &sysent[tcp->scno];
if (!(s->sys_flags & (TRACE_FILE | TRACE_DESC)))
return 0;
// check for special cases where we need to do something other than
// test arg[0]
#ifdef LINUX
if (s->sys_func == sys_dup3 ||
s->sys_func == sys_sendfile ||
s->sys_func == sys_sendfile64 ||
!strcmp(s->sys_name,"tee"))
{
// fd,fd
return fdmatch(tcp->pid,tcp->u_arg[0]) || fdmatch(tcp->pid,tcp->u_arg[1]);
}
if (s->sys_func == sys_inotify_add_watch ||
s->sys_func == sys_faccessat ||
s->sys_func == sys_fchmodat ||
s->sys_func == sys_futimesat ||
s->sys_func == sys_mkdirat ||
s->sys_func == sys_unlinkat ||
s->sys_func == sys_newfstatat ||
s->sys_func == sys_mknodat ||
s->sys_func == sys_openat ||
s->sys_func == sys_readlinkat ||
s->sys_func == sys_utimensat ||
s->sys_func == sys_fchownat ||
s->sys_func == sys_pipe2)
{
// fd,path
return fdmatch(tcp->pid,tcp->u_arg[0]) ||
(umovestr(tcp,tcp->u_arg[1],sizeof path,path),
pathmatch(tcp->pid,path));
}
if (s->sys_func == sys_link ||
s->sys_func == sys_pivotroot ||
s->sys_func == sys_rename ||
s->sys_func == sys_symlink ||
s->sys_func == sys_mount)
{
// path,path
return (umovestr(tcp,tcp->u_arg[0],sizeof path,path),
pathmatch(tcp->pid,path)) ||
(umovestr(tcp,tcp->u_arg[1],sizeof path,path),
pathmatch(tcp->pid,path));
}
if (s->sys_func == sys_renameat ||
s->sys_func == sys_linkat)
{
// fd,path,fd,path
return fdmatch(tcp->pid,tcp->u_arg[0]) ||
fdmatch(tcp->pid,tcp->u_arg[2]) ||
(umovestr(tcp,tcp->u_arg[1],sizeof path,path),
pathmatch(tcp->pid,path)) ||
(umovestr(tcp,tcp->u_arg[3],sizeof path,path),
pathmatch(tcp->pid,path));
}
if (s->sys_func == sys_old_mmap)
{
// x,x,x,x,fd
return fdmatch(tcp->pid,tcp->u_arg[4]);
}
if (s->sys_func == sys_symlinkat)
{
// path,fd,path
return fdmatch(tcp->pid,tcp->u_arg[1]) ||
(umovestr(tcp,tcp->u_arg[0],sizeof path,path),
pathmatch(tcp->pid,path)) ||
(umovestr(tcp,tcp->u_arg[2],sizeof path,path),
pathmatch(tcp->pid,path));
}
if (s->sys_func == sys_poll ||
s->sys_func == printargs ||
s->sys_func == sys_ppoll ||
s->sys_func == sys_select ||
s->sys_func == sys_oldselect ||
s->sys_func == sys_pselect6 ||
s->sys_func == sys_pipe ||
s->sys_func == sys_pipe2 ||
s->sys_func == sys_eventfd2 ||
s->sys_func == sys_eventfd ||
s->sys_func == sys_inotify_init1 ||
s->sys_func == sys_timerfd_create)
{
// these either return fd's or they do other things we don't
// know how to handle
return 0;
}
#else
# warning "path tracing only using arg[0]"
#endif
if (s->sys_flags & TRACE_FILE)
{
umovestr(tcp,tcp->u_arg[0],sizeof path,path);
return pathmatch(tcp->pid,path);
}
if (s->sys_flags & TRACE_DESC)
{
return fdmatch(tcp->pid,tcp->u_arg[0]);
}
return 0;
}
--
Grant Edwards grant.b.edwards Yow! I feel like a wet
at parking meter on Darvon!
gmail.com
------------------------------------------------------------------------------
The ultimate all-in-one performance toolkit: Intel(R) Parallel Studio XE:
Pinpoint memory and threading errors before they happen.
Find and fix more than 250 security defects in the development cycle.
Locate bottlenecks in serial and parallel code that limit performance.
http://p.sf.net/sfu/intel-dev2devfeb
_______________________________________________
Strace-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/strace-devel