如何编写gdb脚本(使用python)?示例添加断点,运行,我们遇到了什么断点?

Joh*_*han 13 scripting unit-testing gdb openocd gdb-python

我正在尝试用gdb创建一个小单元测试,用于由OpenOCD控制的嵌入式mcu (这使我可以通过gdb服务器控制我的目标).

所以我想用gdb的一些脚本来自动执行此操作.

我想为gdb写一些或多或少的脚本:

  1. 添加几个断点
  2. 启动该程序
  3. 当我们停止时,它停在哪里(获取帧信息)
  4. 放弃.

有任何想法吗?

关于如何在python gdb脚本中执行此操作的示例将是很好的.

谢谢约翰


注意:

假设我们有这个基本结构,或多或少进入test_failed()或test_success(),具体取决于函数start_test()返回的内容.

void test_failed() {    
    while(1);    
}

void test_success() {    
    while(1);    
}

int main(void) {    
    int status = start_test();    

    if( status > 0 ) {    
        test_failed();    
    }    
    test_success();

    while(1);    
}
Run Code Online (Sandbox Code Playgroud)

在gdb中手动执行此操作是非常紧张的,

(gdb) break test_success
Breakpoint 1 at 0x20: file src/main.c, line 9.
(gdb) break test_failed
Breakpoint 2 at 0x18: file src/main.c, line 5.
(gdb) cont
Continuing.

Breakpoint 1, test_success () at src/main.c:9
9       while(1);
(gdb) frame
#0  test_success () at src/main.c:9
9       while(1);
(gdb) 
Run Code Online (Sandbox Code Playgroud)

因此,我尝试的下一步是将这些gdb命令添加到gdb启动脚本中,该脚本或多或少看起来像这样.

break test_success
break test_failed
target remote localhost:3333
cont 
frame
Run Code Online (Sandbox Code Playgroud)

然后开始吧

arm-none-eabi-gdb --batch --command=commands.gdb main.elf
Run Code Online (Sandbox Code Playgroud)

而这种作品,但它不是很好.我如何使用gdb似乎支持的"新的和酷的"python脚本来做到这一点.

Mar*_*rcH 10

FYI最近的gdb版本可以用Python编写脚本.您可以从gdb命令行调用python代码.这打开了一个全新的世界,查看相关文档.从命令行运行:

 dnf/yum/apt-get install gdb-doc
 info gdb extending python
Run Code Online (Sandbox Code Playgroud)

如果你不喜欢基于文本的信息浏览器,这里有一个(在众多?中)替代的图形浏览器:

yelp 'info:gdb' # , go to "Extending"
Run Code Online (Sandbox Code Playgroud)

这是一个示例gdb-python脚本.它将gdb附加到运行的第一个"your_program".

#!/usr/bin/python

import subprocess
import string

def backquotes(cmdwords):
        output = subprocess.Popen(cmdwords, stdout=subprocess.PIPE).communicate()[0]
        return output.strip()

pid = backquotes(['pgrep', 'your_program'])

gdb.execute("attach " + str(pid))
Run Code Online (Sandbox Code Playgroud)


Gie*_*iel 9

我正在使用的缩减示例:

class DebugPrintingBreakpoint(gdb.Breakpoint):
    debugging_IDs = frozenset({37, 153, 420})
    def stop(self):
        top = gdb.newest_frame()
        someVector = top.read_var('aVectorVar')
        # Access the begin() & end() pointer of std::vector in GNU Standard C++ lib
        first = someVector['_M_impl']['_M_start']
        last = someVector['_M_impl']['_M_finish']
        values = []
        while first != last:
            values.append(int(first.dereference()['intID']))
            first = first + 1
        if not set(values) & debugging_IDs:
            return False # skip: none of the items we're looking for can be found by ID in the vector on the stack
        print("Found other accompanying IDs: {}".format(values))
        return True # drop to gdb's prompt
# Ensure shared libraries are loaded already
gdb.execute("start")
# Set our breakpoint, which happens to reside in some shared lib, hence the "start" previously
DebugPrintingBreakpoint("source.cpp:42")
gdb.execute("continue")
Run Code Online (Sandbox Code Playgroud)

您可以从gdb的提示符执行此脚本,如下所示:

(gdb) source script.py
Run Code Online (Sandbox Code Playgroud)

或者从命令行:

$ gdb --command script.py ./executable.elf
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅完整的GDB Python API文档.

  • `gdb.execute(“ continue”)`确实可以工作:-) (2认同)