“如何追踪”;libc++;abi.dylib:调用纯虚拟函数&引用;在Xcode中 我有一个多线程的OS X应用程序,它使用C++、ObjuleC和SWIFT的混合。

“如何追踪”;libc++;abi.dylib:调用纯虚拟函数&引用;在Xcode中 我有一个多线程的OS X应用程序,它使用C++、ObjuleC和SWIFT的混合。,c++,xcode,macos,C++,Xcode,Macos,当我的应用程序关闭时,我在Xcode调试器窗口中看到: libc++abi.dylib: Pure virtual function called! 我知道这个错误通常是由C++类构造函数或析构函数中虚函数调用引起的。 有没有简单的方法可以找到它的位置?所谓“简单”,我的意思是“不分析每一个具有虚函数的类的构造函数和析构函数的每一行的调用树” 我没有看到堆栈跟踪。打印此消息时,调试器不会停止程序。我的应用程序代理的applicationIDTerminate方法记录的消息位于此消息之前 我尝试

当我的应用程序关闭时,我在Xcode调试器窗口中看到:

libc++abi.dylib: Pure virtual function called!

我知道这个错误通常是由C++类构造函数或析构函数中虚函数调用引起的。 有没有简单的方法可以找到它的位置?所谓“简单”,我的意思是“不分析每一个具有虚函数的类的构造函数和析构函数的每一行的调用树”

我没有看到堆栈跟踪。打印此消息时,调试器不会停止程序。我的应用程序代理的
applicationIDTerminate
方法记录的消息位于此消息之前


我尝试在“所有异常”上设置一个断点,但不幸的是,该断点经常被使用大量异常的代码击中。是否有其他符号可以放置断点?

首先,它很可能位于析构函数中,在析构函数中调用纯虚函数,而不是构造函数(不保证,但可能)

如果在调用纯虚拟函数时编译器生成异常,则可以通过使用
set\u terminate()
(例如explained)设置自己的终止处理程序来捕获异常。然后,可以在terminate处理程序中设置一个断点,以查看代码是如何到达该点的

如果调用纯虚拟函数时编译器未生成异常(更可能的情况),则可以尝试添加自己的伪类,以帮助缩小发生错误调用的范围。只需让这些虚拟类在其析构函数中打印一些内容,并确保它们在某些时候被删除,从而有助于缩小事件发生的范围。例如,在main()函数的最开始处放置一个,如果看到打印的消息,则在删除静态对象时会发生错误调用,因为该伪对象将是main()返回之前删除的最后一个对象。通过添加虚拟类作为可以修改的其他类的第一个数据成员,您可以做类似的事情,但是您需要了解对象被删除后会导致有问题的纯虚拟函数调用


最后,如果它有用,您实际上可以为纯虚拟函数提供一个实现,并且这些函数实际上可以被调用(是的,这是合法的C++)。如果您知道要调用的纯虚拟函数的确切名称,那么您可以为它提供一个实现,并在其中放置一个断点以捕获堆栈跟踪。这取决于您确切地知道正在调用的纯虚拟函数,而您的问题表明这可能是未知的。

C++标准库定义了一些实现低级语言/库功能的“ABI”函数
libc++
有一个很好的文档来描述它们

其中之一是
\ucxa\upure\uvirtual
,当程序以某种方式调用纯虚拟函数时,会调用该函数。因此,如果您在那里设置了断点,您应该能够找到发生这种情况的位置


通常,当
vtable
处于中间状态时,从构造函数或析构函数中调用虚函数时,会发生纯虚函数调用。有关更多详细信息,请参阅。

查看任何在其析构函数中调用虚拟方法的类,或者实际上调用其析构函数中任何方法的类,因为这些方法本身可能调用虚拟方法。在基类的析构函数中,派生类不再存在,因此虚拟函数调用将执行基类的版本。通常会生成崩溃日志报告,因为该错误是异常
SIGABRT
。若并没有,那个么可能会在代码中搜索“virtual”,并在每个代码上设置断点;这应该只是一个消除过程的问题。在
\uucxa\upure\uvirtual
@TavianBarnes上设置一个断点。我想你的答案是正确的。如果你能给出一个真实的答案,你就可以得到赏金。