如何在没有GDB Python API的情况下在C或Python代码中控制gdb?

Pen*_*nny 13 c python gdb arm

我试图用python或c编写一个程序,可以使用gdb调试c代码.

我已经阅读了TomInvoke解决方案并从Python控制GDB.但它们或多或少是在python中编写脚本gdb的解决方案.由于我将使用arm-gdb来调试嵌入式程序,我无法在我的gdb中启用python脚本.

我的目标是创建一个gdb的高级抽象.例如,启动gdb,设置一些断点并在我的代码中继续.我还阅读了一些材料gdb/mi界面.但有谁能告诉我如何使用gdb/mi接口创建一个gdb进程并从c/python代码与gdb进行通信?(幸运的是我的arm-gdb支持gdb/mi接口).

Mar*_*ter 5

正如上面评论中所承诺的那样,我已将我的(早期,不完整,几乎肯定是错误的)ruby工作发布到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
Run Code Online (Sandbox Code Playgroud)

警告你,代码可能是......苛刻的,这是公平的.目前(这是我停止的地方)没什么用处(在我的工作中途进行gdb更新之后,请参阅 下面的语法).

但是,同名目录中有许多示例可能会有所帮助.要(尝试!)运行它们,您需要执行以下操作:

rake clean
rake grammar
rake make 
cd examples/simple_fuzzer
ruby -I ../../lib -r rubygems simple_fuzzer.rb
Run Code Online (Sandbox Code Playgroud)

考虑到写入的时间你应该选择ruby1.8,如果你有选择的话(我当时没有进入1.9并且可能存在1.9下的字符串编码问题).

通过树梢http://treetop.rubyforge.org(PEG解析器)执行响应的 解析.用新鲜的眼睛看着语法,我确信它可以简化.您将需要使用安装此(以及任何其他所需的宝石)gem install ....

如果您进行Pythonize,还有一些提示:

文档

外部"使用GDB调试"很少(第22章).我抛出了这个PDF而且只是ch.22作为单独的文件进入存储库的docs部分.

异步

该协议是异步的(起初我认为这是命令/响应类型协议,这是一个错误).如果我要重新实现它,我可能会使用像事件机器或libevent这样的东西,而不是滚动我自己的select()循环.

语法

语法有点......令人困惑.虽然文档(27.2.2)声明响应"由零个或多个带外记录组成,但可选地,由单个结果记录组成":

`output -> ( out-of-band-record )* [ result-record ] "(gdb)" nl`
Run Code Online (Sandbox Code Playgroud)

你应该知道,因为任何时候都可以在read() 套接字上到达,显然可以返回async/result/more async/terminator(!).例如,我用我当前的gdb看到了这个:

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

行开始^是结果记录,所有其他行是异步(然后是终止符).这似乎是规范中一个相当重要的缺陷.

速度

我的主要关注点是安全性,我对MI的自动模糊测试,二进制检查等感兴趣.为此,GDB/MI太慢了(在调试器中启动程序的成本).因人而异.

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)
Run Code Online (Sandbox Code Playgroud)

(对于我们非MI专家但gdb知识渊博的用户来说,这是好的和清晰的).我现在还记不起那些有问题的东西(自从我看到它以来已经过了一年多)但是如果那些神经元发射了,我会回来更新它.

备择方案

当我第一次踏上这条路的时候,我发现了Jamis Buck发布的博客:http://weblog.jamisbuck.org/2006/9/25/gdb-wrapper-for-ruby 这包含了一个在popen中的gdb命令行会话(这让我有点畏缩.特别是人们可能会认为它很脆弱,因为gdb不能保证CLI输出的稳定性.您可能(或可能不)更喜欢这种方法.

如果您在Windows上,那么PyDbg/PeiMei可能会引起您的兴趣:http://code.google.com/p/paimei/

您可能也喜欢" 灰帽子Python:黑客Python编程"(Seitz)这本书.同样,大多数基于Windows,但可能会鼓舞人心.