I have recently learned the LD_PRELOAD trick (What is the LD_PRELOAD trick?), which can be used to debug or patch the program.
I wanted to see if I could combine this trick and GCC destructor (https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Function-Attributes.html) to debug a variable, and created an extremely simple case to hone my understanding.
I have test.c
as provided below:
#include <stdio.h>
int a = 1;
void __attribute__((destructor)) run_last() {
printf("Destructor: %d\n", a);
}
and test_2.c
as provided below:
#include <stdio.h>
#include "test.c"
int main()
{
extern int a;
printf("main: %d\n", a++);
}
I compile test.c
using the command gcc -Wall -O3 -fPIC -shared test.c -o test.so
to generate the shared object, and compile test_2.c
using the command gcc test_2.c -o test_2
Now, what I'm hoping to see is an output of:
main: 1
Destructor: 2
The reason for this expectation is because I have post-incremented the variable a
after I printed the statement, and as I am using extern int a
, as far as I understand, I am incrementing the variable a
that was declared in the test_2.c
, which contains the destructor function run_last()
that will use the most updated value of a
.
However, instead, I get an output such as this:
Why is there a Destructor: 1
here? From my understanding, shouldn't the destructor only be called once? My guess at the moment is that when I #include "test.c"
in the test_2.c
, there is a behavior that I don't understand at the moment.
Thank you for any suggestions or guidance,