I have a multithreaded OS X application that uses a mixture of C++, Objective-C, and Swift.
When my application shuts down, I see this in the Xcode debugger window:
libc++abi.dylib: Pure virtual function called!
I know that this error is typically caused by a call to a virtual function in a C++ class constructor or destructor.
Is there an easy way to find where it is? By "Easy", I mean "not analyzing call trees for every line of every constructor and destructor of every class that has a virtual function".
I don't see a stack trace. The debugger does not halt the program when this message is printed. A message logged from my app delegate's applicationDidTerminate
method precedes this message.
I tried setting a breakpoint on "All exceptions" but unfortunately that breakpoint is hit often by code that uses lots of exceptions. Is there some other symbol where I can put a breakpoint?
C++ standard libraries define a few "ABI" functions that implement low-level language/library features. libc++
has a nice document that describes them here.
One of them is __cxa_pure_virtual
, which is called when a program somehow invokes a pure-virtual function. So if you set a breakpoint there, you should be able to find out where that's happening.
Usually, pure virtual function calls happen when you call a virtual function from within a constructor or destructor, while the vtable
is in an intermediate state. See this answer for more details.
First up, it is mostly likely in a destructor where the call to a pure virtual function is being made rather than a constructor (not guaranteed, but likely).
If an exception is being generated by your compiler when a pure virtual function is called, then you may be able to catch it by setting up your own terminate handler with set_terminate()
(e.g. explained here). You could then set a breakpoint in your terminate handler to see exactly how your code is getting to that point.
If an exception is not generated by your compiler when a pure virtual function is called (the more likely situation), then you could try adding your own dummy classes to help narrow down where the offending call is occurring. Simply have these dummy classes print something in their destructors and ensure they get deleted at times that help narrow down when things occur. For example, place one at the very start of your main() function and if you see its message printed then the offending call is happening when static objects are being deleted because that dummy object would be the last object deleted before main() returns. You could do similar things by adding such dummy classes as the first data member of other classes you can modify, but you need some idea of the objects being deleted leading up to the offending pure virtual function call.
Finally, in case it is useful, you can actually provide an implementation for pure virtual functions and these can in fact be called (yes, this is legal C++). If you know the exact pure virtual function being called, then you could provide an implementation for it and put a breakpoint in there to catch the stack trace. This relies on you knowing exactly the pure virtual function being called though and your question suggests this might not be known.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With