One way would be to set up a watch expression. If you can't setup a watch expression, say, because you're using an iterator and it'd be hard to set one, you can also tell gdb to setup a breakpoint, and then ignore it N times.
Let's see how this works with this example:
#include <vector>
int main() {
std::vector<int> v = {1,2,3,4,5,0,7,8,9};
int x = 42;
for (auto i = v.begin(); i != v.end(); ++i) {
x = x / *i;
}
return 0;
}
After compiling we run it to see it crash; let's start it on gdb, then set a brakepoint on the line where it crashes.
(gdb) break foo.cpp:8
Breakpoint 1 at 0x4007bc: file foo.cpp, line 8.
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004007bc in main() at foo.cpp:8
Typing "info breakpoints" will tell you the breakpoint number; then we can tell gdb to ignore this breakpoint forever (where forever is a very large number, so the program will run until it crashes):
(gdb) ignore 1 99999
Will ignore next 99999 crossings of breakpoint 1.
(gdb) run
Starting program: /home/nico/src/a.out
Program received signal SIGFPE, Arithmetic exception.
0x00000000004007d5 in main () at foo.cpp:8
8 x = x / *i;
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004007bc in main() at foo.cpp:8
breakpoint already hit 6 times
ignore next 99993 hits
(gdb)
By doing this now we know the program crashes the sixth time it goes through that breakpoint. Now we can actually debug the problem:
(gdb) ignore 1 5
Will ignore next 5 crossings of breakpoint 1.
(gdb) run
Starting program: /home/nico/src/a.out
Breakpoint 1, main () at foo.cpp:8
8 x = x / *i;
(gdb) p *i
$1 = (int &) @0x603024: 0
This time gdb will break exactly on the spot we want.