Как управлять GDB в коде C или Python без API GDB Python? - PullRequest
13 голосов
/ 26 июля 2011

Я пытаюсь написать программу на python или c, которая может отлаживать код c с помощью gdb.

Я прочитал решение Tom и Вызов и управление GDB из Python . Но они являются более или менее решением для сценариев GDB в Python. Так как я собираюсь использовать arm-gdb для отладки встроенной программы, я не могу включить сценарии python в моем gdb.

Моя цель - создать высокоуровневую абстракцию GDB. Например, запустите GDB, установите несколько точек останова и продолжайте в моем коде. Я также прочитал некоторые материалы интерфейса gdb / mi. Но может ли кто-нибудь сказать мне, как использовать интерфейс GDB / mi для создания процесса GDB и общаться с GDB из кода C / Python? (К счастью, мой arm-gdb поддерживает интерфейс gdb / mi).

Ответы [ 3 ]

5 голосов
/ 18 августа 2011

Как и было обещано в комментариях выше, я опубликовал свою (раннюю, неполную, почти наверняка глючную) рубиновую работу на http://github.com/mcarpenter/rubug.

Вот пример (вы можете найти это в examples/breakpoint). Функция check_for_crash является обратным вызовом, который может быть вызван после запуска программы под названием factorial. Точка останова принимает имя функции (fac; двоеточие указывает, что это рубиновый символ, который, по сути, является легким строка).

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

Справедливо предупредить вас, что код может быть ... грубым. В настоящее время (это то, где я остановился) ничего не работает (после обновления 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, Парсер PEG. Глядя на грамматику с свежие глаза я уверен, что это можно упростить. Вам нужно будет установить это (и любые другие необходимые драгоценные камни), используя gem install ....

Еще несколько советов, если вы делаете Pythonize:

Документация

За пределами "Отладки с помощью GDB" мало что есть (гл. 22). Я бросил этот PDF и просто гл. 22 как отдельный файл в раздел docs хранилища.

Асинхронный

Протокол асинхронный (сначала я предположил, что это было протокол типа команда / ответ, это была ошибка). Если бы я был реализовать это, я бы, вероятно, использовал что-то вроде машины событий или Либевент вместо того, чтобы катиться по моей собственной select() петле.

Грамматика

Грамматика немного ... запутанная. Хотя документация (27.2.2) утверждает, что ответ "состоит из нуля или более вне полосы записи, за которыми, возможно, следует одна запись результата ":

`output -> ( out-of-band-record )* [ result-record ] "(gdb)" nl`

вы должны знать, что, поскольку все может прибыть в любое время, read() на сокете, по-видимому, может вернуть async / result / больше асинхронный / терминатора (!). Например, я вижу это с моим текущим GDB:

=thread-group-started,id="i1",pid="1086"
=thread-created,id="1",group-id="i1"
^running
*running,thread-id="all"
(gdb)

Строка, начинающаяся с ^, является записью результата, все остальные являются асинхронными (тогда Терминатор). Это кажется довольно существенным недостатком в спецификация.

Скорость

Мое основное внимание уделяется безопасности, и я интересовался МИ для автоматическое фаззинг, бинарный контроль и т. д. Для этой цели GDB / MI слишком медленно (стоимость запуска программы в отладчике). YMMV.

MI / CLI mapping

В стандартном наборе команд CLI GDB были некоторые вещи, которые я не мог видеть, как реализовать с помощью команд MI. У меня есть скелет код для чего-то вроде этого:

gdb = Gdb::MI.new
gdb.cli(:file, '/bin/ls')
gdb.cli(:set, :args, '> /dev/null')
gdb.cli(:run)
gdb.cli(:quit)

(я думаю, это хорошо и понятно для нас, не являющихся MI-экспертами, но знающими GDB). Я не могу сейчас вспомнить, что это были за проблемы (прошло больше года так как я посмотрел на это), но если эти нейроны стреляют, я вернусь и обновите это.

Альтернативы

Когда я только начинал на этом пути я нашел запись в блоге от Джемиса Бака: 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). Опять же, в основном на основе окон, но может оказаться вдохновляющим.

1 голос
/ 22 августа 2011

Ссылки, которые вы перечислили, являются скорее "вызовом Python из GDB", но вы спрашиваете, как вызвать GDB из Python или C. Интерфейс GDB / MI определенно подходит. Eclipse, Emacs и KDevelop используют GDB / MI для абстрагирования интерфейса отладки. Я лично использовал KDevelop с тремя разными кросс-скомпилированными версиями GDB для ARM, AVR и H8S. Протокол MI разработан для анализа программным обеспечением, поэтому синтаксис очень регулярный.

Поиск Google дал обертку Python GDB , которая должна помочь вам начать.

0 голосов
/ 22 августа 2011

Как насчет использования http://www.noah.org/python/pexpect/? Это версия Python http://en.wikipedia.org/wiki/Expect, которая очень полезна для автоматизации задач с помощью внешних команд.

...