Вот что-то такое хак, я немного смущен, чтобы опубликовать это.Но если вам нужен только один раз, он может быть достаточно хорош, чтобы позволить вам получить необходимую информацию.Там действительно должен быть лучший способ.
Вы можете определить глупый маленький сценарий GDB, который выполняет команду step
или next
определенное количество раз:
# 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использовал шаг вместо next
без особой на то веской причины; просто измените его на то, что вам нужно.)
Затем вы можете запустить эту команду (с дополнительным счетчиком), и она будет отображать каждый step
или next
приятно.
Вот пример программы, которая будет аварийно завершать работу при попытке разыменования пустого указателя:
#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;
}
Вот сеанс gdb (в Windows), отлаживающий эту программу ииспользуя сценарий step_mult
:
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)
К сожалению, поскольку сценарий не останавливается при возникновении ошибки segfault, GDB решает просто прекратить отладку программы, поэтому вы не можете делать дальнейшие полезные запросы.Но журнал может все еще быть полезным.
Я уверен, что есть множество способов сделать сценарий более интеллектуальным.К сожалению, я понятия не имею, как это сделать, и документы уровня пользователя для GDB не кажутся слишком полезными для этих деталей.Лучше всего было бы, если бы скрипт мог обнаружить произошедшую ошибку или сигнал и просто остановиться, а не полагаться на произвольный счет.Я полагаю, что интерфейс gdb / MI или, возможно, даже интерфейс сценариев Python может иметь хороший механизм, но я ничего о них не знаю.
После первого запуска вы можете использовать отображаемое количество (37 вмой пример) и перезапустите программу, подсчитайте, где она только что потерпела крах, и возьмите управление вручную.
Как я уже сказал, это не очень красиво - но может привести вас туда .