无意义的C++和Objective-C++在Mavericks上崩溃

Tom*_*ing 5 c++ macos objective-c++ osx-mavericks

我有一个大型Mac应用程序,可以在大型数据集上运行几天.它是Objective-C++和C++的混合体.它在Mountain Lion上运行得很好,但是在Mavericks上,在运行了大约10到20分钟(其中分配和销毁了几百万个对象)后,它崩溃了.它表现得好像是因为无效指针崩溃(即在已删除的C++对象上调用一个函数),但它所指向的对象处于完全没有意义的状态.

我的所有C++类都继承自一个公共基类,其构造函数如下所示:

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

当它崩溃时,调试器显示在坏对象中,值为mCreated0.它的行为好像对象从未运行其构造函数!

我不认为这是内存踩踏,因为这个值永远不会是0或其预期值,并且对象中没有其他字段的值看起来像是你期望从内存中踩踏的垃圾.

我也尝试过使用scribble运行,0x555并且0xaaa值和值不会显示在任何地方.我也试过Guard Edges.

深入调查没有透露任何信息.坏对象甚至不是同一个类.我能想到的是,Mavericks中的新内存(压缩未使用的内存)会导致一些新的行为(可能是一个bug或者一些以前未知的,大部分是非执行的规则,现在真的很重要).

有没有人见过类似的东西?或者有没有人知道任何大多数未知的内存规则会在Mavericks下更强烈地应用?

Ken*_*ses 4

我认为您对无效指针的怀疑是正确的。它可能是指向已删除对象的指针,也可能是垃圾指针。任一者都会与mCreated您期望的成员不同。在删除对象的情况下,内存可以用于其他用途,因此设置为其他值。对于垃圾指针,您没有指向任何曾经是您的类的实例的东西。

我不知道分配工具对于 C++ 对象的工作效果如何,但您可以尝试在该工具下重现崩溃。当它在调试器中停止时,获取this指针,然后从 Instruments 获取该地址的历史记录。

如果 Instruments 不起作用,您可以设置MallocStackLoggingNoCompact环境变量。然后,当它在调试器中停止时,检查this指针并使用以下命令查看该地址的历史记录:

(lldb) script import lldb.macosx.heap
(lldb) malloc_info --stack-history 0x10010d680
Run Code Online (Sandbox Code Playgroud)

(当然,使用this地址而不是。)0x10010d680

或者,malloc_history如果在 LLDB 中执行此操作很麻烦,您可以使用 shell 中的命令来调查历史记录。