假设我通过创建共享对象并使用LD_PRELOAD首先加载它来替换函数。是否可以让该函数的参数与原始库中的参数不同?
例如,如果我替换 pthread_mutex_lock ,那么取代参数 pthread_mutex_t 需要 pthread_my_mutex_t 。有可能吗?
其次,除了函数之外,是否可以使用LD_PRELOAD更改结构声明?例如,可以向结构添加一个字段。
答案 0 :(得分:3)
虽然您可以安排提供修改后的pthread_mutex_lock()
函数,但代码将被编译为调用标准函数。当使用传递给标准函数的参数调用替换时,这将导致问题。这是一种礼貌的说法:
任何预加载的函数都必须实现相同的接口 - 相同的名称,相同的参数,相同的值 - 与它替换的函数相同。内部可以根据需要实现,但界面必须相同。
与结构类似。编译现有代码以期望结构的一个大小,具有一个特定布局。您可能会在最后添加一个额外的字段,但未替换的代码可能无法正常工作。它将为原始结构大小分配空间,而不是增强结构等。它永远不会访问额外元素本身。它可能并非完全不可能,但您必须设计程序来处理动态变化的结构大小,这会对您何时可以做到严重的限制,使得“您不能”的答案可能是适当的(并且当然很多)更简单)。
IMNSHO,LD_PRELOAD机制适用于紧急情况(并且是针对特定问题的临时创可贴)。这不是一个你应该计划用于任何远程类似的机制。
答案 1 :(得分:2)
LD_PRELOAD只做一件事,只做一件事。它安排特定的DSO文件位于列表的前面,ld.so用它来查找符号。它与代码在找到后如何使用函数或数据项无关。
你可以用LD_PRELOAD做任何事情,只需将替换库与列表前面的-l链接即可进行模拟。另一方面,如果您无法使用-l完成任务,则无法使用LD_PRELOAD执行此任务。
答案 2 :(得分:0)
您所描述的内容的影响在概念上与在正常链接时提供不匹配的外部函数的影响相同:未定义的行为。
如果你想这样做,而不是玩火,你为什么不让你的替换函数也以pthread_mutex_t *
为参数类型,然后只需将指针转换为pthread_my_mutex_t *
in功能体?通常情况下,此转换仅在源级别进行;不应该为它生成代码。