Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing 如何编写gdb脚本(使用python)?示例添加断点,运行,我们遇到了什么断点?_Unit Testing_Scripting_Gdb_Openocd_Gdb Python - Fatal编程技术网

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

Unit testing 如何编写gdb脚本(使用python)?示例添加断点,运行,我们遇到了什么断点?,unit-testing,scripting,gdb,openocd,gdb-python,Unit Testing,Scripting,Gdb,Openocd,Gdb Python,我试图用gdb创建一个小单元测试, 对于由控制的嵌入式mcu(通过gdb服务器控制我的目标) 因此,我想通过一些gdb脚本来实现这一点的自动化 我想为gdb编写某种脚本,或多或少地做到这一点: 添加两个断点 启动程序 当我们停下来时,它停在哪里(获取帧信息) 退出 有什么想法吗 举一个关于如何在python gdb脚本中实现这一点的例子就好了 谢谢 约翰 注: 假设我们有这个基本结构, 或多或少进入测试失败()或测试成功() 取决于函数start_test()返回的内容 在gdb中手动执行此操

我试图用gdb创建一个小单元测试, 对于由控制的嵌入式mcu(通过gdb服务器控制我的目标)

因此,我想通过一些gdb脚本来实现这一点的自动化

我想为gdb编写某种脚本,或多或少地做到这一点:

  • 添加两个断点
  • 启动程序
  • 当我们停下来时,它停在哪里(获取帧信息)
  • 退出 有什么想法吗

    举一个关于如何在python gdb脚本中实现这一点的例子就好了

    谢谢 约翰


    注:

    假设我们有这个基本结构, 或多或少进入测试失败()或测试成功() 取决于函数start_test()返回的内容

    在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) 
    
    因此,我尝试的下一步是将这些gdb命令添加到gdb启动脚本中,该脚本大致如下所示

    break test_success
    break test_failed
    target remote localhost:3333
    cont 
    frame
    
    首先是

    arm-none-eabi-gdb --batch --command=commands.gdb main.elf
    
    这种方法很有效,但不是很好。 我如何使用“新而酷”的python脚本实现这一点,
    gdb似乎支持。

    好的,我在问问题时找到了答案。。。这真的很简单

    如果希望以特定顺序执行“-command”和“-eval”,则不应同时使用它们

    一种更容易预测的方法是将所有内容放在commands.gdb文件中并忽略--eval

    所以它变成了这样:

    arm-none-eabi-gdb --batch --command=commands.gdb main.elf
    
    break test_success
    break test_failed
    target remote localhost:3333
    cont 
    frame
    
    (gdb) source script.py
    
    其中commands.gdb如下所示:

    arm-none-eabi-gdb --batch --command=commands.gdb main.elf
    
    break test_success
    break test_failed
    target remote localhost:3333
    cont 
    frame
    
    (gdb) source script.py
    

    但是,用类似python的东西来实现这一点可能会更好。

    仅供参考,最近的gdb版本可以用python编写脚本。您可以从gdb命令行调用python代码。这将打开一个全新的世界,请查看相关文档。从命令行运行:

     dnf/yum/apt-get install gdb-doc
     info gdb extending python
    
    如果您不喜欢基于文本的信息浏览器,这里有一个(在许多浏览器中?)可供选择的图形浏览器:

    yelp 'info:gdb' # , go to "Extending"
    
    下面是一个示例gdb python脚本。它将gdb连接到发现正在运行的第一个“your_程序”

    #!/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))
    

    我目前使用的一个简化示例:

    类调试打印断点(gdb.Breakpoint):
    调试_id=frozenset({37153420})
    def停止(自):
    top=gdb.最新的_帧()
    someVector=top.read_var('aVectorVar'))
    访问gd标准C++中的STD:()和:():
    first=someVector[''M_impl'][''M_start']
    last=someVector[''M_impl'][''M_finish']
    值=[]
    而第一次最后:
    values.append(int(first.dereference()['intID']))
    第一个=第一个+1
    如果未设置(值)和调试ID:
    return False#skip:我们要查找的项目中没有一项可以通过堆栈向量中的ID找到
    打印(“找到其他伴随ID:{}”。格式(值))
    返回True#返回gdb的提示
    #确保已加载共享库
    gdb.execute(“启动”)
    #设置断点,该断点恰好位于某个共享库中,因此前面使用了“start”
    调试打印断点(“source.cpp:42”)
    gdb.执行(“继续”)
    
    您可以从gdb的提示符执行此脚本,如下所示:

    arm-none-eabi-gdb --batch --command=commands.gdb main.elf
    
    break test_success
    break test_failed
    target remote localhost:3333
    cont 
    frame
    
    (gdb) source script.py
    
    或从命令行:

    $ gdb --command script.py ./executable.elf
    

    有关更多信息,请参阅完整部分。

    只想指出一些我在回到这个主题时感到困惑的事情(注意,我目前使用的是Ubuntu 14.04、GNU gdb(Ubuntu 7.7.1-0ubuntu5~14.04.3)7.7.1):

    首先,有人提到它“可以作为解释器调用
    gdb
    ”:

    。。。也就是说,可以用shebang行
    #编写一个脚本文本文件/usr/bin/gbd-P
    #/usr/bin/gbd--python
    ,然后在其中编写python代码,然后使其可执行
    chmod+x pygdbscript
    ,然后运行
    /pygdbscript
    。。。但正如本文所述:

    如果我尝试类似的方法,我会得到
    gdb:unrecognedoption'-python'
    。显然,这个选项是/曾经是
    gdb
    ?“archer”分支的一个特性


    因此,为了在
    gdb
    中运行Python脚本,实际上有两种方法:

    • 用扩展名
      .py
      命名脚本文件;在这里说
      test.py
    def Something():
    打印(“来自python的你好”)
    某物
    gdb.执行(“退出”);
    
    注意,在本例中,您只需编写简单的Python代码;并且您不需要
    导入gdb
    来访问
    gdb
    对象。您可以使用以下任一选项运行此命令:

    gdb-x test.py
    gdb-x=test.py
    gdb——命令test.py
    gdb--command=test.py
    gdb-command test.py
    gdb-command=test.py
    
    。。。这似乎是等效的,因为在脚本指示退出之前,
    gdb
    的结果是相同的打印输出:

    $ gdb -x=test.py
    GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.3) 7.7.1
    ...
    For help, type "help".
    Type "apropos word" to search for commands related to "word".
    hello from python
    
    注意对于这种情况,类似于
    test.gdb.py
    的名称也将被解释为纯Python脚本,因为它们以
    .py
    结尾

    • 为脚本命名其他名称-只要它不以
      .py
      扩展名结尾;在这里说
      test.pygdb
    在这种情况下,
    gdb
    将脚本解释为一个
    gdb
    脚本,即使用
    gdb
    命令-这意味着,无论您想在这里编写什么Python代码,都必须用“
    Python
    ”作为起始行,并在Python代码的末尾用“
    end
    ”包装。同样,它将通过以下任何等效调用调用:

    gdb-x test.pygdb
    gdb-x=test.pygdb
    gdb--命令test.pygdb
    gdb—命令=test.pygdb
    gdb-命令test.pygdb
    gdb-command=test.pygdb
    
    。。。然后输出与前一种情况相同(因为它运行的是同一个Python脚本):


    以及对OP的响应:如果OP中的C代码位于
    /tmp/myprog.C