I was working on making an interception library (on Linux); which I pre-load before I run the application that I need to use it for. This is intended to perform redirection.
In my library, I have the __attribute__ constructor(())
to set up the environment that is needed to be run before any resolutions to the calls defined in my library are made.
Now, my assumption was that at runtime, this constructor will be called before any resolutions have been made to the functions that I have defined in this library. For example, let’s say that I was intercepting the ioctl
function. My assumption was that the dynamic linker would only resolve any calls (and call them) ONLY after the __attribute__ constructor(())
has run; or at-least run the ctor when the first call to ioctl
was made, and the loader is resolving it.
But to my surprise, it happens to be the case that the ctor is delayed (on average by 17-30 milliseconds). The ctor is indeed called, but it is delayed. There are calls redirected to my version of ioctl
before the ctor has even executed.
I have made attempts to understand the stuff that happens between the program getting loaded, but it was challenging to come to any conclusion. I would really appreciate it to know the details behind such an execution.
The way I compile my shared library is:
g++ my_lib.cpp -shared -fPIC -o my_lib.so
And then, I load it with my application as:
LD_PRELOAD="./my_lib.so" ./{my_application_executable}