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!

+3


source to share


3 answers


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 example
export 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

...

+2


source


Since it is a dinâmica variable, libvar is not securely heap allocated and can be modified by other programs in the OS that use the same memory.



The best practice is to use a constant or pass a value every time it is called if you need to change it.

-1


source


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.

-1


source







All Articles