2012-06-25 40 views
3

我想LD_PRELOAD linux的clone函數。在我的LD_PRELOADed版本中,我需要在調用原始clone函數之前記錄輸入參數。但是,問題是clone需要可變數量的參數。它是這樣宣佈的。計算克隆函數的可變參數個數

int clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ... 
/* pid_t *pid, struct user_desc *tls, pid_t *ctid */); 

我們這些參數傳遞給原來的clone功能,我必須知道的都通過了參數的數目。我該怎麼辦呢?

+0

你還碰巧有LD_PRELOAD代碼(或者至少是一些骨架)?因爲我正在嘗試做同樣的事情,並且陷入了clone()varags。根據va_ *的實現來回答已接受的答案,我認爲它只會在堆棧中隨機(隨機)數據。調用者必須始終告訴被調用者使用多少(參數數量,終止符,格式字符串或者某物)。 – fiction

回答

1

如果有一個NULL終止符,則可以調用va_arg,但它不返回NULL

2

使用va_*函數,這些是使用可變參數列表時要走的路。

下面是man page,其中還包含一個例子。

0

man page描述了這樣的原型:

int clone(int (*fn)(void *), void *child_stack, int flags, 
      void *arg, ... /* pid_t *ptid, struct user_desc *tls, pid_t *" ctid "); 

注:我添加了tlspid_t之間的逗號,我認爲有手動的一個錯字。

然後討論參數ptidctid。所以我會繼續檢查文檔,對於這些額外參數被定義的情況,那就是如何從va_list中讀取它們。

1

對此的正確答案是:您無法計算變量參數函數中參數的數量。

然而,對於clone功能,您可以承擔參數的個數通過查看flags說法,因爲某些標誌需要一定的額外的參數。

採取例如CLONE_PARENT_SETTID標誌,在manual page它規定:在父母和孩子的存儲位置點名

店子線程ID。 (在Linux中2.5.32-2.5.48有一個標誌CLONE_SETTID該這樣做。)

因此,如果設置了此標誌,那麼你知道ptid參數應該存在,你可以使用va_*功能得到它。

但是,沒有辦法驗證用戶是否確實通過了參數,這意味着如果用戶沒有填充內容會導致錯誤。

+0

因此,如果設置了CLONE_PARENT_SETTID,那麼您可以假定ptid並且只吃一個參數,如果CLONE_SETTLS您可以預期tls並從堆棧讀取2個參數,並且如果設置了CLONE_CHILD_CLEARTID或CLONE_CHILD_SETTID,則您可以預期3個參數?這個克隆()是可怕的黑客。 – fiction