9

I'm trying to verify the functionality of functions in a shared object library. In programs with a main function, I would simply start the program and gdb would automatically breakpoint on main, but that's obviously not available here.

Let's say I have some add.c:

long add(long x, long y) {
    return x + y;
}

I compile this with gcc -shared -o libadd.so -fPIC add.c and load it into GDB:

(gdb) file libadd.so
Reading symbols from libadd.so...(no debugging symbols found)...done.
(gdb) start
Function "main" not defined.
Make breakpoint pending on future shared library load? (y or [n])
Starting program: /tmp/minimal/libadd.so

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000001 in ?? ()

Preferably, I would like to be able to use gdb similar to below:

(gdb) file libadd.so
Reading symbols from libadd.so...(no debugging symbols found)...done.
(gdb) call (long)add(5,6)
$1 = 11

But this call results in You can't do that without a process to debug.

Can I debug libraries like this in GDB?

Addison Crump
  • 666
  • 5
  • 19
  • 1
    Nice canonical question. +1 for both. – S.S. Anne Jan 11 '20 at 01:51
  • 1
    @JL2210 Took me a solid 3 or 4 hours to figure this out yesterday. Figured it might be useful in the future for someone else since this strikes me as something that would be a fairly common problem. – Addison Crump Jan 11 '20 at 01:59
  • You should accept your own answer now to make this question look as answered in the list of questions. – Ruslan Mar 28 '20 at 11:11

2 Answers2

5

You can do so with starti, as shown below:

(gdb) file libadd.so
Reading symbols from libadd.so...(no debugging symbols found)...done.
(gdb) starti
Starting program /tmp/minimal/libadd.so

Program stopped.
0x00007ffff7dfd4a0 in deregister_tm_clones ()
(gdb) call (long)add(5,6)
$1 = 11

You can also do this with binaries containing a main function, as seen in this similar question.

Addison Crump
  • 666
  • 5
  • 19
2

One way you can do this is by creating a dummy executable that links the shared library:

#include "thelib.h"

int main(int argc, char** argv) {
    if (argc == 100000) {
        // Call any function from the library, so that the shared library will be used
        sub(0, 0);
    }
}

Then, compile and debug this executable, linking to the shared library:

$ gdb dummy
(gdb) start
(gdb) call (long)add(5, 6)
Justin
  • 24,288
  • 12
  • 92
  • 142