GDB使用什么信号来实现tracee和tracer之间的控制转移

时间:2017-11-27 02:09:37

标签: gdb signals

通过控制转移,我的意思是,在tracee执行一个函数并返回之后,生成哪个信号,以便GDB可以等待*()并再次获取控制权?虽然很多人声称......不是SIGTRAP。

1 个答案:

答案 0 :(得分:2)

  

在tracee执行一个函数并返回后,生成哪个信号,以便GDB可以等待*()并再次获取控制权?

当一个“有趣”事件发生时,tracee被停止,控件被转移回GDB,

有趣的事件是:

  1. 断点开火,
  2. 如果执行无效的内存访问或无效的浮点操作,tracee会遇到一个信号(例如SIGSEGVSIGFPE),
  3. tracee完全消失(例如由外部程序获取SIGKILL),
  4. [可能还有其他“有趣”事件,但我现在想不出任何其他事情。]

    现在,对“GDB使用的信号......”的技术上正确答案是:完全没有。除非上述事件之一发生,否则控制不会转移。

    也许你的问题是:在执行类似finish命令(从当前函数中退出)之后,控制如何回到GDB?

    答案是:GDB在使我们进入当前函数的CALL指令之后立即在指令上设置临时断点。

    最后,是什么原因导致内核停止跟踪并使GDB中的waitpid在执行断点指令时返回?

    x86上,GDB使用INT3(操作码0xCC)指令设置断点(使用调试寄存器有另一种机制,但它仅限于4个同时断点,并且通常保留用于硬件观察点)。当tracee执行INT3指令时,SIGTRAP 确实是内核生成的信号(即您找到的其他答案都是正确的)。

    如果不知道是什么导致你相信不是 SIGTRAP,那么很难猜测你是如何说服自己不是。

    <强>更新

      

    我尝试手动向tracee发送SIGTRAP信号,试图导致GDB的虚假唤醒,但是失败了。

    以什么方式失败?

    我希望您观察到的是GDB以Program received signal SIGTRAP ...停止。那是因为GDB 知道它放置断点的位置。

    当GDB收到SIGTRAP 时,tracee指令指针与其中一个断点匹配,然后GDB“知道”这是已触发的断点,并相应地采取行动。

    但是当GDB收到SIGTRAP且跟踪IP 没有匹配任何断点时,GDB会将其视为任何其他信号:打印消息并等待你告诉它接下来要做什么。

      

    “GDB设置了一个临时断点......这意味着GDB必须修改tracee的代码区域,这可能是只读的。那么,GDB如何应对呢?

    你是对的:GDB需要修改(通常是不可写的).text部分以使用INT3方法插入任何断点。幸运的是,这是内核通过ptrace(POKE_TEXT, ...)授予它的“超级大国”之一。

    P.S。这是一个有趣的练习,可以使校验和自己函数之一的代码字节的程序变白。然后,您可以在“要校验和”功能上放置断点之前和之后执行校验和,并观察断点存在时校验和是否不同。

    P.P.S。如果您对GDB正在做的事情感到好奇,设置maintenance debug inferior将提供很多线索。