我认为valgrind中的包装框架非常好。我试图跟踪不同代码路径之间的差异(至于为什么一个工作而另一个不工作)。而不是试图看看strace
输出的差异(这不会给我所有我需要的细节,因为我想跟踪lib和sys调用,所以我决定围绕少数几个函数使用包装。valgrind包装可变参数?
一个函数让我抓我的头是fcntl
。
但是fcntl手册页声明为如下
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock *lock);
然而,因为这是C
和超载并不自然而然地C
,它的原型为fcntl.h
如下
extern int fcntl (int __fd, int __cmd, ...);
终端用户包装设备在Valgrind的支持WORD参数N多,但携带使用了错误的号码args来一个警告,我没有看到任何可变参数一提。
像printf
这样的更经典的可变参数函数通常使用较低的固定参数函数vprintf
来实现,它将va_list
作为单个参数。在这种情况下,我会包装vprintf
而不是printf
,但唉AFAIK fcntl
没有这样的中间功能。
我的问题是 - fcntl
的“安全”包装会是什么样子?
例如,下面的似乎工作,但它是安全的:
int I_WRAP_SONAME_FNNAME_ZU(libcZdsoZa,fcntl)(int fd, int cmd, ...)
{
int result;
OrigFn fn;
void* arg;
va_list argp;
va_start(argp, cmd);
arg=va_arg(argp, void*);
VALGRIND_GET_ORIG_FN(fn);
printf("@@fcntl wrapper: args fd=%d, cmd=%d, arg=%p ... ", fd, cmd, arg);
CALL_FN_W_WWW(result, fn, fd, cmd, arg);
printf("##fcntl wrapper: result %d\n", result);
return result;
}