EXC_断点崩溃的原因 我在一个C++逻辑单元中的一些用户计算机上发生了一个崩溃,在逻辑X中运行。不幸的是,我不能在本地重复它,在试图找出它可能发生的过程中,我有一些问题。p>
以下是来自崩溃转储的相关信息:EXC_断点崩溃的原因 我在一个C++逻辑单元中的一些用户计算机上发生了一个崩溃,在逻辑X中运行。不幸的是,我不能在本地重复它,在试图找出它可能发生的过程中,我有一些问题。p>,c++,macos,debugging,C++,Macos,Debugging,以下是来自崩溃转储的相关信息: Exception Type: EXC_BREAKPOINT (SIGTRAP) Exception Codes: 0x0000000000000001, 0x0000000000000000 Exception Note: EXC_CORPSE_NOTIFY Termination Signal: Trace/BPT trap: 5 Termination Reason: Namespace SIGNAL, Code 0x5 Terminating Proce
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Termination Signal: Trace/BPT trap: 5
Termination Reason: Namespace SIGNAL, Code 0x5
Terminating Process: exc handler [0]
问题是:
- 在我所看到的情况下,什么可能导致EXC_断点。Apple提供的信息是否完整且准确:“与异常退出类似,此异常旨在为附加的调试器提供在执行过程中的特定点中断进程的机会。您可以使用_builtin_trap()从自己的代码触发此异常如果未附加调试器,则终止进程并生成崩溃报告。“
- 为什么会发生在SharedObject+200上(请参阅反汇编)
- RBX是崩溃发生时的“this”指针李>
juce::ValueTree::SharedObject::SharedObject(juce::ValueTree::SharedObject const&) + 200
< C++ >如下:
SharedObject (const SharedObject& other)
: ReferenceCountedObject(),
type (other.type), properties (other.properties), parent (nullptr)
{
for (int i = 0; i < other.children.size(); ++i)
{
SharedObject* const child = new SharedObject (*other.children.getObjectPointerUnchecked(i));
child->parent = this;
children.add (child);
}
}
更新2:
在相关寄存器的崩溃寄存器值处:
this == rbx: 0x00007fe5bc37c950
&other == r12: 0x00007fe5bc348cc0
rax = 0
rcx = 0
此代码中可能存在一些问题:
- 就像前面提到的SM一样,其他.children.getObjectPointerUnchecked(i)可以返回null ptr
- 在
中,在调用ObjectClass*add(ObjectClass*const newObject)noexcept
之前检查newObject是否为null(这意味着此方法调用中可能会出现null),但在incremerenceCount
data.elements[numUsed++]=newObject期间添加此对象之前不进行null检查代码>,因此这里可能有一个null ptr,如果您在其他地方调用此数组而不进行检查,则可能会发生崩溃
- 我们并不知道data.elements的类型(我假设是数组),但可能会因为指针赋值而发生复制操作(如果指针转换为object,如果data.elements不是指针数组,或者存在一些运算符重载),这里可能会发生崩溃(但可能性不大)
- 子对象和父对象之间存在循环引用,因此在对象销毁期间可能会出现问题
other.children.getObjectPointerUnchecked(i)
在取消引用之前不会返回nullptr
?这是一个非常好的问题。但是假设(int I=0;Iadd
中的jassert
是否正在运行,表示data.elements==nullptr
?您是否可以发布SharedObject的其余代码,或者至少是默认构造函数(childen的初始化方式)和析构函数?另外,add函数(第二次更新)中可能存在问题,在将newObject分配给data.elements后,检查newObject是否为null。如果在某个地方有data.elements上的循环,那么其中可能有一些未经检查的null ptr。data.elements的类型是什么,不是在复制发生并崩溃的地方吗?谢谢-我会慢慢地看这些,确保没有遗漏什么。你知道为什么我们会得到EXC_断点而不是EXC_坏访问吗?或者为什么它会报告它违反了这个指令?0x127167a15:movl 0x40(%rbx),%eaxEXC\u断点似乎是一个特定的异常,用于帮助调试(如果已连接调试器)。您是否尝试附加调试器并查看此异常期间发生的情况?在重新阅读您的帖子之后,如果崩溃发生在复制构造函数上(而不是内部),您可能正在传递一个null ptr,并且取消对ptr(const&)的引用会产生崩溃。没有附加调试程序,这就是奇怪的原因。这是在客户机器上。如果我可以很容易地附加一个调试器,那么找出哪里出了问题就容易多了!这并不意味着如果附加了调试器,就会触发此操作,只是,如果附加了调试器,这将有助于调试。似乎触发此异常是因为您尝试使用null(但大多数post在Mac或iOS上都引用了nil),这就是为什么它很可能是某个地方的nullptr。对于nullptr类型的问题,我肯定会得到类似EXC_BAD_ACCESS的东西。EXC_断点表示CPU调试寄存器或INT3指令中存在断点位置?除非我错过了什么…约翰干杯-这是一个很好的角度。我明天会仔细检查一下,看看你有没有发现什么。我怀疑这些地址很接近,因为它们几乎是同时分配到堆上的。。。但是值得好好检查一下:)你明白了吗?如果没有,在崩溃点获取寄存器的二次读取可能会很有用。某些事情可以在运行时随机化,它们在运行时的更改方式可以告诉您是查看堆栈还是堆地址
/** Appends a new object to the end of the array.
This will increase the new object's reference count.
@param newObject the new object to add to the array
@see set, insert, addIfNotAlreadyThere, addSorted, addArray
*/
ObjectClass* add (ObjectClass* const newObject) noexcept
{
data.ensureAllocatedSize (numUsed + 1);
jassert (data.elements != nullptr);
data.elements [numUsed++] = newObject;
if (newObject != nullptr)
newObject->incReferenceCount();
return newObject;
}
this == rbx: 0x00007fe5bc37c950
&other == r12: 0x00007fe5bc348cc0
rax = 0
rcx = 0