exc_breakpoint崩溃的原因
Cause of EXC_BREAKPOINT crash
我在逻辑X中运行的C 录音组件中的某些用户计算机上发生了崩溃。不幸的是,我无法在本地重复,并且在尝试解决如何解决的过程中可能发生了一些问题。
这是崩溃转储的相关信息:
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_breakpoint的原因。来自Apple的信息是完整而准确的:"类似于异常出口,此例外旨在使附件的调试器有机会在执行的特定点中断过程。您可以从您自己身上触发此例外使用__builtin_trap((函数的代码。如果没有附加调试器,则终止该过程并生成崩溃报告。"
- 为什么会发生在共享对象 200上(请参阅拆卸(
- 是rbx当崩溃发生的那一刻。
崩溃发生在这里:
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);
}
}
拆卸:
-> 0x127167950 <+0>: pushq %rbp
0x127167951 <+1>: movq %rsp, %rbp
0x127167954 <+4>: pushq %r15
0x127167956 <+6>: pushq %r14
0x127167958 <+8>: pushq %r13
0x12716795a <+10>: pushq %r12
0x12716795c <+12>: pushq %rbx
0x12716795d <+13>: subq $0x18, %rsp
0x127167961 <+17>: movq %rsi, %r12
0x127167964 <+20>: movq %rdi, %rbx
0x127167967 <+23>: leaq 0x589692(%rip), %rax ; vtable for juce::ReferenceCountedObject + 16
0x12716796e <+30>: movq %rax, (%rbx)
0x127167971 <+33>: movl $0x0, 0x8(%rbx)
0x127167978 <+40>: leaq 0x599fe9(%rip), %rax ; vtable for juce::ValueTree::SharedObject + 16
0x12716797f <+47>: movq %rax, (%rbx)
0x127167982 <+50>: leaq 0x10(%rbx), %rdi
0x127167986 <+54>: movq %rdi, -0x30(%rbp)
0x12716798a <+58>: leaq 0x10(%r12), %rsi
0x12716798f <+63>: callq 0x12711cf70 ; juce::Identifier::Identifier(juce::Identifier const&)
0x127167994 <+68>: leaq 0x18(%rbx), %rdi
0x127167998 <+72>: movq %rdi, -0x38(%rbp)
0x12716799c <+76>: leaq 0x18(%r12), %rsi
0x1271679a1 <+81>: callq 0x12711c7b0 ; juce::NamedValueSet::NamedValueSet(juce::NamedValueSet const&)
0x1271679a6 <+86>: movq $0x0, 0x30(%rbx)
0x1271679ae <+94>: movl $0x0, 0x38(%rbx)
0x1271679b5 <+101>: movl $0x0, 0x40(%rbx)
0x1271679bc <+108>: movq $0x0, 0x48(%rbx)
0x1271679c4 <+116>: movl $0x0, 0x50(%rbx)
0x1271679cb <+123>: movl $0x0, 0x58(%rbx)
0x1271679d2 <+130>: movq $0x0, 0x60(%rbx)
0x1271679da <+138>: cmpl $0x0, 0x40(%r12)
0x1271679e0 <+144>: jle 0x127167aa2 ; <+338>
0x1271679e6 <+150>: xorl %r14d, %r14d
0x1271679e9 <+153>: nopl (%rax)
0x1271679f0 <+160>: movl $0x68, %edi
0x1271679f5 <+165>: callq 0x12728c232 ; symbol stub for: operator new(unsigned long)
0x1271679fa <+170>: movq %rax, %r13
0x1271679fd <+173>: movq 0x30(%r12), %rax
0x127167a02 <+178>: movq (%rax,%r14,8), %rsi
0x127167a06 <+182>: movq %r13, %rdi
0x127167a09 <+185>: callq 0x127167950 ; <+0>
0x127167a0e <+190>: movq %rbx, 0x60(%r13) // MY NOTES: child->parent = this
0x127167a12 <+194>: movl 0x38(%rbx), %ecx
0x127167a15 <+197>: movl 0x40(%rbx), %eax
0x127167a18 <+200>: cmpl %eax, %ecx
更新1:看来RIP暗示我们处于"添加"调用的中间,这是此功能,分别为:
/** 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;
}
更新2:在相关寄存器的崩溃寄存器值时:
this == rbx: 0x00007fe5bc37c950
&other == r12: 0x00007fe5bc348cc0
rax = 0
rcx = 0
我怀疑问题在于,应该在堆栈上无意中分配了一个应该放置在堆上的共享的,朗格计数的对象。如果堆栈随后放松并被覆盖,并且对ref计数对象的引用仍然存在,那么随机的事情将在访问该引用的情况下发生不可预测的时间发生。(在地址空间的接近和其他方面的距离也使我怀疑两者都在堆上。(
此代码中可能有一些问题:
- 就像SM所提到的,其他.Children.GetObjectPoTewercecked(i(可以返回nullptr
- 在
ObjectClass* add (ObjectClass* const newObject) noexcept
中,您在调用incReferenceCount
之前检查了newObject是否没有null(这意味着在此方法调用中可能发生null(,但是在data.elements [numUsed++] = newObject;
期间添加此对象之前,您不会取消检查,因此您可能有一个nullptr在这里,如果您在没有检查的地方将此数组拨打在其他地方,则可能会崩溃。 - 我们真的不知道数据的类型(我假设一个数组(,但是由于指针分配,可能会发生副本操作(如果指针转换为对象,如果数据。一个指针或有一些操作员过载(,这里可能发生崩溃(但不可能(
- 儿童与父母之间有一个循环裁判,因此在物体破坏过程中可能存在问题
相关文章:
- 当回溯以零开始时,如何调试崩溃
- 内联映射初始化的动态atexit析构函数崩溃
- 执行函数时导致崩溃的变量
- 程序崩溃并显示"std::out_of_range"错误
- CoInitialize()在单独的线程上崩溃而不返回
- 使用调试/崩溃报告将应用程序部署到客户端
- 为什么所有C++编译器都会崩溃或挂起此代码
- 为什么lambda在clang上崩溃而不是在gcc上崩溃
- 为什么我的多线程作业队列崩溃
- ExtractIconEx:可以工作,但偶尔会崩溃
- 为什么引用传递会导致此崩溃(C++)
- 试图创建流或fopen时程序崩溃
- 类对象数组的问题会导致崩溃
- 排序时无法执行交换操作.我做的时候它会崩溃.为什么
- 为什么要增加导致崩溃的指针
- 在虚幻引擎中删除NXOpen对象时崩溃
- 为什么它只打印双链接列表的第一个值,而我的程序却崩溃了
- 应用程序崩溃并显示"symbol _ZdlPvm, version Qt_5 not defined in file libQt5Core.so.5 with link time reference"
- Visual Studio在尝试读取resource.txt文件时崩溃
- 将方法转换为调用该方法的成员函子对象会导致崩溃