gdb7.7 does not load shared libraries - gdb

Perhaps, i misunderstand something, but i can't make Gdb to read debug libraries.
what i do from command line is:
gdb
file problem_exec
b main
r
GDB stops at:
(gdb) r
Starting program: /Users/.../problem_exec
Breakpoint 1, main (argc=<error reading variable: Could not find the frame base for "main(int, char**)".>, argv=<error reading variable: Could not find the frame base for "main(int, char**)".>)
No shared libraries:
(gdb) info shared
No shared libraries loaded at this time.
The last command gives: "No shared libraries loaded at this time."
My .gdbinit looks like:
# file .gdbinit
set stop-on-solib-events 1
# stop gdb from stepping over functions and output diagnostics
set step-mode on
set breakpoint pending on
set env DYLD_LIBRARY_PATH path1:path2:path3
#automatically load shared libraries (on/off):
set auto-solib-add on
I am sure that an executable is linked against debug version of the shared libraries (in total there are some 30 libraries, but the one I am interested in is definitely compiled in a debug mode). I checked it with otool -L problem_exec
If I run program, it goes until a run-time error in the library I want to debug, but i can not step in.
Am I missing something?
p.s. I run self-compiled version of Gdb on os-x.
UPDATE: it could be related to this problem.

set stop-on-solib-events 1
With that setting, GDB should stop before any shared libraries are loaded.
When you do this:
file problem_exec
b main
r
... where is GDB stopped?
info shared
If GDB is stopped at main, then shared libraries should be loaded. But if it is stopped in the dynamic loader (as I expect it is), then they should not be loaded yet.

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.

Program is unable to find .so files when running through gdb [duplicate]

This question already has answers here:
gdb can not open shared object file
(2 answers)
Closed 3 years ago.
Im trying to debug my c++ program. I can run it fine normally but when I attempt to run the exe through gdb it suddenly cant find my so files. The directory is in my path and when I try "show environment" in gdb the path still shows the directory but it cant find the so files.
I ran
gdb --args ${EXE} ${ARGS}
and I get back
error while loading shared libraries: libX.so: cannot open shared object file: No such file or directory.
You should check the shared library search path using the command:
(gdb) set solib-search-path.
To check which libraries are already loaded:
(gdb) info sharedlibrary.
To manually load a shared library if it is not loaded: (gdb) sharedlibrary libTest.
The following command may also be useful to check which files have their symbols loaded already: (gdb) info sources.

Force gdb to use provided thread lib

I have an embedded ARM application which is bundled with all the so-libraries stripped, including the libpthread.so. Sometimes the application gets stuck in some part of code and I want to be able to attach to it with gdb and see what's going on. The problem is that gdb refuses to load the needed threading support library, with the following messages:
Trying host libthread_db library: /home/me/debug_libs/libthread_db.so.1.
td_ta_new failed: application not linked with libthread
thread_db_load_search returning 0
warning: Unable to find libthread_db matching inferior's thread
library, thread debugging will not be available.
Because of this I cannot debug the application, e.g. I cannot see current call stacks for all threads.
After some investigation I suspect that the td_ta_new failing with the application not linked with libthread is caused by the stripped version of libpthread, which lacks the nptl_version symbol. Is there any way to bypass the error?
The gdb is compiled for ARM and being run on the device itself. I have unstripped versions of the libraries, but the application is already running with the stripped libraries.
Is there any way to bypass the error?
A few ways that come to mind:
Use add-symbol-file to override the stripped libpthread.so.0 with un-stripped one:
(gdb) info shared libpthread.so
# shows the path and memory address where stripped libpthread.so.0 is loaded
(gdb) add-symbol-file /path/to/unstripped/libpthread.so.0 $address
# should override with new symbols, and attempt to re-load libthread_db.so.1
Run gdb -ex 'set sysroot /path/to/unstripped' ... where /path/to/unstripped is the path that mirrors installed tree (that is, if you are using /lib/libpthread.so.0, there should be /path/to/unstripped/lib/libpthread.so.0.
I have not tested this, but I believe it should work.
You could comment out the version check in GDB and rebuild it.

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.

GDB Loading the incorrect library

I have two different version of a library let's say
libxyz.so
at two different location
1) /home/maverick/dev/libxyz.so ( development Version)
2) /home/maverick/prod/libxyz.so ( Production Version )
I have a setup that compile my program and link with appropriate version of the library depending on LD_LIBRARY_PATH. for example If I want to link my program with dev version of libxyz.so i change my LD_LIBRARY_PATH to add /home/maverick/dev and if I want to link with prod version I change LD_LIBRARY_PATH to add /home/maverick/prod instead.
I compiled my program by linking with dev version and the output of
ldd MyProg
is
libxyz.so => /home/maverick/dev/libxyz.so
If i run the program it loads the libxyz.so from
/home/maverick/dev/libxyz.so
and runs fine.
it this point my LD_LIBRARY_PATH includes /home/maverick/dev not /home/maverick/prod
but when I try to debug this program through GDB
gdb MyProg
it loads the libxyz.so from location
/home/maverick/prod/libxyz.so
I have trouble making GDB load the correct version of the library during debug. So till now what I am doing is first launch the program (that load the dev version) and attach gdb to that PID this way its works fine. but if it run like
gdb MyProg
it dosen't
I tried every thing to fix this like setting up sysroot, solib-search-path in GDB but nothing is working.
if fact when I set up sysroot to point to the debug version of the library gdb gave some message like
.dynamic section for XXX is not at the expected address
any suggestion would be appreciated.
I have trouble making GDB load the correct version of the library during debug.
Let me guess: you are using tcsh, right?
The problem most likely comes from yoour ~/.cshrc resetting LD_LIBRARY_PATH to /home/maverick/prod.
When you run the program in GDB, it executes $SHELL -c your-program [args...] (so as to allow you to use I/O redirection).
Solution: don't touch environment in your .cshrc for non-interactive shell, e.g. start it with:
if ($?prompt == 0) exit