ГБД: Автоматически «Следующее»? - PullRequest
8 голосов
/ 28 апреля 2011

Быстрый на этот раз.

Возможно ли (кроме нажатия Enter навсегда) для GDB непрерывно next через программу построчно находить, где происходит ошибка?

Изменить: continue не то, что я хотел бы;Я хотел бы эффективно видеть полное выполнение программы построчно, как вы получаете от next снова и снова.

Ответы [ 4 ]

7 голосов
/ 28 апреля 2011

Вот что-то такое хак, я немного смущен, чтобы опубликовать это.Но если вам нужен только один раз, он может быть достаточно хорош, чтобы позволить вам получить необходимую информацию.Там действительно должен быть лучший способ.

Вы можете определить глупый маленький сценарий 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 вмой пример) и перезапустите программу, подсчитайте, где она только что потерпела крах, и возьмите управление вручную.

Как я уже сказал, это не очень красиво - но может привести вас туда .

0 голосов
/ 27 мая 2012

Смотрите также этот пост: c - GDB auto step - автоматическая распечатка строк при свободном запуске? , который использует интерфейс Python для GDB.

0 голосов
/ 28 апреля 2011

Команда continue будет выполняться до тех пор, пока не возникнет точка останова, приложение не вызовет исключение (например, сбой) или приложение завершится.

0 голосов
/ 28 апреля 2011

Вы можете использовать continue или c, чтобы продолжить выполнение до следующей точки останова.

Также см. Запуск приложения в GDB до возникновения исключения (StackOverflow) о том, как установить «точку захвата», которая прервет выполнение при возникновении исключения.

...