随应用程序预加载时共享库构造函数调用的延迟

问题描述 投票:0回答:1

我正在制作一个拦截库(在Linux上);我在运行需要使用它的应用程序之前预先加载它。这是为了执行重定向。

在我的库中,我有

__attribute__ constructor(())
来设置在对我的库中定义的调用进行任何解析之前需要运行的环境。

现在,我的假设是,在运行时,将在对此库中定义的函数做出任何解析之前调用此构造函数。例如,假设我正在拦截

ioctl
函数。我的假设是动态链接器只会在
__attribute__ constructor(())
运行之后解析任何调用(并调用它们);或者至少在第一次调用
ioctl
时运行 ctor,并且加载器正在解析它。 但令我惊讶的是,ctor 却出现了延迟(平均 17-30 毫秒)。确实呼叫了 ctor,但延迟了。在 ctor 执行之前,有一些调用被重定向到我的
ioctl
版本。

我尝试了解程序加载之间发生的事情,但得出任何结论都很困难。我真的很感激知道这样的执行背后的细节。

我编译共享库的方式是:

g++ my_lib.cpp -shared -fPIC -o my_lib.so

然后,我将其与我的应用程序一起加载:

LD_PRELOAD="./my_lib.so" ./{application_executable}
c++ shared-libraries
1个回答
0
投票

现在,我的假设是,在运行时,将在对此库中定义的函数做出任何解析之前调用此构造函数。

这确实是一个合理的期望。

但令我惊讶的是,ctor 竟然出现了延迟(平均 17-30 毫秒)。确实呼叫了 ctor,但延迟了。在 ctor 执行之前,有一些调用被重定向到我的 ioctl 版本。

有几种可能的解释:

  1. 您误解了您的观察结果
  2. ld-linux
    本身调用
    ioctl
    作为其自身初始化的一部分
  3. 您的
    constructor
    例程会调用
    ioctl
    本身
  4. 您创建与您的
    constructor
  5. 并行运行的线程
  6. 还有其他事情我没有想到......

在没有更多细节的情况下,无法判断以上哪个原因才是真正的原因。

调试此问题的一种方法是将无限循环放入您的

ioctl
插入器中(参见例如此 answer),然后运行程序。它应该阻止。一旦完成,将调试器附加到它,并找出 where
ioctl
是从哪里调用的。

© www.soinside.com 2019 - 2024. All rights reserved.