setting gdb breakpoint inside shared object file - c++

I have an executable that dynamically loads a shared object library, let say foo.so. I do not build foo.so and it is given to me as a library to use in my code. foo.cpp compiles to give foo.so. I do not have access to foo.cpp but have foo.so. I want to set a breakpoint when my executable calls a function inside this shared library foo.so (that is when function inside foo.cpp is called). Is their a way in gdb to do so?
I have tried
gdb funcname
but it does not seem to work. Any pointers how to break gdb at that point?

Is their a way in gdb to do so?
Yes.
I have tried gdb funcname
That wouldn't work. You need to run gdb exename, then break funcname at the (gdb) prompt.
At that point, GDB will likely inform you that funcname does not yet exist (since you haven't yet dynamically loaded foo.so), and will ask you whether you want to create a deferred breakpoint. You should answer yes, and GDB will retry setting this breakpoint every time a new shared library is loaded. Eventually this will succeed, and you should get the breakpoint set (automatically and silently), and when you call the funcname later, that breakpoint will fire and GDB will stop (which is exactly what you want).

Related

gdb: how to learn which shared library loaded a shared library in question

I need to get the list of shared libraries used by an app in runtime. Most of them can be listed by ldd, but some can be seen only with gdb -p <pid> and by running the gdb command info sharedlib.
It would really help, if I could learn in some way: for a chosen library (in the list, output by info sharedlib), which library (of the same list) had caused to load it. Is there any way to learn it in gdb or in some other way? Because sometimes, I see a loaded library in the list and cannot get why it is there and which (probably, previously loaded in memory) library loaded it.
UPDATE:
I attach a screen shot of gdb showing the info that I need. I used breakpoint on dlopen, as it was suggested in comments and in the answer. The command x/s $rdi prints out the first argument of dlopen, as by Linux System V ABI, i.e. it prints the name if the library, about which I want to learn who loaded it (libdebuginfod.so.1). I put it here just for those who are curious. In my case, it can be seen, that the libdebuginfod.so.1 was loaded by libdw.so.1 (as shown by bt command).
Is there any way to learn it in gdb or in some other way?
There are a few ways.
You can run the program with env LD_DEBUG=files /path/to/exe.
This will produce output similar to:
LD_DEBUG=files /bin/date
76042:
76042: file=libc.so.6 [0]; needed by /bin/date [0]
It is the needed by part that you most care about.
You could also use GDB and use set set stop-on-solib-events 1. This will produce output similar to:
Stopped due to shared library event:
Inferior loaded /lib/x86_64-linux-gnu/libc.so.6
At that point, you could execute where command and observe which dlopen() call caused the new library to be loaded.
You could also set a breakpoint on dlopen() and do the same.
The stop-on-solib-events may be better if your executable repeatedly dlopen()s the same library -- the library set will not change when you dlopen() the same library again, and you'll stop when you don't care to stop. Setting stop-on-solib-events avoids such unnecessary stops.

Unable to find breakpoint when debugging a cpp source file when invoked from .sh

I need to set breakpoints in a cpp source file. The current setup to call the cpp target is through a shell target, with additional dependencies, which means it's not feasible to directly invoke the cpp target in Linux console.
As I searched online, there are generally two ways:
invoke gdb in shell
pause in cpp, let gdb connect to the process
I don't know how to do the first way, so I choose the second way here.
I insert sleep(30) in cpp file, then in another terminal I open gdb and connect to the running process. I confirm the gdb can stop at the sleep() function in gdb. But the problem is the gdb seems only knowing the sleep function context, without knowing the call site of the sleep function. If I force setting breakpoint in the main program, gdb shows no such file. If I continue in gdb, it will not stop at any breakpoints I set in cpp file.
You need to compile the program with debug symbols. Otherwise GDB will only know of symbols in the dynamic symbol table. Turning off optimizations also helps debugging. So add the flags -O0 -g.
If this is not possible, you'll have have to step through the disassembly (Ctrl+X, 2).

How to set breakpoint with gdb on function from stripped shared library?

I've got an executable file and stripped lib.so file that is used by executable.
I have decompiled lib.so file and defined the function fun I want to set breakpoint and its internal address.
Is it possible to set breakpoint on function fun using gdb?
How to define the address of fun at runtime?
Is it possible to set breakpoint on function fun using gdb?
Yes: GDB can set a breakpoint on arbitrary address:
(gdb) break *0x12345678
How to define the address of fun at runtime?
Since GDB by default disables ASLR, the address of fun will not change from run to run (assuming you run the program under GDB from the start).
Therefore, you only need to find the address of fun once.
Let's assume that your lib.so is linked at 0 (most non-prelinked shared libraries are).
Further let's assume that you are on Linux.
Then info proc map will tell you where the lib.so is loaded (you want the first start address belonging to it). Add that start address to the value of fun you found by disassembling, and set a breakpoint there.

gdb how to set breakpoint in dynamic library opened by dlopen

Afternoon,everbody.
I have an application 'test' compiled by main.c . A dynamic liabrary 'libtest.so' which is compiled by test.cpp with '-g'. In main.c I invoke the 'libtest.so' with 'dlopen' . And now I want to set a breakpoint in test.cpp ,but the gdb never hit it. I do as follow:
gdb ./test -d /home/lcl/test
break test.cpp:35
run
can anybody give me some tips ,thanks!
You should first verify that dlopen is actually succeeding (it's likely that it's not).
To do so:
set a breakpoint in main.c after dlopen.
confirm that returned handle is not NULL
At that point, GDB should have loaded symbols for libtest.so, and libtest.so should show up in info shared GDB output.
If everything looks good, info break should show an active breakpoint in test.cpp:35 at some address. If that breakpoint is never hit, it's likely that you never actually exercise that line of code.

How can I run a program with additional flags in gdb?

I'm trying to test out this answer:
_dl_runtime_resolve -- When do the shared objects get loaded in to memory?
But when I try various ways to run essentially the same as gdb "LD_BIND_NOW=y binary",it fails.
How can I run my app with this flag on inside gdb?
Two choices. First:
env LD_BIND_NOW=y gdb binary
Or, run gdb binary and then inside gdb:
set env LD_BIND_NOW=y
run
The former will affect the gdb binary itself, which may or may not matter. The latter might not actually work :-)