2010-09-18 2 views
11

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

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

+ 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
+1

Существует дубликат Stackoverflow вопрос с полезным ответом: HTTP: // StackOverflow.com/a/8657833/431087 –

ответ

4

GDB имеет другой "язык" для взаимодействия с автоматизированными программами под названием GDB/MI (подробное here) , но, к сожалению, он не выглядит так, как будто он поддерживает условные выражения, и ожидается, что он будет запускаться из других программ с разбором и разветвлением. Таким образом, это выглядит как Ожидать это самый простой (или, по крайней мере, рабочий) раствор:

$ 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; его команды и вывод немного более легко разбираются, если вы расширитесь, чтобы использовать более сложные функции, как вы можете видеть в ранее связанной документации.

11

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

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

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

+0

[Этот документ] (http://info2html.sourceforge.net/cgi-bin/info2html-demo/info2html? (gdb.info.gz) Convenience% 2520Funs) показывает, как использовать '_isvoid 'с' _exitcode', чтобы избежать установки «маловероятных значений». –

8

Я думаю, что у меня есть нашел полное решение вашего вопроса в связи с поиском чего-то подобного в How to make gdb send an external notification on receiving a signal?. Ни один из других парней, похоже, не упомянул или не обнаружил gdb hooks.

Основано на подсказке Мэтью о $ _exitcode, теперь это мое приложение /.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 
Смежные вопросы