Заставить GDB автоматически завершать работу при успешном завершении? - PullRequest
11 голосов
/ 18 сентября 2010

Я использую сценарий отладки, который последовательно запускает несколько связанных процессов с отладчиком. В настоящее время я использую -x для автоматического выполнения нескольких команд (например, run). Как заставить GDB автоматически завершать работу после успешного завершения отлаженного процесса? Добавление команды quit в командный файл приведет к тому, что эта команда будет обрабатываться не только при успешном завершении, но и при возникновении ошибок ( Я бы предпочел взять на себя в этот момент).

Вот выдержка из того, что происходит:

+ gdb -return-child-result -x gdbbatch --args ./mkfs.cpfs /dev/loop0
GNU gdb (GDB) 7.1-ubuntu
Reading symbols from /home/matt/cpfs/mkfs.cpfs...done.

Program exited normally.
Breakpoint 2 at 0x805224f: file log.c, line 32.
(gdb)

Содержимое gdbbatch:

start
b cpfs_log if level >= WARNING

Ответы [ 3 ]

11 голосов
/ 18 сентября 2010

GDB устанавливает $_exitcode, когда программа успешно завершается.Вы можете использовать это - установить его на маловероятное значение в начале вашего скрипта и только quit в конце, если он изменился:

set $_exitcode = -999
# ...
run
# ...
if $_exitcode != -999
  quit
end

(установка $_exitcode на маловероятноеЗначение немного уродливо, но в противном случае оно вообще не будет определено, если программа не завершится, и, кажется, нет никакого очевидного способа спросить «определена ли эта переменная?» в условном выражении.)

9 голосов
/ 13 марта 2011

Я думаю, что нашел полное решение вашего вопроса в связи с поиском чего-то похожего в Как заставить gdb отправлять внешнее уведомление о получении сигнала? .Ни один из других парней здесь, кажется, не упоминал и не обнаружил gdb hooks .

На основании подсказки Мэтью о $ _exitcode, теперь это мой app / .gdbinit , которыйдостигает именно того поведения, которое требуется;нормальный выход при успешном завершении и переход к приглашению GDB, отправка электронной почты, еще много чего:

set $_exitcode = -999
set height 0
handle SIGTERM nostop print pass
handle SIGPIPE nostop
define hook-stop
    if $_exitcode != -999
        quit
    else
        shell echo | mail -s "NOTICE: app has stopped on unhandled signal" root
    end
end
echo .gdbinit: running app\n
run
4 голосов
/ 18 сентября 2010

GDB имеет другой «язык» для взаимодействия с автоматизированными программами, называемый GDB / MI (подробное описание здесь ), но, к сожалению, он не выглядит так, как будто он поддерживает условные выражения и, как ожидается, будет запущен из программы с разбором и ветвлением. Итак, похоже, что Expect - самое простое (или хотя бы работающее) решение:

$ cat gdbrunner
#!/usr/bin/expect -f

#spawn gdb -return-child-result --args ./mkfs.cpfs /dev/loop0
spawn gdb -return-child-result --args [lindex $argv 0]

#send "start\n"
#send "b cpfs_log if level >= WARNING"
send "run\n"

expect {
    normally\.         { send "quit\n" }
    "exited with code" { interact -nobuffer }
}

Я проверил это с помощью простых программ:

$ cat prog1.c
int main(void) { return 0; }
$ cat prog2.c
int main(void) { return 1; }

Со следующими результатами:

$ ./gdbrunner ./prog1
spawn gdb -return-child-result --args ./prog1
run
(gdb) run
Starting program: /home/foo/prog1

Program exited normally.
(gdb) quit
$ ./gdbrunner ./prog2
spawn gdb -return-child-result --args ./prog2
run
(gdb) run
Starting program: /home/foo/prog2

Program exited with code 01.
(gdb)

По сути, вы должны проанализировать вывод и ответвление, используя что-то еще. Это, конечно, будет работать с любой другой программой, способной обрабатывать ввод / вывод другого процесса, но приведенный выше сценарий ожидаемого запуска должен помочь вам начать работу, если вы не возражаете против Tcl. Должно быть немного лучше и ожидать первого (gdb) приглашения, но оно работает из-за буферизации stdin.

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

...