Как управлять 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 что очень полезно для автоматизации задач с внешними командами.