我認爲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;
}