I have a PIC shared library which also has a main function
#include <dtest2.h>
#include <stdio.h>
extern const char elf_interpreter[] __attribute__((section(".interp"))) = "/lib/ld-linux.so.2";
int dtestfunc1(int x,int y) {
int i=0;
int sum = 0;
for(i=0;i<=x;i++) {
sum+=y;
sum+=dtestfunc2(x,y);
}
return sum;
}
int main (int argc, char const* argv[])
{
printf("starting sharedlib main\n");
int val = dtestfunc1(4,5);
printf("val = %d\n",val);
_exit(0);
}
This library is linked to another shared library libdtest2 which has the implementation of dtestfunc2 called from dtestfunc1.
If i run gdb directly on dtestfunc1 using
gdb libdtest1.so
the symbols for libdtest2.so are not loaded by gdb. I cannot step into dtestfunc1 because of this and if i press s, the function just executes and gets out.
If i create a driver program which calls dlopen on the shared library, gdb loads the symbols properly after dlopen is executed and everything works fine.
Note: This is a toy example that mirrors my problem for a much larger shared library. All my binaries and libraries are compiled with the -ggdb3 flag.
Edit: My shared library is runnable. I added the proper interpreter path using the extern definition in the source code. I compiled it with gcc -ggdb3 -O0 -shared -Wl,-soname,libdtest1.so.1 -ldtest2 -L/usr/lib -Wl,-e,main -o libdtest1.so.1.0 dtest1.o.
I can run it and it executes perfectly.Running the shared library is not the issue here.
Why is gdb behaving differently in both these cases?
Because you didn't build libdtest1.so correctly for GDB to work with it.
In particular, your libdtest1.so is lacking DT_DEBUG entry in its dynamic section, which you can confirm like so:
readelf -d libdtest1.so | grep DEBUG
You should see nothing. In a correctly built runnable libdtest1.so (which you can build using -pie flag), the output should look like this:
0x00000015 (DEBUG) 0x0
The runtime loader updates DT_DEBUG to point to its r_debug structure, which then allows GDB to find other loaded shared libraries. Without DT_DEBUG, GDB can't find them.
Update:
After adding the pie flag my build command is
gcc -ggdb3 -O0 -pie -shared -Wl,-soname,libdtest1.so.1 -ldtest2 -L/usr/lib -Wl,-e,main -o libdtest1.so.1.0 dtest1.c -I.The DEBUG section is still missing
Terminology: it's not a DEBUG section. It's a DT_DEBUG entry in the .dynamic section.
It is still missing because -shared overrides -pie. Remove -shared from the link line.
You would also not need -Wl,-e,main, nor would you need to specify the .interp -- GCC will do that for you.
The correct link command:
gcc -ggdb3 -O0 -pie -rdynamic dtest1.c -I. -Wl,-soname,libdtest1.so.1 \
-L/usr/lib -ldtest2 -o libdtest1.so.1.0
(Order of sources and libraries on the link line matters, yours is wrong.)
Added bonus: your main will receive correct argc and argv[], instead of bogus values you are getting now.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With