2012-06-25 42 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