I am trying to debug an application that is built from a number of shared libraries using GDB.
Start of gdb:
prompt$ gdb
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-50.el6)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Tell GDB the program to debug:
(gdb) file /home/me/build-path/my-program
Reading symbols from /home/me/build-path/my-program...done.
Set a breakpoint within the application:
(gdb) my-program-src.cpp:57
breakpoint 1 at 0x819df9b: file src/my-program-src.cpp, line 57
Run the program:
(gdb) run
Starting program: /home/me/build-path/my-program
The program stops at the breakpoint, as expected:
Breakpoint 1 MyClass:func(this-0xffffc1c0) at src/my-program-src.cpp:235
Line 235 of my-program-src.cpp
is a constructor call for class Derived
which is in MySharedLib1.so
.
'class Derived' is derived from 'class Base' which is in MySharedLib2.so
If I now step, the program exits inside `MySharedLib2.so' with a SIG SEGV (which is what I am trying to debug), i.e:
Program received signal SIGSEGV, Segmentation fault.
0x0024c2fa in osal::MsgQMsg::id(unsigned int) () from /home/me/build-path/lib/libMySharedLib2.so
GDB is not stepping into either of the shared libraries.
bt
gives the name of the function where the problem occurred, but list
shows code in my-program-src.cpp
All code is compiled with the following options:
gcc -MD -D__LINUX__ -g -Wall -Wextra -Iinc -m32 -fpic -I../../public_inc /home/me/src/file.c -o /home/me/build-path/obj/file.o
The shared libraries are linked with the following options:
gcc -o /home/me/build-path/lib/libMySharedLib1.so -shared /home/me/build-path/obj/file.o -L/home/me/build-path/lib/ -m32
If I change the Makefiles so that archives libraries are build (i.e. .a
) I can step into functions as expected.
Further information:
If I manually try to add the symbols from the shared library I get the following:
(gdb) add-symbol-file /home/me/build-path/lib/libMySharedLib2.so
The address where /home/me/build-path/lib/libMySharedLib2.so has been loaded is missing
(Note: i get the same response from add-symbol-file
once the breakpoint has been hit)
If I can set a breakpoint in a function within the shared library, GDB breaks as expected but if I type list
GDB shows the calling line in the main application code (i.e. the calling function that is not in a shared library). GDB does not complain about source files not being found.
Why can't I step into my shared libraries?
Why can't I step through code in shared libraries?
If the shared library has no debug symbols/info, gdb will by default step over it rather than into it. You can use stepi
(abbrev si
) to instead step by single instructions. I find the following commands in by .gdbinit file useful:
define sx
si
x /1i $pc
end
document sx
Step one instruction and print next instruction
end
define nx
ni
x /1i $pc
end
document nx
Step one instruction running through calls and print next instruction
end
which defines the commands sx
/nx
to step by single instructions, and then disassemble the next instruction to be run. Quite useful when trying to debug through machine code with no debug info.
It may be a typo, but you used libMySharedLib2.so
with a 2
not a 1
when you tried to load the symbols.
In any case, you should use g++
to compile and link c++ code. Furthermore, the main program doesn't have to be pic, although it probably doesn't hurt.
It works for me as follows:
$ cat >lib.h
class Base
{
int _x;
public:
Base(int);
};
class Derived : public Base
{
public:
Derived(int x);
};
$ cat >lib.cpp
#include "lib.h"
Base::Base(int x)
{
_x = *reinterpret_cast<int*>(x);
}
Derived::Derived(int x) : Base(x)
{
}
$ cat >main.cpp
#include "lib.h"
int main(int, char**)
{
Derived d(0);
return 0;
}
$ g++ -shared -fpic -m32 -g -Wall -o libMySharedLib1.so lib.cpp
$ g++ -m32 -g -Wall -L. -l MySharedLib1 main.cpp
$ LD_LIBRARY_PATH=$PWD gdb ./a.out
GNU gdb (GDB) 7.3.50.20111117-cvs-debian
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from a.out...done.
(gdb) r
Starting program: a.out
Program received signal SIGSEGV, Segmentation fault.
0xf7fdb552 in Base::Base (this=0xffffd83c, x=0) at lib.cpp:5
5 _x = *reinterpret_cast<int*>(x);
(gdb) bt
#0 0xf7fdb552 in Base::Base (this=0xffffd83c, x=0) at lib.cpp:5
#1 0xf7fdb5ba in Derived::Derived (this=0xffffd83c, x=0) at lib.cpp:8
#2 0x08048591 in main () at main.cpp:5
(gdb) br main
Breakpoint 1 at 0x804857d: file main.cpp, line 5.
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: a.out
Breakpoint 1, main () at main.cpp:5
5 Derived d(0);
(gdb) s
Derived::Derived (this=0xffffd83c, x=0) at lib.cpp:8
8 Derived::Derived(int x) : Base(x)
(gdb) s
Base::Base (this=0xffffd83c, x=0) at lib.cpp:5
5 _x = *reinterpret_cast<int*>(x);
(gdb output slightly edited)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With