Typically, to enter a stepping mode from the very beginning of a C++ program execution, one uses the break main
command in GDB. But that breaks the program only at the entrance to the main()
function.
How can I break a program on a very first user-written operation (say, a constructor of a statically defined class instance)?
For example, if I had the following code, how could I break at A()
without using the break 5
command?
#include <iostream>
struct A {
A() {
std::cout << "A()" << std::endl;
}
};
static A a;
int main() {
return 0;
}
In reality, I debug a very large code written by someone else. The code has a lot of static class instances scattered across different source files. That is not feasible to manually set breakpoints on each of the constructors.
If the target environment supports it, gdb can allow you to “rewind” the program by running it backward. A target environment that supports reverse execution should be able to “undo” the changes in machine state that have taken place as the program was executing normally.
The command would be " reverse-step ", or " reverse-next ". If you run into the error: Target child does not support this command. then try adding target record at the beginning of execution, after starting run . Edit: Since GDB 7.6 target record is deprecated, use target record-full instead.
If you want to execute the entire function with one keypress, type "next" or "n". This is equivalent to the "step over" command of most debuggers. If you want gdb to resume normal execution, type "continue" or "c". gdb will run until your program ends, your program crashes, or gdb encounters a breakpoint.
Just press c. It will continue execution until the next breakpoint. You can also disable intermediate breakpoints by using disable #breakpointnumber as stated here.
You can define a break point at the constructor.
(gdb) break 'A::A()'
Breakpoint 1 at 0x8048724: file x.cc, line 4.
(gdb) run
Starting program: /.../a.out
Breakpoint 1, A::A (this=0x804a0ce <a>) at x.cc:4
4 std::cout << __func__ << std::endl;
(gdb) bt
#0 A::A (this=0x804a0ce <a>) at x.cc:4
#1 0x08048700 in __static_initialization_and_destruction_0 (__initialize_p=1,
__priority=65535) at x.cc:8
#2 0x0804871c in _GLOBAL__sub_I_main () at x.cc:10
#3 0x080487a2 in __libc_csu_init ()
#4 0xb7d44a1a in __libc_start_main (main=0x80486ad <main()>, argc=1,
argv=0xbffff184, init=0x8048750 <__libc_csu_init>,
fini=0x80487c0 <__libc_csu_fini>, rtld_fini=0xb7fed180 <_dl_fini>,
stack_end=0xbffff17c) at libc-start.c:246
#5 0x080485d1 in _start ()
(gdb)
Note the use of single quotes to indicate that the identifier is C++ mangled. Also note that the stack trace shows that main()
has not been called yet.
From the stack trace, there are a number of choices to set a breakpoint that will be before any global constructor gets called. One such breakpoint is on _start
.
(gdb) break _start
Breakpoint 1 at 0x80485b0
(gdb) run
Starting program: /.../a.out
Breakpoint 1, 0x080485b0 in _start ()
(gdb) bt
#0 0x080485b0 in _start ()
(gdb)
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