Why is the program printing the wrong value of the global shared object variable?
I have built a shared object from the following code C
using the following command:
gcc -fPIC -shared libx.c -o libx.so
libx.c
extern int printf(const char *, ...);
int libvar = 250;
void libfunc(){
printf("%d,",libvar);
}
Then I linked the following C
code to the library libx.so
with the following command:
gcc -no-pie -lx -L ./ -o main main.c
-no-pie: Tell the compiler to create an ELF executable instead of a shared object (due to what my compiler does by default).
main.c
extern void libfunc();
int main(){
libfunc();
}
Now, when theoretically running the program, the dynamic loader will map the shared library libx.so
somewhere in the address space of the running process (./main) and will resolve symbols libfunc
and libvar
(By changing stuff in .got
and .plt
for segments PIC
), it will eventually resolve the symbol printf
and then print the value libvar
that is 250
.
But the program prints some strange value:
root@afr0ck:~# ./main; printf "\n"
-1076465840
I've debugged for a long time to figure out what's going on, but I can't figure it out!
source to share
I modified your example a bit. Mine libfunc
contains:
void libfunc(){
printf("in libfunc libvar=%d\n",libvar);
}
Note that the order of the arguments gcc
matters (and your arguments gcc
are in the wrong order). More on Calling GCC .
I have compiled your library with
gcc -fPIC -shared -Wall libx.c -o libx.so
Then I compiled yours main.c
with
gcc -Wall main.c -L. -lx -o main
Then execution ended with
./main: error while loading shared libraries: libx.so: cannot open
shared object file: No such file or directory
And that's ok, see ld-linux (8)
To fix this error, either explicitly set LD_LIBRARY_PATH
to contain a directory having libx.so
(for example .
) eg. by typing the same terminal that starts your program, for exampleexport LD_LIBRARY_PATH=.
or set rpath appropriately by compiling your program with
gcc -Wall main.c -Wl,-rpath,. -L. -lx -o main
In both cases, I get
in libfunc libvar=250
as expected at startup ./main
BTW, using strace (1) would help you find your error (not in the code you are showing, but in the wrong system configuration), And you could also compile both the library and the executable with -g
and then use the debugger gdb
...
source to share
Someone pointed out what the library is in /lib
, so I went to check it out, and I found out that I was using the wrong library that defined the same symbols libfunc
and libvar
, and there libfunc
was another in the function printf
that was causing the program to print the wrong value.
So, technically, the difference between the two libraries was in the format string argument in printf
, which I didn't check when debugging.
source to share