Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nonsensical C++ and Objective-C++ crash on Mavericks

I've got a large Mac app that runs for a couple of days at a time operating on a large data set. It's a mix of Objective-C++ and C++. It runs great on Mountain Lion, but on Mavericks, after running for about 10 to 20 minutes (in which a couple of million objects are allocated and destroyed), it crashes. It behaves as if it's crashing with an invalid pointer (i.e. calling a function on a deleted C++ object), but the object it's pointing to is in a state that makes absolutely no sense.

All my C++ classes inherit from a common base class where the constructor looks something like this:

MyClass::MyClass()
{
  mCreated = 12345; //int member variable set here and NEVER TOUCHED AGAIN.
  //other initialization stuff
}

When it crashes, the debugger shows that in the bad object, the value for mCreated is 0. It's behaving as if the object never ran its constructor!

I don't think it's memory stomping, because this value is never anything other than 0 or its expected value, and none of the other fields in the object have values that look like the garbage you'd expect from memory stomping.

I've also tried running with scribble turned on, and the 0x555 and 0xaaa values don't show up anywhere. I've also tried Guard Edges.

In-depth investigation has not revealed anything. The bad object isn't even always the same class. All I can think of is that something with the new memory stuff in Mavericks (compressing unused memory) is causing some new behavior (maybe a bug or maybe some previously unknown, mostly-unenforced rule that now really matters).

Has anyone seen anything similar? Or does anyone know of any mostly-unknown memory rules that would apply more strongly under Mavericks?

like image 868
Tom Hamming Avatar asked Oct 02 '22 09:10

Tom Hamming


1 Answers

I think you're right about the invalid pointer suspicion. It might be a pointer to a deleted object or it might be a garbage pointer. Either one would be consistent with the mCreated member being different than you expect. In the case of a deleted object, the memory could be used for something else and therefore set to some other value. In the case of a garbage pointer, you're not pointing to anything that ever was an instance of your class.

I don't know how well the Allocations instrument works for C++ objects, but you could try reproducing the crash under that. When it stops in the debugger, get the this pointer and then get the history of that address from Instruments.

If Instruments doesn't work, you can set the MallocStackLoggingNoCompact environment variable. Then, when it stops in the debugger, examine the this pointer and use the following commands to view the history of that address:

(lldb) script import lldb.macosx.heap
(lldb) malloc_info --stack-history 0x10010d680

(Use the this address instead of 0x10010d680, of course.)

Alternatively, you can use the malloc_history command from a shell to investigate the history, if doing it within LLDB is cumbersome.

like image 139
Ken Thomases Avatar answered Oct 17 '22 23:10

Ken Thomases