调试器如何能够在任何抛出异常时中断程序?

10
在GDB和其他调试器中,可以使用catch throw命令要求调试器在将异常传递给相应的异常处理程序之前停止。这种机制是如何实现的?是否有可用于挂接的操作系统信号?是否有函数指针可以打补丁以允许此操作?是否使用单步执行使其发生?
除了调试器外,是否还有其他机制可用于实现此功能?
1个回答

10

GDB在库函数上设置了断点,该函数执行堆栈展开(对于x86_64是__cxa_throw())以实现catch throw。它将使用与设置任何其他类型代码断点相同的机制来设置此断点。

这个机制是通过什么方式实现的?有没有操作系统信号可以用来进行钩入?有没有函数指针可以猴子补丁以允许此操作发生?它是否单步执行来使其发生?

以上都不是。这只是对__cxa_throw()的普通断点。GDB利用对C++运行时实现的了解,具有所有这些缺点。C++异常在操作系统的监视之下,所以操作系统不会知道它们的存在。混淆的原因在于某些信号(例如段错误)在Windows上被称为异常,并且在调试时可以像处理C++异常一样处理。但这是使操作系统信号(例如段错误)表现得像C++异常,而不是反过来。

另请参见ftp://ftp.gnu.org/old-gnu/Manuals/gdb/html_node/gdb_30.html


在 GNU/Linux 平台上,至少 x86_64 架构下,gdb 的 catch throw 实际上是在 __cxa_throw 上设置断点,而 catch catch 则在 __cxa_begin_catch 上设置断点。 - Arne Vogel
看起来我提到的这些函数名称实际上是由Itanium C++ ABI强制规定的英特尔架构 - 请注意,微软Windows是唯一一个在该架构上不遵循此ABI的主要平台。 - Arne Vogel
@Arne:谢谢你的信息,我会更新答案。 - Johannes Overmann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接