2

假设我通过创建一个共享对象并使用 LD_PRELOAD 首先加载它来替换一个函数。该函数的参数是否可以与原始库中的参数不同?

例如,如果我替换pthread_mutex_lock,这样就可以使用pthread_my_mutex_t而不是参数pthread_mutex_t。可能吗?

其次,除了函数之外,是否可以使用 LD_PRELOAD 更改结构声明?例如,可以在结构中再添加一个字段。

4

3 回答 3

4

尽管您可以安排提供修改后pthread_mutex_lock()的函数,但代码将被编译为调用标准函数。当使用传递给标准函数的参数调用替换时,这将导致问题。这是一种礼貌的说法:

  • 期待它崩溃和燃烧

任何预加载的函数都必须实现与它所替换的函数相同的接口——相同的名称、相同的参数输入、相同的值输出。内部可以根据需要以不同的方式实现,但接口必须相同。

与结构类似。现有代码被编译为期望结构的一种尺寸,一种特定的布局。您可能会在最后添加一个额外的字段,但未替换的代码可能无法正常工作。它将为结构的原始大小而不是增强的结构等分配空间。它永远不会访问额外的元素本身。这可能不是完全不可能,但是您必须设计程序来处理动态变化的结构大小,这对您何时可以做到这一点施加了足够严格的限制,以至于“您不能”的答案可能是恰当的(当然很多更简单)。

IMNSHO,LD_PRELOAD 机制用于紧急情况(并且是给定问题的临时创可贴)。这不是您应该计划在任何远程类似定期使用的机制。

于 2012-06-03T16:32:59.097 回答
2

LD_PRELOAD 做一件事,而且只做一件事。它将特定的 DSO 文件安排在 ld.so 用于查找符号的列表的前面。它与代码一旦找到后如何使用函数或数据项无关。

您可以使用 LD_PRELOAD 执行的任何操作,只需将替换库与列表前面的 -l 链接即可进行模拟。另一方面,如果使用 -l 无法完成任务,则无法使用 LD_PRELOAD 完成任务。

于 2012-06-03T16:28:29.647 回答
0

您所描述的效果在概念上与在正常链接时提供不匹配的外部函数的效果相同:未定义的行为。

如果你想这样做,而不是玩火,为什么不让你的替换函数也pthread_mutex_t *作为它的参数类型,然后pthread_my_mutex_t *在函数体中转换指针呢?通常,无论如何,这种转换只会在源级别发生;不应为其生成任何代码。

于 2012-06-03T16:43:18.267 回答