C++ 荒谬的C++;和目标-C++;撞上小牛队

C++ 荒谬的C++;和目标-C++;撞上小牛队,c++,macos,objective-c++,osx-mavericks,C++,Macos,Objective C++,Osx Mavericks,我有一个大型Mac应用程序,在一个大数据集上运行几天。它是Objul-C++和C++的混合体。它在Mountain Lion上运行得很好,但在Mavericks上,在运行大约10到20分钟(其中分配和销毁了数百万个对象)后,它崩溃了。它的行为好像是用一个无效的指针崩溃(即调用一个被删除的C++对象的函数),但是它指向的对象处于一个完全没有意义的状态。 P>所有的C++类都继承了一个公共基类,构造函数看起来类似于这个: MyClass::MyClass() { mCreated = 1234

我有一个大型Mac应用程序,在一个大数据集上运行几天。它是Objul-C++和C++的混合体。它在Mountain Lion上运行得很好,但在Mavericks上,在运行大约10到20分钟(其中分配和销毁了数百万个对象)后,它崩溃了。它的行为好像是用一个无效的指针崩溃(即调用一个被删除的C++对象的函数),但是它指向的对象处于一个完全没有意义的状态。 <> P>所有的C++类都继承了一个公共基类,构造函数看起来类似于这个:

MyClass::MyClass()
{
  mCreated = 12345; //int member variable set here and NEVER TOUCHED AGAIN.
  //other initialization stuff
}
当它崩溃时,调试器显示在坏对象中,
mCreated
的值为0。它的行为就像对象从未运行过它的构造函数一样

我不认为这是内存踩踏,因为这个值永远不是0或它的期望值以外的任何值,并且对象中的其他字段都没有看起来像内存踩踏所期望的垃圾的值

我也尝试过在scribble打开的情况下运行,
0x555
0xaaa
值不会显示在任何地方。我也试过保护边缘

深入调查没有发现任何情况。坏对象甚至不总是同一个类。我所能想到的是,在Mavericks中使用新内存的东西(压缩未使用的内存)会导致一些新的行为(可能是一个bug,也可能是一些以前未知的、大部分是未强制执行的规则,这些规则现在真的很重要)


有人见过类似的东西吗?或者有人知道在Mavericks下应用得更为强大的大部分未知内存规则吗?

我认为关于无效指针的怀疑你是对的。它可能是指向已删除对象的指针,也可能是垃圾指针。任何一个都将与
mCreated
成员一致,这与您预期的不同。对于已删除的对象,内存可用于其他用途,因此可设置为其他值。对于垃圾指针,您没有指向任何曾经是类实例的对象

<>我不知道分配工具对C++对象有多好,但是你可以试着在下面重写崩溃。当它在调试器中停止时,获取
this
指针,然后从仪器中获取该地址的历史记录

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

(lldb) script import lldb.macosx.heap
(lldb) malloc_info --stack-history 0x10010d680
(当然,使用
地址而不是
0x10010d680


或者,如果在LLDB中执行历史记录比较麻烦,您可以使用shell中的命令来研究历史记录。

最近学习了非常有用的调试技术(因此我觉得分享它更好):GDB(当然还有LLDB)可以监视内存地址的读写。我不记得确切的命令,但你肯定会在这里找到它,搜索“gdb watch memory access”。等等,不,@H2CO3-很高兴知道,但无法知道它将阻塞哪个地址。你为什么不使用初始化列表?@Jefferson先生,我猜对象可能已被破坏。您可以为构造函数和析构函数设置断点,当构造函数中的断点命中时,设置观察点并继续,当析构函数中的断点命中时,删除该观察点并继续。如果没有,我建议您使用
this
转储来记录所有对象构造函数和析构函数。并检查日志,当崩溃发生时,访问的对象是否已被销毁。我尝试了此选项,并在其停止的地址上调用了malloc_信息。它一点也没有回报。我确认我给的地址是对的。我在堆栈中另一个处于有效状态的对象的地址上尝试了它,它打印了一行关于malloc的内容,然后是关于类的全名的内容,然后是“error:expression failed”,后面是一堆以
typedef int kern\u return\t;typedef未签名任务\u t#定义最大帧128
等。看起来像头文件或其他文件的一部分。尝试使用“malloc_历史记录”工具。我知道但没有使用LLDB命令的经验。它可能有局限性。不过,您得到的结果表明,
这个
指针是垃圾。尝试向上移动堆栈,找出调用方从何处获取其调用成员函数的实例指针。也许它是从一个已解除分配实例的成员变量中获得的,等等。在某个地方,垃圾链开始了。