Ответ 1
Ну, это было нелегко, но я думаю, что я немного его понял:) Я прошел через кучу неудачных попыток (опубликовано здесь); соответствующий код ниже.
В основном проблема "следующего/шага до точки останова" заключается в том, как определить, является ли вы "on" точкой останова или нет, если отладчик остановлен (на шаге). Заметьте, что я использую GDB 7.2-1ubuntu11 (текущий для Ubuntu 11.04). Итак, это было так:
- Впервые я нашел о "Переменные удобства" , и если учесть, что есть счетчики программ и такие доступные, должна быть какая-то удобная переменная GDB, дает статус "точки останова" и может использоваться непосредственно в GDB script. Просматривая индекс ссылки GDB, я просто не могу найти таких переменных (мои попытки находятся в nub.gdb)
- При отсутствии такой внутренней переменной "статус точки останова" - единственное, что осталось сделать - это захватить вывод командной строки ( "stdout" ) GDB (в ответ на команды) в виде строки и проанализировать ее ( ищет "точку останова" )
- Затем я узнал о Python API для GDB и команду
gdb.execute("CMDSTR", toString=True)
, которая, по-видимому, именно то, что необходимо для захвата вывод: "По умолчанию любой вывод, созданный командой, отправляется на стандартный вывод gdb. Если параметр to_string имеет значение True, то вывод будет собран gdb.execute и возвращен как строка [ 1]"!- Итак, сначала я попытался создать script (pygdb-nub.py, gdbwrap), который будет использовать
gdb.execute
в рекомендуемом порядке; не удалось - из-за этого: - Тогда я подумал, что буду использовать программу python script to
subprocess.Popen
GDB, заменяя ее stdin и stdout; и затем продолжить контроль GDB (pygdb-sub.py) - это тоже не сработало... (видимо, потому что я не перенаправлял stdin/вне права) - Затем я подумал, что буду использовать сценарии python для вызова из GDB (через
source
), который будет внутренне fork в pty, когдаgdb.execute
должен быть вызван, чтобы захватить его вывод (pygdb-fork.gdb, pygdb-fork.py)... Это почти сработало - поскольку возвращаются строки; однако GDB замечает, что что-то не так: "[tcsetpgrp failed in terminal_inferior: Operation not allowed]", и последующие строки возврата, похоже, не меняются.
- Итак, сначала я попытался создать script (pygdb-nub.py, gdbwrap), который будет использовать
И наконец, подход, который работал: временно перенаправляет вывод GDB из gdb.execute
в файл журнала в ОЗУ (Linux: /dev/shm
); а затем, читая его, разглаживая его и печатая его из python - python также обрабатывает простой цикл while, который до достижения точки останова.
Ирония заключается в том, что большинство этих ошибок, вызвавших это решение путем перенаправления лог файла, на самом деле недавно зафиксированы в SVN; что они будут распространяться на дистрибутивы в ближайшем будущем, и можно будет напрямую использовать gdb.execute("CMDSTR", toString=True)
:/Тем не менее, поскольку я не могу рисковать строить GDB из источника прямо сейчас (и, возможно, столкнуться с возможными новыми несовместимыми), это хорошо достаточно для меня также:)
Вот соответствующие файлы (частично также в pygdb-fork.gdb, pygdb-fork.py):
pygdb-logg.gdb
:
# gdb script: pygdb-logg.gdb
# easier interface for pygdb-logg.py stuff
# from within gdb: (gdb) source -v pygdb-logg.gdb
# from cdmline: gdb -x pygdb-logg.gdb -se test.exe
# first, "include" the python file:
source -v pygdb-logg.py
# define shorthand for nextUntilBreakpoint():
define nub
python nextUntilBreakpoint()
end
# set up breakpoints for test.exe:
b main
b doFunction
# go to main breakpoint
run
pygdb-logg.py
:
# gdb will 'recognize' this as python
# upon 'source pygdb-logg.py'
# however, from gdb functions still have
# to be called like:
# (gdb) python print logExecCapture("bt")
import sys
import gdb
import os
def logExecCapture(instr):
# /dev/shm - save file in RAM
ltxname="/dev/shm/c.log"
gdb.execute("set logging file "+ltxname) # lpfname
gdb.execute("set logging redirect on")
gdb.execute("set logging overwrite on")
gdb.execute("set logging on")
gdb.execute(instr)
gdb.execute("set logging off")
replyContents = open(ltxname, 'r').read() # read entire file
return replyContents
# next until breakpoint
def nextUntilBreakpoint():
isInBreakpoint = -1;
# as long as we don't find "Breakpoint" in report:
while isInBreakpoint == -1:
REP=logExecCapture("n")
isInBreakpoint = REP.find("Breakpoint")
print "LOOP:: ", isInBreakpoint, "\n", REP
В принципе, pygdb-logg.gdb
загружает pygdb-logg.py
python script, устанавливает псевдоним nub
для nextUntilBreakpoint
и инициализирует сеанс - все остальное обрабатывается python script. И вот пример сеанса - в отношении источника теста в OP:
$ gdb -x pygdb-logg.gdb -se test.exe
...
Reading symbols from /path/to/test.exe...done.
Breakpoint 1 at 0x80483ec: file test.c, line 14.
Breakpoint 2 at 0x80483c7: file test.c, line 7.
Breakpoint 1, main () at test.c:14
14 count = 1;
(gdb) nub
LOOP:: -1
15 count += 2;
LOOP:: -1
16 count = 0;
LOOP:: -1
19 doFunction();
LOOP:: 1
Breakpoint 2, doFunction () at test.c:7
7 count += 2;
(gdb) nub
LOOP:: -1
9 count--;
LOOP:: -1
10 }
LOOP:: -1
main () at test.c:20
20 printf("%d\n", count);
1
LOOP:: -1
21 }
LOOP:: -1
19 doFunction();
LOOP:: 1
Breakpoint 2, doFunction () at test.c:7
7 count += 2;
(gdb)
... так же, как я этого хотел: P Просто не знаю, насколько это надежно (и можно ли использовать его в avr-gdb
, для чего мне это нужно:) EDIT: версия avr -gdb в Ubuntu 11.04 в настоящее время является 6.4, что не распознает команду python:()
Хорошо, надеюсь, это поможет кому-то,
Ура!
Вот некоторые ссылки:
- GDB: обнаружена ошибка на stdin
- У GDB возникают проблемы с получением команд, переданных по протоколу STDIN
- Re: [Gdb] Как использовать другой вход GDB?
- gdb не принимает ввод на stdin
- Использование gdb в среде IDE - comp.os.linux.development.apps | Группы Google
- rmathew: Terminal Sickness
- [TUTORIAL] Вызов внешней программы в C (Linux) - GIDForums
- shell - как использовать несколько аргументов с помощью shebang (т.е. #!)? - Переполнение стека
- Перенаправление/сохранение вывода оболочки в переменную GDB? - Переполнение стека
- Corey Goldberg: Python - перенаправление или выключение STDOUT и STDERR
- Скалы безмятежности > 9. Скрипт gdb
- gdb python scripting: где
parse_and_eval
ушел? - Переполнение стека - shell - вызывать gdb для автоматического передачи аргументов в отлаживаемую программу - переполнение стека
- Хранение файлов/каталогов в памяти с tmpfs | HowtoForge - Linux Howtos и учебники
- простой способ касаться файла, если он не существует | Python | Python
- os.fork() отличается в cgi- script? - Python
- java - Написание тестов, которые используют GDB - как захватить вывод? - Переполнение стека
- Отладка с помощью GDB: как создать команды GDB в Python - Wiki
- Справочная карта GDB