Как управлять gdb в коде C или Python без API Python GDB?
Я пытаюсь написать программу на python или c, которая может отлаживать код c с помощью gdb.
Я прочитала решение Тома и вызов и управление GDB из Python. Но они более или менее решение для сценариев gdb в python. Поскольку я собираюсь использовать arm-gdb для отладки встроенной программы, я не могу включить скрипты python в моем gdb.
моя цель-создать абстракцию высокого уровня gdb. Например, запустите gdb, установите некоторые точки останова и продолжить в моем коде. Я также прочитал некоторые материалы интерфейса gdb/mi. Но может ли кто-нибудь сказать мне, как использовать интерфейс gdb/mi для создания процесса gdb и связи с gdb из кода C/python? (К счастью, мой arm-gdb поддерживает интерфейс gdb/mi).
3 ответов
как и было обещано в комментариях выше, я опубликовал свою (раннюю, неполную, почти наверняка багги) рубиновую работу в http://github.com/mcarpenter/rubug.
вот пример (вы можете найти это в
examples/breakpoint
). Функция check_for_crash
- это обратный вызов, который может быть вызван
после программы называется factorial
это работает. Точка останова принимает имя функции
(fac
; ведущая двоеточие просто указывает, что это
символ ruby, который во всех отношениях и цели здесь облегченные
строка.)
EXE = 'factorial'
def check_for_crash(gdb, event)
case event.type
when :command_response
raise RuntimeError, 'oops' unless
[ :done, :running ].include? event.response.result
when :breakpoint
puts 'Breakpoint reached'
pp event
gdb.continue
when :exit
puts 'Exit'
gdb.stop_event_loop
exit
end
end
gdb = Rubug::Gdb.new
resp = gdb.file EXE
gdb.register_callback(method :check_for_crash)
gdb.break(:fac)
gdb.run '5 > /dev/null'
gdb.start_event_loop
справедливо предупредить вас, что код может быть... crufty. В настоящее время (здесь я остановился) ничего не работает (после обновления gdb в середине моей работы см. грамматика ниже).
есть куча примеров в каталоге же имя, которое может оказаться полезным. К (попытка!) запускать их, вам нужно будет сделать что-то вроде этого:
rake clean
rake grammar
rake make
cd examples/simple_fuzzer
ruby -I ../../lib -r rubygems simple_fuzzer.rb
дали время, когда это было написано, вы, вероятно, должны пойти с ruby1.8 если у вас есть выбор (я не в 1.9, в то время и, вероятно, проблемы с кодировкой строк под 1.9).
разбор ответов выполняется treetop
http://treetop.rubyforge.org, анализатор колышка. Глядя на грамматику с
свежие глаза я уверен, что это можно было бы упростить. Вам нужно будет установить это
(и любые другие необходимые драгоценные камни) с помощью gem install ...
.
еще несколько советов, если вы Pythonize:
документация
снаружи мало " отладки с GDB" (гл. 22). Я бросил этот PDF и просто ch. 22 в виде отдельного файла в the docs раздел репозитория.
асинхронные
протокол asynrchronous (сначала я предположил, что это было
протокол типа команды / ответа, это была ошибка). Если я
повторно реализовать это я бы, вероятно, использовал что-то вроде event machine или
libevent, а не сворачиваю свой собственный select()
петли.
грамматика
грамматики немного... запутанным. Хотя документация (27.2.2) говорится, что ответ "состоит из нуля или более из группы записи, за которыми, необязательно, следует одна запись результата":
`output -> ( out-of-band-record )* [ result-record ] "(gdb)" nl`
вы должны знать, что, поскольку все может прибыть в любое время read()
по-видимому, сокет может возвращать async/result/больше
async/Терминатор(!). Например, я вижу это с моим текущий gdb:
=thread-group-started,id="i1",pid="1086"
=thread-created,id="1",group-id="i1"
^running
*running,thread-id="all"
(gdb)
начало строки ^
является записью результата, все остальные асинхронны (тогда
терминатор.) Это кажется довольно значительным недостатком
спецификация.
скорость
мое основное внимание-безопасность, и я был заинтересован в MI для автоматизированный fuzzing, бинарный осмотр, etc. Для этого GDB/MI тоже медленно (стоимость запуска программы в отладчике). YMMV.
отображение MI / CLI
там были некоторые вещи в стандартной команде GDB CLI, которую я не удалось увидеть, как реализовать с помощью команд MI. У меня есть скелет код для чего-то вроде этого:
gdb = Gdb::MI.new
gdb.cli(:file, '/bin/ls')
gdb.cli(:set, :args, '> /dev/null')
gdb.cli(:run)
gdb.cli(:quit)
(что приятно и понятно, я думаю, для нас, не-Mi-expert-но-GDB-знающих пользователей). Я не могу сейчас вспомнить, что это были за проблемные вещи (это больше года с тех пор, как я посмотрел на это), но если эти нейроны сработают, я вернусь и обновлять.
варианты
когда я впервые начал из на этой дороге я нашел сообщение в блоге от Jamis Buck: http://weblog.jamisbuck.org/2006/9/25/gdb-wrapper-for-ruby это обертывания сеанс командной строки gdb в popen (), который заставил меня немного поморщиться. В в частности, можно ожидать, что он будет хрупким, поскольку gdb не делает гарантии о стабильности выхода CLI. Вы можете (или не можете)) предпочитаю такой подход.
если вы находитесь в windows, то PyDbg / PeiMei может представлять интерес: http://code.google.com/p/paimei/
вам также может понравиться книга Grey Hat Python: программирование на Python для хакеров (Seitz). Опять же, в основном на основе windows, но может оказаться вдохновляющим.
ссылки, которые вы перечислили, больше похожи на "вызов Python из GDB", но вы спрашиваете, как вызвать GDB из Python или C. GDB / MI интерфейс, безусловно, путь. Eclipse, Emacs и KDevelop используют GDB/MI для абстракции интерфейса отладки. Я лично использовал KDevelop с тремя различными скомпилированными версиями gdb для ARM, AVR и H8S. Протокол MI предназначен для анализа программным обеспечением, поэтому синтаксис очень регулярный.
поиск Google дал а Python GDB wrapper это должно вам начать работу.
Как насчет использования http://www.noah.org/python/pexpect/ ? Это версия pythonhttp://en.wikipedia.org/wiki/Expect что очень полезно для автоматизации задач с внешними командами.