I would like to monitor(debug) a linux dynamic library written in C.
I want to see when and what parameters are passed to it.
The library to monitor 'X', is invoked by another dynamic library 'Y'.
Both 'X and 'Y' appear in /proc/pid/maps of the executable 'A'.
Using ltrace, on the executable did not show lib X or Y.
The executable is using multiple threads.
Also, when using ldd command on the exec it doesn't mention anything about libs X or Y.
ldd Y, shows that Y needs X.
Using ldd on all the libs, execs in the project doesn't mention anyone who would need Y.
Yet Y appears to be loaded in the /proc/pid/maps of the exec.
I'm not sure what steps I could take in order to debug the X lib, any advice is appreciated.
If user756235 can run it under gdb then this is an approach using this and this. The only question is to make a full list of functions in a shared library X: nm ./libX.so | grep "T "
And then create .gdbinit (in my case I control args of print_in_lib):
host: srv2-x64rh5-01, OS: Linux 2.6.18-238.el5>more .gdbinit
file main
set pagination off
set logging file gdb.txt
set breakpoint pending on
set logging on
b print_in_lib
commands
info args
continue
end
r
set logging off
quit
And when I run gdb:
host: srv2-x64rh5-01, OS: Linux 2.6.18-238.el5>gdb -q Function
"print_in_lib" not defined. Breakpoint 1 (print_in_lib) pending.
warning: no loadable sections found in added symbol-file
system-supplied DSO at 0x2aaaaaaab000 thousands: 1 print_debug: 0
Breakpoint 1, print_in_lib (print_debug=0, index=0) at my_lib.cpp:7 7
if (print_debug) { print_debug = 0 index = 0
Breakpoint 1, print_in_lib (print_debug=0, index=1) at my_lib.cpp:7 7
if (print_debug) { print_debug = 0 index = 1
Breakpoint 1, print_in_lib (print_debug=0, index=2) at my_lib.cpp:7 7
if (print_debug) { print_debug = 0 index = 2
Breakpoint 1, print_in_lib (print_debug=0, index=3) at my_lib.cpp:7 7
if (print_debug) { print_debug = 0 index = 3
Related
The following workflow worked for me at one point, and then it suddenly stopped working. I'd like to figure out why and get it to work again.
on the host, build binary for target system with debug information
send the stripped version of the binary to the target system
on the target, run the binary with gdbserver :6006 mybinary args...
on the host, run gdb-multiarch mybinary. This is the unstripped version. It shows that it loaded symbols from the local binary.
At the gdb prompt, run target remote <ip_of_target>:6006
Then, if I say b main, it inserts a breakpoint at an unrelocated address like 0x621730, which is the offset of the main function in the local binary, whereas it should be added on top of the VM address the remote binary is loaded at (0x5555555000 in this case.) Obviously the unrelocated address doesn't work.
So step 6 was working at one point. I don't know what I'm doing now differently to make the relocation no longer work. Help would be appreciated.
Version of gdbserver and that of host gdb are both Ubuntu 8.1.1-0ubuntu1. The remote system is aarch64.
So step 6 was working at one point. I don't know what I'm doing now differently to make the relocation no longer work.
I suspect that you have upgraded your toolchain, and that your upgraded toolchain produces a Position-Independent Executable mybinary by default, where the old toolchain didn't.
Try adding -no-pie to the link line of mybinary.
Obviously the unrelocated address doesn't work.
Actually, this does work for local debugging -- GDB is smart enough to realize that the code got loaded at a different address:
gdb -q a.out
Reading symbols from a.out...
(gdb) b main
Breakpoint 1 at 0x112d: file t.c, line 1. <<< Note: unrelocated address
(gdb) run
Starting program: /tmp/a.out
Breakpoint 1, main () at t.c:1
1 int main() {return 0; }
(gdb) p/x $pc
$1 = 0x55555555512d <<< Note: breakpoint worked.
It's possible that remote debugging doesn't work, although this worked fine for me using GDB-10.0:
strip a.out -o b.out
gdbserver :6006 ./b.out
Process ./b.out created; pid = 239653
Listening on port 6006
... in another window:
gdb -q ./a.out
Reading symbols from ./a.out...
(gdb) target remote :6006
Remote debugging using :6006
Reading /lib64/ld-linux-x86-64.so.2 from remote target...
warning: File transfers from remote targets can be slow. Use "set sysroot" to access files locally instead.
Reading /lib64/ld-linux-x86-64.so.2 from remote target...
Reading symbols from target:/lib64/ld-linux-x86-64.so.2...
Reading symbols from /usr/lib/debug/.build-id/a8/97a1105e21dd270bd418fe58c441700a6d8ec5.debug...
0x00007ffff7fe4940 in _start () from target:/lib64/ld-linux-x86-64.so.2
(gdb) b main
Breakpoint 1 at 0x55555555512d: file t.c, line 1.
Im using Xcode for C++ development via an external build system. If I use Xcode 6.2 (lldb 320.4.160) everything works fine, i can set breakpoints, and they are being hit - everything nice. However, if I want to upgrade to a newer version of Xcode e.g. 7.3 (lldb 350.0.21.3) my breakpoints aren't being hit anymore. My research so far is telling me that the new lldb can't set the breakpoints for some reason.
once I stop execution of the program and type (lldb) breakpoint list my output looks like this:
Current breakpoints:
1: file = '/full/path/to/src/main.cpp', line = 842, exact_match = 0, locations = 0 (pending)
2: file = '/full/path/to/src/class.cpp', line = 383, exact_match = 0, locations = 0 (pending)
3: file = '/full/path/to/src/Homie.cpp', line = 12, exact_match = 0, locations = 0 (pending)
the (pending) at the end shows that the bp could not be set correctly. If I now set a breakpoint in the lldb via breakpoint set --file main.cpp --line 842 I get a breakpoint of which (lldb) breakpoint list is giving the following output:
4: file = 'main.cpp', line = 12, exact_match = 0, locations = 1, resolved = 1, hit count = 0
4.1: where = TEST`::__cxx_global_array_dtor() + 29 at main.cpp:842, address = 0x000000010027130d, resolved, hit count = 0
this breakpoint is being hit during program execution - everything nice
If I try to set the breakpoints on the same executable using Xcode 6.2 the debugger can successfully find the source file even with the full file path.
How can I make the new lldb version set the breakpoints correctly?
Thanks!
Xcode always sets file & line breakpoints using it's notion of the full path to the source. When Xcode is building the project, it can make sure it's "full path to source" and what it provided the compiler (and which the compiler then writes in the debug information) are the same. But with an external build system, they may not be the same (e.g. the build system may refer to the path through complicated relative paths, or through symlinks, etc...) The debugger doesn't resolve paths for all the source file paths, that is just too expensive for big projects. So if these don't match setting breakpoints by full path won't work.
You can find out what path the debugger thinks your main.cpp has by setting your breakpoint, then finding the address of the location (0x000000010027130d in the example above) and running the command:
(lldb) image lookup -va 0x000000010027130d
One of the output lines will be the compile unit:
CompileUnit: id = {0x00000000}, file = "/tmp/hello-world.c", language = "c99"
Is the full path given here the same as the one you saw when Xcode set the breakpoint. If it is then I don't know what could be going wrong, but if they aren't, you know the why, and that may point you in the direction of fixing it.
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.
trace point can be traced, but trace actions does not work normally.
at the last of gdb side below shows trace point is traced.
but "collect $regs" does not work as expected.
my platform is RH6.4.
1. gdbserver side.
gdbserver :10000 ./a.out
Process ./a.out created; pid = 10466
Listening on port 10000
Remote debugging from host 127.0.0.1
2. gdb side.
gdb a.out
(gdb) target remote :10000
Remote debugging using :10000
Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
0x00000033b7000b00 in _start () from /lib64/ld-linux-x86-64.so.2
Created trace state variable $trace_timestamp for target's variable 1.
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.107.el6.x86_64
(gdb) trace main
Tracepoint 1 at 0x400541: file a.c, line 12.
(gdb) actions 1
collect $regs
end
(gdb) tstart
(gdb) break 15
Breakpoint 2 at 0x40055f: file a.c, line 15.
Breakpoint 2, main (argc=1, argv=0x7fffca819f08) at a.c:18
18 sleep (1);
(gdb) cont
Continuing.
(gdb) tstop
(gdb) tfind
Found trace frame 0, tracepoint 1
12 c = 2;
I suppose you expected tracepoint to be in actual main declaration line in the source file, am I wrong?
The important part is that it is placed in function's entry point, this is, actually, first function's code line that, looking at the information you provided, it should be c = 2;
On the other hand, this is just a stupid detail, please note that you have no code at line 15 and breakpoint has been set at line 18.
Edit:
According to your comments, you expected tfind to dump all collected registers but you would need an extra step for this: by using tfind with no argument you selected next tracepoint (first one in this case) and, to dump this tracepoint's action collected info, you should call tdump
I am simply using gdb to step through a code line by line to learn how it is working and what it is doing. It worked fine the first time I did this, but now the next command is not working right. Sometimes it goes forward, sometimes it goes backwards. It doesn't make sense. Every time I do this it seems to be the same pattern. Below is an example. Anyone know what is wrong?
Note: This is an old Mac with old program versions (That I do not have the power to update)
Please be explicit. I am fairly new to linux and programming in general.
Thanks!
Reading symbols for shared libraries ... done
(gdb) b main
Breakpoint 1 at 0x2730: file ../../../../gcc-3.4.6/libf2c/libF77/pow_zi.c, line 14.
(gdb) r
Starting program: /Users/kevin/project/ConstU/main
nReading symbols for shared libraries +. done
Error in re-setting breakpoint 1:
Function "main" not defined.
Re-enabling shared library breakpoints: 1
Breakpoint 1, 0x00002730 in main () at main.c:34
34 {
(gdb) n
main () at main.c:42
42 for (i=0;i<DpDIM;i++) {
(gdb) n
34 {
(gdb) n
35 runstart=clock();
(gdb) n
39 Init=ReadInit(&CaseDim);/*reads in initial valies from initfile*/
(gdb) n
35 runstart=clock();
(gdb) n
39 Init=ReadInit(&CaseDim);/*reads in initial valies from initfile*/
(gdb)
Anyone know what is wrong?
The symptoms you've described are very common when debugging programs built with optimization: the compiler re-arranges code in such a way that instructions from different lines become intermixed.
Make sure you compile without any -O flags, or add -O0 at the end of your compilation lines.
here is part of the make file: CC = gcc CFLAGS = -g -O2
That would do it: remove -O2 and your debugging would go much easier.