gdb not loading symbols when running standalone shared library

2.8k Views Asked by At

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.

  1. Why is gdb behaving differently in both these cases?
  2. How can i manually point gdb to the shared library if i am running gdb directly on the 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 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.

2

There are 2 best solutions below

7
On BEST ANSWER

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.

2
On

the easy fix.... recompile the library with (for gcc) the parameter '-ggdb' Then it will have all the symbols available to gdb.