Gdb does not load symbols when running standalone shared library
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
that has an implementation dtestfunc2
called from dtestfunc1
.
If I run gdb directly on dtestfunc1 using
gdb libdtest1.so
symbols for libdtest2.so are not loaded by gdb. I cannot log in dtestfunc1
because of this, and if I press s, the function just executes and exits.
If I create a driver program that calls dlopen on the shared library, gdb loads the symbols correctly after dlopen is executed and everything works fine.
- Why does gdb behave differently in both cases?
- How can I manually point gdb to a shared library if I run gdb directly on a shared library?
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 running. I added the correct 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 works fine. Shared library exclusion is not a problem here.
source to share
Why does gdb behave differently in both cases?
Since you didn't build correctly libdtest1.so
to get GDB to work with it.
Specifically, yours libdtest1.so
doesn't have an entry DT_DEBUG
in its dynamic section, which you can confirm like this:
readelf -d libdtest1.so | grep DEBUG
You won't see anything. In a well-formed runnable libdtest1.so
(which you can build using a flag -pie
), the output should look like this:
0x00000015 (DEBUG) 0x0
The runtime boot loader updates DT_DEBUG
to point to its structure r_debug
, 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
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.
DEBUG section is still missing
Terminology: This is not a section DEBUG
. This is an entry DT_DEBUG
in the section .dynamic
.
It's still missing as it -shared
overrides -pie
. Remove -shared
from the link line.
You also don't need to -Wl,-e,main
, and you don't need to specify .interp
- GCC will do it for you.
Correct link:
gcc -ggdb3 -O0 -pie -rdynamic dtest1.c -I. -Wl,-soname,libdtest1.so.1 \
-L/usr/lib -ldtest2 -o libdtest1.so.1.0
(Ordering sources and libraries on the link line is significant, i.e. incorrect.)
Added bonus: your main one will get the correct argc
and argv[]
not the bogus values you are getting now.
source to share