首页 > 解决方案 > 如何在不向应用程序传递信号的情况下进行步进?

问题描述

假设在 GDB 下运行的进程由于接收到信号而停止,例如SIGSEGV由于访问无效位置。然后我修复该位置(通过写入寄存器或以任何其他方式)并希望单步执行,重试错误指令。

有一个 command stepi,如果信号被忽略或一开始没有被接收到,它将起作用。但是由于有一个待处理的信号,我不能使用它,至少不能直接使用。如果我使用signal 0命令,它会忽略信号,但它会作为continue. 因此,如果我使用signal 0,我必须找出下一条指令从哪里开始,在其上添加 atb等等。这很不方便。

另一种方式就像handle SIGSEGV ignore后面stepi跟着另一个handle命令来恢复它的原始状态。同样不方便:甚至不能define为此提供“黑匣子”功能,因为信号处理的原始状态可能是非默认状态,并且在si.

那么,有什么简单的方法可以在不继续执行的情况下删除挂起的信号吗?

标签: gdbsignalsbreakpoints

解决方案


在 gdb 7.9及更高版本中,有一个queue-signal命令可以让您0在下次恢复目标时发送信号(或者根本不发送信号,如果您将其作为参数提供)。这是一些文档

当线程恢复执行时,队列信号立即传递给当前线程。信号可以是信号的名称或编号。信号的处理必须设置为将信号传递给程序,否则GDB会报错。handle您可以使用该命令控制来自 GDB 的信号的处理。

或者,如果信号为零,则丢弃当前线程的任何当前排队的信号,并且在恢复执行时不会传递任何信号。

该命令与该命令signal的不同之处在于信号只是排队,不恢复执行。并且queue-signal不能用于传递处理状态已设置为 的信号nopass


推荐阅读