GDB: Automatic 'Next'ing?
Here's something's that's such a hack I'm a bit embarrassed to post it. But if you need just a one-off, it might do well enough to let you get the information you want. There really should be a better way.
You can define a stupid little gdb script that executes the step
or next
command a certain number of times:
# file: step_mult.gdb
define step_mult
set $step_mult_max = 1000
if $argc >= 1
set $step_mult_max = $arg0
end
set $step_mult_count = 0
while ($step_mult_count < $step_mult_max)
set $step_mult_count = $step_mult_count + 1
printf "step #%d\n", $step_mult_count
step
end
end
(I used step instead of next
for no particularly good reason; just change it to whatever you need.)
Then you can run that command (with an optional count), and it'll display each step
or next
nicely.
Here's a sample program that'll crash when it tries to dereference a NULL pointer:
#include<stdio.h>
int x[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8,9, 10
};
int* p[11];
int main()
{
int i;
for (i = 0; i < 11; ++i) {
p[i] = &x[i];
}
p[5] = 0;
for (i = 0; i < 11; ++i) {
printf( "*p[%d] == %d\n", i, *p[i]);
}
return 0;
}
Here's a gdb session (on Windows) debugging that program and using the step_mult
script:
C:\temp>gdb test.exe
GNU gdb (GDB) 7.2
...
Reading symbols from C:\temp/test.exe...done.
(gdb) source c:/temp/step_mult.gdb
(gdb) start
Temporary breakpoint 1 at 0x401385: file C:\temp\test.c, line 23.
Starting program: C:\temp/test.exe
[New Thread 5396.0x1638]
Temporary breakpoint 1, main () at C:\temp\test.c:23
23 for (i = 0; i < 11; ++i) {
(gdb) step_mult 70
step #1
24 p[i] = &x[i];
step #2
23 for (i = 0; i < 11; ++i) {
step #3
24 p[i] = &x[i];
step #4
23 for (i = 0; i < 11; ++i) {
step #5
24 p[i] = &x[i];
step #6
23 for (i = 0; i < 11; ++i) {
step #7
24 p[i] = &x[i];
step #8
23 for (i = 0; i < 11; ++i) {
step #9
24 p[i] = &x[i];
step #10
23 for (i = 0; i < 11; ++i) {
step #11
24 p[i] = &x[i];
step #12
23 for (i = 0; i < 11; ++i) {
step #13
24 p[i] = &x[i];
step #14
23 for (i = 0; i < 11; ++i) {
step #15
24 p[i] = &x[i];
step #16
23 for (i = 0; i < 11; ++i) {
step #17
24 p[i] = &x[i];
step #18
23 for (i = 0; i < 11; ++i) {
step #19
24 p[i] = &x[i];
step #20
23 for (i = 0; i < 11; ++i) {
step #21
24 p[i] = &x[i];
step #22
23 for (i = 0; i < 11; ++i) {
step #23
27 p[5] = 0;
step #24
29 for (i = 0; i < 11; ++i) {
step #25
30 printf( "*p[%d] == %d\n", i, *p[i]);
step #26
*p[0] == 0
29 for (i = 0; i < 11; ++i) {
step #27
30 printf( "*p[%d] == %d\n", i, *p[i]);
step #28
*p[1] == 1
29 for (i = 0; i < 11; ++i) {
step #29
30 printf( "*p[%d] == %d\n", i, *p[i]);
step #30
*p[2] == 2
29 for (i = 0; i < 11; ++i) {
step #31
30 printf( "*p[%d] == %d\n", i, *p[i]);
step #32
*p[3] == 3
29 for (i = 0; i < 11; ++i) {
step #33
30 printf( "*p[%d] == %d\n", i, *p[i]);
step #34
*p[4] == 4
29 for (i = 0; i < 11; ++i) {
step #35
30 printf( "*p[%d] == %d\n", i, *p[i]);
step #36
Program received signal SIGSEGV, Segmentation fault.
0x004013d2 in main () at C:\temp\test.c:30
30 printf( "*p[%d] == %d\n", i, *p[i]);
step #37
Program received signal SIGSEGV, Segmentation fault.
0x004013d2 in main () at C:\temp\test.c:30
30 printf( "*p[%d] == %d\n", i, *p[i]);
step #38
Program exited with code 030000000005.
step #39
The program is not being run.
(gdb)
Unfortunately, since the script doesn't stop when the segfault happens, gdb decides to simply stop debugging the program, so you can't make any further useful inquiries. But the log might still be useful.
I'm sure there are numerous ways one might make the script more intelligent. Unfortunately, I have no idea how to do that, and the user level docs for GDB don't seem too helpful for those details. The best way would be if the script could detect the segfault or signal had happened and just stop then instead of relying on some arbitrary count. I imagine the gdb/MI interface, or probably even the Python scripting interface might have a good mechanism, but I don't know anything about those.
After your first run you could use the count displayed (37 in my example) and restart the program and give a count that's just shy of where it crashed before and take control manually.
Like I said, it's not particularly pretty - but it might get you there.