如何自动打印 GDB 中的每个执行行,直到到达给定的断点?

2023-12-06

我希望能够在 GDB 中设置一个断点,并让它运行到该点 - 并在此过程中打印出它“单步执行”的行。

这是一个基于这个简单文件的示例main和一个函数,每个函数有两个断点:

$ cat > test.c <<EOF
#include "stdio.h"

int count=0;

void doFunction(void) {
  // two steps forward
  count += 2;
  // one step back
  count--;
}

int main(void) {
  // some pointless init commands;
  count = 1;
  count += 2;
  count = 0;
  //main loop
  while(1) {
    doFunction();
    printf("%d\n", count);
  }
}
EOF

$ gcc -g -Wall test.c -o test.exe
$ chmod +x test.exe
$ gdb -se test.exe
...
Reading symbols from /path/to/test.exe...done.
(gdb) b main
Breakpoint 1 at 0x80483ec: file test.c, line 14.
(gdb) b doFunction
Breakpoint 2 at 0x80483c7: file test.c, line 7.

要启动会话,我需要运行(r)程序,然后将在第一个断点处停止(main):

(gdb) r
Starting program: /path/to/test.exe 

Breakpoint 1, main () at test.c:14
14    count = 1;
(gdb) 

此时 - 例如,我可以点击继续(c);该过程将运行,不输出任何内容,并在请求行处中断:

(gdb) c
Continuing.

Breakpoint 2, doFunction () at test.c:7
7     count += 2;
(gdb)

另一方面,我可以使用步骤(而不是继续)逐行进行操作s)或下一个(n);例如:

14    count = 1;
(gdb) n
15    count += 2;
(gdb) s
16    count = 0;
(gdb) s
19      doFunction();
(gdb) s

Breakpoint 2, doFunction () at test.c:7
7     count += 2;
(gdb) s
9     count--;
(gdb) s
10  }
(gdb) s
main () at test.c:20
20      printf("%d\n", count);
(gdb) s
...
(gdb) s
_IO_vfprintf_internal (s=Cannot access memory at address 0xe5853361
) at vfprintf.c:210
210 vfprintf.c: No such file or directory.
    in vfprintf.c
(gdb) s
245 in vfprintf.c
(gdb) s
210 in vfprintf.c
(gdb) n
245 in vfprintf.c
...
(gdb) n
2006    in vfprintf.c
(gdb) n
__printf (format=0x80484f0 "%d\n") at printf.c:39
39  printf.c: No such file or directory.
    in printf.c
(gdb) n
main () at test.c:21
21    }
(gdb) n
19      doFunction();
(gdb) n

Breakpoint 2, doFunction () at test.c:7
7     count += 2;
(gdb) 

Anyways, I am aware that I can keep Enter pressed, and the last entered command (step or next) will repeat (left a bit longer session in the second case, to show that 'next' remains on same level, 'step' steps inside the functions being called). However, as it can be seen, depending on whether step or next runs, it may take a while until a result is reached - and so, I don't want to sit for 10 minutes with my hand stuck on the Enter button :)

所以,我的问题是 - 我可以以某种方式指导gdb运行到“断点 2”而无需进一步的用户干预 - 同时打印出它所经过的行,就好像按下了步骤(或下一步)一样?


好吧,这并不容易 - 但我想我有点明白了:)我经历了一系列失败的尝试(发布here);相关代码如下。

基本上,“下一个/步骤直到断点”中的问题是,如果调试器停止(在一个步骤中),如何确定是否“位于”断点。另请注意,我使用 GDB 7.2-1ubuntu11(当前适用于 Ubuntu 11.04)。所以,事情是这样的:

  • 我第一次发现关于便利变量,并认为 - 考虑到有程序计数器等可用,必须有一些 GDB 方便变量来提供“断点”状态,并且可以直接在 GDB 脚本中使用。看完之后GDB参考索引然而,有一段时间,我根本找不到任何这样的变量(我的尝试是在nub.gdb)
  • 由于缺乏这样的“断点状态”内部变量 - 唯一要做的就是捕获 GDB 的('stdout')命令行输出(响应命令)作为字符串,并解析它(寻找“断点”)
  • Then, I found out about Python API to GDB, and the gdb.execute("CMDSTR", toString=True) command - which is seemingly exactly what is needed to capture the output: "By default, any output produced by command is sent to gdb's standard output. If the to_string parameter is True, then output will be collected by gdb.execute and returned as a string[1]"!
    • So, first I tried to make a script (pygdb-nub.py,gdbwrap) that would utilize gdb.execute in the recommended manner; failed here - because of this:
      • Bug 627506 – python: gdb.execute([...], to_string=True) 部分打印到 stdout/stderr
      • Bug 10808 – 允许 GDB/Python API 捕获和存储 GDB 输出
    • 然后,我想我应该使用 python 脚本subprocess.PopenGDB 程序,同时替换其 stdin 和 stdout;然后从那里继续控制 GDB (pygdb-sub.py) - 也失败了...(显然,因为我没有正确重定向标准输入/输出)
    • 然后,我想我应该使用 python 脚本从 GDB 调用(通过source)每当gdb.execute应该被调用,以便捕获其输出(pygdb-fork.gdb,pygdb-fork.py)... 这almost有效 - 因为有返回的字符串;然而 GDB 注意到有些不对劲:“[tcsetpgrp 在terminal_inferior 中失败:不允许操作]",并且后续的返回字符串似乎没有改变。

最后,有效的方法是:暂时重定向 GDB 输出gdb.execute到 RAM 中的日志文件(Linux:/dev/shm);然后读回它,解析它并从 python 打印它 - python 还处理一个简单的 while 循环,该循环会一直执行到到达断点。

具有讽刺意味的是 - 大多数通过重定向日志文件导致此解决方案的错误实际上最近在 SVN 中得到了修复;这意味着这些将在不久的将来传播到发行版,并且人们将能够使用gdb.execute("CMDSTR", toString=True)直接:/然而,由于我现在不能冒险从源代码构建GDB(并且可能会遇到可能的新的不兼容问题),这对我来说也足够好了:)

 

这是相关文件(部分也在pygdb-fork.gdb,pygdb-fork.py):

pygdb-logg.gdb is:

# gdb script: pygdb-logg.gdb
# easier interface for pygdb-logg.py stuff
# from within gdb: (gdb) source -v pygdb-logg.gdb
# from cdmline: gdb -x pygdb-logg.gdb -se test.exe

# first, "include" the python file:
source -v pygdb-logg.py

# define shorthand for nextUntilBreakpoint():
define nub
  python nextUntilBreakpoint()
end

# set up breakpoints for test.exe:
b main
b doFunction

# go to main breakpoint
run

pygdb-logg.py is:

# gdb will 'recognize' this as python
#  upon 'source pygdb-logg.py'
# however, from gdb functions still have
#  to be called like:
#  (gdb) python print logExecCapture("bt")

import sys
import gdb
import os

def logExecCapture(instr):
  # /dev/shm - save file in RAM
  ltxname="/dev/shm/c.log"

  gdb.execute("set logging file "+ltxname) # lpfname
  gdb.execute("set logging redirect on")
  gdb.execute("set logging overwrite on")
  gdb.execute("set logging on")
  gdb.execute(instr)
  gdb.execute("set logging off")

  replyContents = open(ltxname, 'r').read() # read entire file
  return replyContents

# next until breakpoint
def nextUntilBreakpoint():
  isInBreakpoint = -1;
  # as long as we don't find "Breakpoint" in report:
  while isInBreakpoint == -1:
    REP=logExecCapture("n")
    isInBreakpoint = REP.find("Breakpoint")
    print "LOOP:: ", isInBreakpoint, "\n", REP

 

基本上,pygdb-logg.gdb加载pygdb-logg.pypython脚本,设置别名nub for nextUntilBreakpoint,并初始化会话 - 其他一切都由 python 脚本处理。这是一个示例会话 - 关于 OP 中的测试源:

$ gdb -x pygdb-logg.gdb -se test.exe
...
Reading symbols from /path/to/test.exe...done.
Breakpoint 1 at 0x80483ec: file test.c, line 14.
Breakpoint 2 at 0x80483c7: file test.c, line 7.

Breakpoint 1, main () at test.c:14
14    count = 1;
(gdb) nub
LOOP::  -1
15    count += 2;

LOOP::  -1
16    count = 0;

LOOP::  -1
19      doFunction();

LOOP::  1

Breakpoint 2, doFunction () at test.c:7
7     count += 2;

(gdb) nub
LOOP::  -1
9     count--;

LOOP::  -1
10  }

LOOP::  -1
main () at test.c:20
20      printf("%d\n", count);

1
LOOP::  -1
21    }

LOOP::  -1
19      doFunction();

LOOP::  1

Breakpoint 2, doFunction () at test.c:7
7     count += 2;

(gdb)

...正如我想要的那样:P 只是不知道它有多可靠(以及是否可以使用avr-gdb,这就是我需要这个的:) 编辑:Ubuntu 11.04 中 avr-gdb 的版本当前是 6.4,它无法识别 python 命令:()

 

好吧,希望这对某人有帮助,
Cheers!

 

这里有一些参考:

  • GDB:在标准输入上检测到错误
  • GDB 在将命令传送到 STDIN 时遇到问题
  • 回复: [Gdb] 如何使用GDB其他输入?
  • gdb 不接受 stdin 上的输入
  • 在 IDE 中使用 gdb - comp.os.linux.development.apps |谷歌网上论坛
  • rmathew:绝症
  • [教程] 在 C 中调用外部程序 (Linux) - GIDForums
  • shell - 如何通过 shebang 使用多个参数(即 #!)? - 堆栈溢出
  • 将 shell 的输出重定向/存储到 GDB 变量中? - 堆栈溢出
  • Corey Goldberg:Python - 重定向或关闭 STDOUT 和 STDERR
  • 愚蠢的悬崖 › 9. 编写 gdb 脚本
  • gdb python 脚本:哪里有parse_and_eval走了吗? - 堆栈溢出
  • shell - 调用gdb自动将参数传递给正在调试的程序 - VoidCC
  • 使用 tmpfs 在内存中存储文件/目录 | HowtoForge - Linux 指南和教程
  • 触摸文件不存在的简单方法 |蟒蛇 | Python
  • os.fork() 在 cgi 脚本中不同吗? - Python
  • java - 使用 GDB 编写测试 - 如何捕获输出? - 堆栈溢出
  • 使用 GDB 进行调试:如何在 Python 中创建 GDB 命令 - Wiki
  • GDB 参考卡
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何自动打印 GDB 中的每个执行行,直到到达给定的断点? 的相关文章

  • 启动时出现 OData v4 错误:找不到段“Whatever”的资源

    我正在构建新的 v4 服务 一切进展顺利 直到我为新模型 实体添加了新控制器 并在启动站点进行测试运行时收到此错误 控制器似乎编码正确 就像其他控制器一样 控制器 CustomersOData 中的操作 GetFeed 上的路径模板 Cus
  • 推导指南中的引用和值之间的差异

    考虑类型A template
  • 如何为 C 分配的 numpy 数组注册析构函数?

    我想在 C C 中为 numpy 数组分配数字 并将它们作为 numpy 数组传递给 python 我可以做的PyArray SimpleNewFromData http docs scipy org doc numpy reference
  • 读取文件特定行号的有效方法。 (奖励:Python 手册印刷错误)

    我有一个 100 GB 的文本文件 它是来自数据库的 BCP 转储 当我尝试导入它时BULK INSERT 我在第 219506324 行上收到一个神秘错误 在解决此问题之前 我想看看这一行 但可惜的是我最喜欢的方法 import line
  • 如何在GDB中重新运行程序多次?

    我有一个程序偶尔会失败 但出现相同的错误 为了调试它 我想在 GDB 下运行它 直到它失败 设置断点并重新运行它 我该怎么办 gdb args path to program
  • 获取 WPF 控件的所有附加事件处理程序

    我正在开发一个应用程序 在其中动态分配按钮的事件 现在的问题是 我希望获取按钮单击事件的所有事件 因为我希望删除以前的处理程序 我尝试将事件处理程序设置为 null 如下所示 Button Click null 但是我收到了一个无法分配 n
  • ASP.NET:获取自 1970 年 1 月 1 日以来的毫秒数

    我有一个 ASP NET VB NET 日期 我试图获取自 1970 年 1 月 1 日以来的毫秒数 我尝试在 MSDN 中寻找方法 但找不到任何东西 有谁知道如何做到这一点 从 NET 4 6 开始 该方法ToUnixTimeMillis
  • 关于在 Windows 上使用 WiFi Direct Api?

    我目前正在开发一个应用程序 我需要在其中创建链接 阅读 无线网络连接 在桌面应用程序 在 Windows 10 上 和平板电脑 Android 但无关紧要 之间 工作流程 按钮 gt 如果需要提升权限 gt 创建类似托管网络的 WiFi 网
  • 如何在 Linq 中获得左外连接?

    我的数据库中有两个表 如下所示 顾客 C ID city 1 Dhaka 2 New york 3 London 个人信息 P ID C ID Field value 1 1 First Name Nasir 2 1 Last Name U
  • 在一个字节中存储 4 个不同的值

    我有一个任务要做 但我不知道从哪里开始 我不期待也绝对不想要代码中的答案 我想要一些关于该怎么做的指导 因为我感到有点失落 将变量打包和解包到一个字节中 您需要在一个字节中存储 4 个不同的值 这些值为 NAME RANGE BITS en
  • C++:.bmp 到文件中的字节数组

    是的 我已经解决了与此相关的其他问题 但我发现它们没有太大帮助 他们提供了一些帮助 但我仍然有点困惑 所以这是我需要做的 我们有一个 132x65 的屏幕 我有一个 132x65 的 bmp 我想遍历 bmp 并将其分成小的 1x8 列以获
  • 上下文敏感与歧义

    我对上下文敏感性和歧义如何相互影响感到困惑 我认为正确的是 歧义 歧义语法会导致使用左推导或右推导构建多个解析树 所有可能的语法都是二义性的语言是二义性语言 例如 C 是一种不明确的语言 因为 x y 总是可以表示两个不同的事物 如下所述
  • 如何使用 Mongodb C# 驱动程序连接多个集合

    我需要将 3 个集合与多个集合合并在一起 lookup我在 C 驱动程序中尝试过 它允许我 lookup用户采集但无法执行秒 lookup用于设置集合 有人可以帮忙吗 db Transactions aggregate lookup fro
  • 如何编写一个同时需要请求和响应Dtos的ServiceStack插件

    我需要提供本地化数据服务 所有本地化的响应 Dto 都共享相同的属性 IE 我定义了一个接口 ILocalizedDto 来标记那些 Dto 在请求端 有一个ILocalizedRequest对于需要本地化的请求 Using IPlugin
  • 有人可以提供一个使用 Amazon Web Services 的 itemsearch 的 C# 示例吗

    我正在尝试使用 Amazon Web Services 查询艺术家和标题信息并接收回专辑封面 使用 C 我找不到任何与此接近的示例 所有在线示例都已过时 并且不适用于 AWS 的较新版本 有一个开源项目CodePlex http www c
  • 如何从main方法调用业务对象类?

    我已将代码分为业务对象 访问层 如下所示 void Main Business object public class ExpenseBO public void MakeExpense ExpensePayload payload var
  • gcc 的配置选项如何确定默认枚举大小(短或非短)?

    我尝试了一些 gcc 编译器来查看默认枚举大小是否很短 至少一个字节 强制使用 fshort enums 或无短 至少 4 个字节 强制使用 fno short enums user host echo Static assert 4 si
  • Server.MapPath - 给定的物理路径,预期的虚拟路径

    我正在使用这行代码 var files Directory GetFiles Server MapPath E ftproot sales 在文件夹中查找文件 但是我收到错误消息说 给定物理路径但虚拟路径 预期的 我对在 C 中使用 Sys
  • 如何在按钮单击时模拟按键 - Unity

    我对 Unity 中的脚本编写非常陌生 我正在尝试创建一个按钮 一旦单击它就需要模拟按下 F 键 要拾取一个项目 这是我当前的代码 在编写此代码之前我浏览了所有统一论坛 但找不到任何有效的东西 Code using System Colle
  • 防止在工厂方法之外实例化对象

    假设我有一个带有工厂方法的类 class A public static A newA Some code logging return new A 是否可以使用 a 来阻止此类对象的实例化new 那么工厂方法是创建对象实例的唯一方法吗 当

随机推荐

  • 无法识别元素“folderLevelBuildProviders”?

    我使用Visual studio打开atomesite 我将MVC 1修改为MVC 2 构建成功 但网页给我这个错误 我尝试了 aspnet regiis iru 但不起作用 Server Error in Application Conf
  • 在 Elastic Search 中计算 *Facet 计数* 的有效方法

    我想计算构面查询 UI 的构面计数 但我认为我遗漏了一些东西 因为我无法使用构面过滤器获取所需的数字 这是一个例子 给定两个方面 每个方面具有三个可能的项 Colors red yellow blue Notes do re mi 当我进行
  • Python 终止符错误

    我正在和我的一个学校朋友一起开发一个 Python 项目 我们导入了 Turtle 和 Math 我的问题是 当我使用 Esc 按钮关闭窗口时 我收到一条错误消息 Terminator Error 我问过老师 但他们也不知道问题出在哪里 因
  • 如何使用文本扫描读取文件中的所有行

    我正在尝试使用以下内容读取 m 文件中的所有行 file content textscan fid s delimiter n whitespace 但这只是返回 file content 0x1 cell 实际上我的文件有 224 行 所
  • 如何下载在我的服务器(springboot)上生成的角度pdf文件?

    我想下载一个从基于 Spring 的 Restful Web 服务发送到我的 Angular 应用程序的 pdf 文件 如何下载它 我的 Angular 应用程序或 Spring Boot 上是否缺少一些代码 我从 Angular 6 应用
  • iPhone:屏幕截图[关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 当用户进行屏幕截图时 按住主页按钮 电源 是否有任何方法在应用程序中调用 或者可以调用哪
  • 在 Python OpenCV 中解码 YUV 图像

    我有一个 YUV420 SP NV21 图像 表示为字节数组 无标头 取自 Android 预览帧 我需要将其解码为 RGB 图像 我之前在 Android 应用程序中使用 Java 和 OpenCV4Android 完成过此操作 conv
  • 使用 Visual Studio Code 自动保存文件更改

    我用过WebStorm从 JetBrains 工作已经快四年了 出于多种原因 它是一个出色的 IDE 但最好的功能之一是它可以在版本控制之外保存文件版本 因此 如果您在版本控制系统保存文件之前不小心删除了文件或丢失了文件 WebStorm
  • 如何完全禁用任何鼠标点击

    在用户单击 登录 按钮和其他事件后 我制作了一个加载脚本 让用户知道他们必须等待 直到 ajax 回复 如何禁用任何鼠标点击 右键单击 左键单击 双击 中键单击 x 单击 on div id doc 我想将该代码添加到loading js
  • 使用 OpenSSL “无法写入‘随机状态’”是什么意思?

    我正在生成一个自签名 SSL 证书来保护我的服务器的管理部分 并且我不断从 OpenSSL 收到此消息 无法写入 随机状态 这是什么意思 这是在 Ubuntu 服务器上 我已经升级了 libssl 来修复最近的安全漏洞 实际上 发生这种情况
  • 点击表单中的提交按钮后如何显示隐藏的div?

    我有一个带有提交按钮的简单 HTML 表单 点击此按钮后我想看看div my id这是以前不可见的
  • “zsh:找不到命令:sails”的问题

    我用 via 安装了 sails jssudo npm install g sails但我仍然得到zsh command not found sails 我正在使用 Ubuntu 14 04 LTS 首先找出节点的路径which node会
  • 错误 193 %1 不是有效的 Win32 应用程序

    当我运行此 python 命令时 我发现此错误 Error 193 1 不是有效的 Win32 应用程序Windll LoadLibrary C Windows System32 plcommpro dll 对于这个错误 我发现我的 plc
  • 需要 RestKit 数据同步场景的帮助

    我正在将 RestKit 用于 iOS To 应用程序 我已经使用restkit完成了以下操作 1 从rest api中以json格式拉取服务器对象 2 删除服务器上不再存在的核心数据中的孤立对象 现在我必须构建以下场景 如果设备上可以使用
  • 读取Excel单元格并将内容复制到txt文件

    我目前正在使用 RapidMiner 并尝试将 xlsx 文件中的 RapidMiner 结果复制到 txt 文件 以便使用 python 进行进一步处理 我在 A 列 A1 A1500 中有纯文本 在 C 列 C1 C1500 中有相应的
  • IStructuralEquatable 和 IStructuralComparable 解决什么问题?

    我注意到 NET 4 中添加了这两个接口以及几个相关的类 它们对我来说似乎有点多余 我读过几篇关于它们的博客 但我仍然不明白它们解决了哪些在 NET 4 之前很棘手的问题 有什么用IStructuralEquatable and IStru
  • JPA:关于OneToMany关系中阻抗不匹配的问题

    我有一个关于 JPA 2 0 提供者是 Hibernate 关系及其在 Java 中相应管理的问题 假设我有一个部门和一个员工实体 Entity public class Department OneToMany mappedBy depa
  • 在 AVD 上运行的应用程序适用于 API 28,但不适用于 API 24

    My application runs fine in AVD Just like the image below when running on AVD which has API 28 My phone has API 24 which
  • Tinymce 4.2.0 无法读取 null 的属性“setContent”

    当我想使用 setContent 函数时 我得到 Cannot read property setContent of null 用于在 Tinymce 库生成的文本编辑器中设置值 实施它是错误的吗 下面是我的代码片段
  • 如何自动打印 GDB 中的每个执行行,直到到达给定的断点?

    我希望能够在 GDB 中设置一个断点 并让它运行到该点 并在此过程中打印出它 单步执行 的行 这是一个基于这个简单文件的示例main和一个函数 每个函数有两个断点 cat gt test c lt