Hexagon GDB Debugger介绍(14)

2023-10-27

Hexagon GDB Debugger介绍 (14)

2.9.2 连续和单步调试

连续意味着恢复程序执行,直到程序正常完成。 相比之下,单步调试意味着只执行程序的一个"step",其中“step”可能意味着一行源代码或一条机器指令(取决于您使用的特定命令)。 在连续和单步执行时,程序可能会因断点而更快停止。

命令 描述
continue [ignore-count]
c [ignore-count]
fg [ignore-count]
在程序上次停止的地址继续执行程序; 在该地址设置的任何断点都将被绕过。 可选参数 ignore-count 允许指定更多次数以忽略此位置的断点; 它的效果类似于忽略(参见第 2.9.1.6 节)。
参数 ignore-count 仅在程序因断点而停止时才有意义。 在其他时候,参数 continue 被忽略。
同义词 c 和 fg(对于前台,因为被调试的程序被认为是前台程序)纯粹是为了方便而提供的,并且具有与 continue 完全相同的行为。

要在不同的地方恢复执行,您可以使用 return(参见第 2.17.3 节)返回调用函数; 或跳转(参见第 2.17.2 节)以转到程序中的任意位置。
使用单步调试的典型方法是在函数的开头或程序中认为存在问题的部分设置断点(参见第 2.9.1 节),运行程序直到它在该断点处停止,然后逐步通过可疑区域,检查感兴趣的变量,直到看到问题发生。

step
继续运行程序,直到控制权到达不同的源代码行,然后停止它并将控制权返回给调试器。 该命令缩写为s.

注意
    如果在控制位于没有调试信息的情况下编译的函数内时使用 step 命令,则执行将继续进行,直到控制到达具有调试信息的函数。  同样,它不会进入没有调试信息编译的函数。  要在没有调试信息的情况下单步执行函数,请使用 stepi 命令,如下所述。

step 命令仅在源代码行的第一条指令处停止。 这可以防止可能在 switch 语句、for 循环等中发生的多次停止。如果在该行中调用具有调试信息的函数,则 step 继续停止。 换句话说,在该行内调用的任何函数都会因断点而停止。

此外,如果有该函数的行号信息,则 step 命令仅进入该函数。 否则它就像下一个命令一样。

step count
继续按步骤运行,但要计算次数。 如果到达断点,则步进立即停止。

next [count]
继续到当前(最里面)堆栈帧中的下一个源代码行。 这与 step 类似,但在代码行中出现的函数调用不会停止执行。 当控制到达在您发出下一个命令时正在执行的原始堆栈级别的不同代码行时,执行将停止。 该命令缩写为 n。
参数计数是重复计数,对于step。
下一个命令仅在源代码行的第一条指令处停止。 这可以防止可能在 switch 语句、for 循环等中发生的多次停止。

set step-mode
set step-mode on

set step-mode on 命令导致 step 命令在不包含调试行信息的函数的第一条指令处停止,而不是跳过它。
这在你可能有兴趣检查没有符号信息的函数的机器指令并且不希望调试器自动跳过此函数的情况下很有用。

set step-mode off
使 step 命令跳过任何不包含调试信息的函数。 这是默认设置。

finish
继续运行,直到所选堆栈帧中的函数返回之后。 打印返回值(如果有)。
将此与返回命令进行对比(参见第 2.17.3 节)。

until
u

继续运行,直到到达当前堆栈帧中超过当前行的源行。 此命令用于避免多次单步执行循环。 和next命令一样,只不过until遇到跳转时,会自动继续执行,直到程序计数器大于跳转的地址。
这意味着在单步执行循环后到达循环末尾时,until 使程序继续执行,直到它退出循环。 相比之下,循环末尾的下一个命令只是返回到循环的开头,这会迫使你逐步执行下一次迭代。
如果程序试图退出当前堆栈帧,则它始终会停止。
如果机器代码的顺序与源代码行的顺序不匹配,直到会产生一些违反直觉的结果。 例如,在以下调试会话的摘录中,f(frame)命令显示执行在第 206 行停止; 但是当我们使用until时,我们到达了第195行:

(hexagon-gdb) f
#0  main (argc=4, argv=0xf7fffae8) at m4.c:206

206                 expand_input();
(hexagon-gdb) until
195             for ( ; argc > 0; NEXTARG) {

这种情况是因为,为了执行效率,编译器在循环结束而不是开始时生成了用于循环闭合测试的代码,即使 C for 循环中的测试是在循环体之前编写的。 当它前进到这个表达式时,until 命令似乎退回到循环的开头。 然而,它并没有真正进入更早的语句,而不是在实际的机器代码方面。
没有参数的until通过单指令单步调试,因此比有参数的until慢。

until location
u location

继续运行程序,直到到达指定位置或当前堆栈帧返回。 location 是任何可以接受的参数形式的中断(参见第 2.9.1.1 节)。 这种形式的命令使用断点,因此比不带参数的 until 更快。 只有在当前帧中才实际到达指定位置。 这意味着直到可以用来跳过递归函数调用。 例如,在下面的代码中,如果当前位置是第 96 行,则发出直到 99 将在相同的阶乘调用中(即,在内部调用返回之后)执行到第 99 行的程序。

94 int factorial (int value)
95 {
96     if (value > 1) {
97            value *= factorial (value - 1);
98     }
99     return (value);
100 }

advance location
继续运行程序到给定的位置。 至少一个参数,任何形式与 break 命令的参数相同。 从当前堆栈帧退出时,执行也将停止。 该命令类似于until,但advance 不会跳过递归函数调用,并且目标位置不必与当前位置在同一帧中。

stepi
stepi arg
si

执行一条机器指令,然后停止并返回调试器。
在按机器指令步进时执行 display/i $pc 通常很有用。 这使得调试器在每次程序停止时自动显示下一条要执行的指令。 见第 2.12.6 节。
参数是重复计数,如step所示。

nexti
nexti arg
ni

执行一条机器指令,但如果是函数调用,则继续执行,直到函数返回。
参数是重复计数,如next所示。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Hexagon GDB Debugger介绍(14) 的相关文章

  • 显示 GDB 中当前的汇编指令

    我正在 GDB 中进行一些汇编级调试 有没有办法让 GDB 以与显示当前源代码行相同的方式显示当前的汇编指令 每个命令后的默认输出如下所示 0x0001433f 990 Foo bar p 这给了我当前指令的地址 但我必须继续参考disas
  • 使用gdb将地址转换为行

    我有一个由剥离的应用程序生成的堆栈跟踪 如下所示 Check failure stack trace 0x7f0e442d392d unknown 0x7f0e442d7b1f unknown 0x7f0e442d7067 unknown
  • 是什么让GDB拒绝崩溃?

    我在这里不知所措 我正在用 C 编写一个编译器 出于爱好 并使用 GDB 7 3 在 amd64 Linux 2 6 32 上使用 GCC 4 6 1 进行编译 除了通常的 I 等之外 标志还有 Wall Wextra O0 g 我有一个函
  • 如何将 gdb 附加到 docker 容器中运行的进程?

    我在 docker 容器中有一个长时间运行的进程 我想将 gdb 附加到该进程以查看正在运行的线程并获取堆栈跟踪 我可以从主机附加到进程 但无法解析任何符号 因为可执行文件位于文件系统中的不同位置 位于 docker 安装的卷中 并且共享系
  • 如何判断共享库加载到进程地址空间中的位置?

    我正在尝试调试一个共享库 其中有使用 gdb 的源代码和调试符号 我没有实际使用此共享库的进程的调试符号或代码 我自己编译它 所以我可以拥有一切 但生成的二进制文件被剥离 以模拟我没有代码的情况 该进程打印我正在尝试调试的目标函数 foo
  • 在 MacOS 上从源代码构建 gdb

    我正在尝试在 Apple M1 MacBook 上安装交叉编译的 gdb 我下载了 gdb 11 1 并执行了以下操作 tmp src gdb 11 1 configure enable targets all make sudo make
  • Go:使用 gdb 打印变量

    在此程序中 如何使用调试器中断执行并打印 i 的值 package main import fmt func main x abc i 3 fmt Println i fmt Println x 我无法打印我 不过我可以打印 x go bu
  • gdb 输入文件中的十六进制值

    我正在尝试通过使用 gdb 内的 run 我可以成功地溢出程序 但在将十六进制值附加到字符串时遇到问题 我尝试过引用 将 mem addr 的值转换为 ascii 以及各种转义尝试 但没有成功 输入文件示例 AAAA x42 在上面的示例中
  • 如何在GDB中运行记录指令历史记录和函数调用历史记录?

    编辑 根据下面的第一个答案 当前的 技巧 似乎正在使用 Atom 处理器 但我希望一些 gdb 专家可以回答这是否是一个基本限制 或者路线图上是否添加了对其他处理器的支持 反向执行似乎在我的环境中起作用 我可以反向继续 查看合理的记录日志
  • 分离Gdb而不恢复劣质

    Gdb 与任何其他程序一样 并不完美 我时不时会遇到导致当前 Gdb 实例无法使用的错误 此时 如果我有一个调试会话 其中有很多有价值的状态 我希望能够在其上启动一个新的 Gdb 会话 也就是说 分离 退出 Gdb 并启动一个新的 Gdb
  • GDB 函数参数上的条件中断

    我想在函数参数大于某个值时设置断点 下面的虚拟代码 int main void uint64 t num 123456 uint64 t x 847534 uint64 t other num x x num other stuff her
  • 如何在 gdb 中禁用“键入 继续,或 q 退出”?

    我想要自动化gdb 并且等待用户输入是不可取的 如何禁用消息 Type
  • 专门逐行调试

    我有一个用 Pascal 编写的脚本 我会以这种方式调试它 在每一行停止 转储内存中所有变量的值 然后转到下一行 是否可以使用 gdb 或其他 Linux 开源工具来完成此操作 使用选项编译文件 g fpc gpc g file pas R
  • GDB/bin/bash 无法在 Eclipse CDT 中执行应用程序?

    在 Mac OS X Mojave 上使用 Eclipse CDT 运行 GDB 时遇到困难 当我尝试调试项目时 GDB 表现得很混乱 我能够调试几次 但随后它在下一个调试会话开始时开始停止 并显示消息 配置 GDB 可执行文件是 User
  • GDB错误:“进程记录:当前架构不支持记录功能”

    我正在尝试在 GDB 中进行反向执行 特别是target record按照说明在 gdb 中运行我的程序后here https stackoverflow com questions 1206872 go to previous line
  • Eclipse 调试模式下的 GDB 找不到 stdlib/rand.c

    我试图让 gdb 在 ubuntu 上与 eclipse cdt 一起运行 以开始调试一些简单的程序 所以我做了我认为必要的步骤来让它运行 1 创建可执行项目 2 Compile 3 Run 4 创建文件 gdbinit 并将其放在主项目文
  • 缺少单独的调试信息,请使用: debuginfo-install glibc-2.12-1.47.el6_2.9.i686 libgcc-4.4.6-3.el6.i686 libstdc++-4.4.6-3.el6.i686

    CentOS 6 2 GNU gdb GDB 红帽企业 Linux 7 2 50 el6 当我使用 GDB 调试简单的 C 代码时 我看到以下警告 Missing separate debuginfos use debuginfo inst
  • 防止GDB中的PLT(过程链接表)断点

    在最新版本的 GDB 中 在库函数调用上设置断点会导致多个实际断点 调用过程链接表 PLT 实际的函数调用 这意味着当调用库函数时 我们每次都会经历两次中断 在以前的 GDB 版本中 只会创建 2 因此您只能得到一次中断 那么问题来了 是否
  • TUI模式下的GDB:如何处理stderr与ui的交互

    我正在尝试使用gdb来调试caffe http caffe berkeleyvision org 我更喜欢使用 tui 模式 因为它允许我查看整个源代码而不仅仅是一行 但有一个问题 每当程序caffe输出一些东西stderr 输出扭曲了 t
  • gcc 中 -g 选项的作用是什么

    我看到很多关于 gdb 的教程要求在编译 c 程序时使用 g 选项 我无法理解 g 选项的实际作用 它使编译器将调试信息添加到生成的二进制文件中 此信息允许调试器将代码中的指令与源代码文件和行号相关联 拥有调试符号可以使某些类型的调试 例如

随机推荐