How to track "lib ++ abi.dylib: A pure virtual function called!" in Xcode

I have a multi-threaded 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 usually caused by a virtual function call in the constructor or destructor of the C ++ class.

Is there an easy way to find where it is? By "Easy" I mean "do not parse call trees for each row of each constructor and destructor of each class that has a virtual function."

I do not see the stack trace. The debugger does not stop the program when printing this message. A message registered from my applicationDidTerminate delegate method precedes this message.

I tried setting a breakpoint to “All Exceptions,” but unfortunately this breakpoint is often used by code that uses many exceptions. Is there any other character where I can put a breakpoint?

+5
source share
2 answers

C ++ standard libraries define several "ABI" functions that implement low-level language / library functions. libc++ has a nice document that describes them here .

One of them is __cxa_pure_virtual , which is called when the program somehow calls a purely virtual function. Therefore, if you set a breakpoint there, you can find out where this happens.

Typically, pure virtual function calls occur when you call a virtual function from a constructor or destructor, and vtable is in an intermediate state. See this answer for more details.

+3
source

First of all, this is most likely in a destructor where a pure virtual function is called, not a constructor (not guaranteed, but likely).

If an exception is thrown by your compiler when you call a pure virtual function, you can catch it by setting your own completion handler using set_terminate() (for example, explaining here ). You can then set a breakpoint in your completion handler to see exactly how your code reaches that point.

If an exception is not thrown by your compiler when calling a pure virtual function (a more likely situation), you can try adding your own dummy classes to narrow down where the abusive call occurs. It’s just that these dummy classes print something in their destructors and guarantee that they will be deleted at times, which will help narrow down when something happens. For example, put it at the beginning of your main () function, and if you see that its message is printed, an abusive call occurs when static objects are deleted, since this dummy object will be the last object deleted before main () returns. You can do such things by adding dummy classes such as the first data member of other classes, which you can change, but you need some idea of ​​the objects being deleted, leading to a violation of the purely virtual function call.

Finally, in case this is useful, you can actually implement the implementation for pure virtual functions, and in fact they can be called (yes, this is legal C ++). If you know the exact pure virtual function that you are calling, you can provide it with an implementation and put a breakpoint there to catch the stack trace. It depends on what you know exactly which virtual function is being called, and your question suggests that this may not be known.

+1
source

Source: https://habr.com/ru/post/1237279/


All Articles