Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to track down "libc++abi.dylib: Pure virtual function called!" in Xcode

Tags:

c++

xcode

macos

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?

like image 896
Kristopher Johnson Avatar asked Dec 02 '15 19:12

Kristopher Johnson


2 Answers

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.

like image 122
Tavian Barnes Avatar answered Sep 30 '22 11:09

Tavian Barnes


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.

like image 22
Craig Scott Avatar answered Sep 30 '22 12:09

Craig Scott