我的程序崩溃了:
Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_PROTECTION_FAILURE at address: 0x00000000
当我使用gdb's backtrace
时,我得到:
#0 0x0000e5f3 in std::__1::__tree_is_left_child<std::__1::__tree_node_base<void*>*> () at
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/c++/v1/__tree:67
#1 0x0000e5f3 in application_manager::ApplicationManagerImpl::DecreaseMessageChain (this=<value temporarily unavailable, due to optimizations>) at __tree:158
#2 0x0002f942 in application_manager::commands::CommandResponseImpl::IsPendingResponseExist (this=<value temporarily unavailable, due to optimizations>) at src/components/application_manager/src/commands/command_response_impl.cc:100
#3 0x0005c638 in application_manager::commands::ShowResponse::Run (this=0xa4d450) at src/components/application_manager/src/commands/mobile/show_response.cc:62
#4 0x0000b762 in utils::SharedPtr<application_manager::commands::Command>::operator-> () at src/components/utils/include/utils/shared_ptr.h:1138
#5 0x0000b762 in application_manager::ApplicationManagerImpl::ManageMobileCommand (this=<value temporarily unavailable, due to optimizations>, message=<value temporarily unavailable, due to optimizations>) at src/components/application_manager/src/application_manager_impl.cc:158
#6 0x0006580c in application_manager::commands::ResponseFromHMI::SendResponseToMobile (this=0xa4c9d0, message=@0xa4c9d4) at src/components/application_manager/src/commands/hmi/response_from_hmi.cc:67
#7 0x00073f2f in application_manager::commands::UIShowResponse::Run (this=0xa4c9d0) at src/components/application_manager/src/commands/hmi/ui_show_response.cc:52
#8 0x0000d3ba in utils::SharedPtr<application_manager::commands::Command>::operator-> () at src/components/utils/include/utils/shared_ptr.h:1202
#9 0x0000d3ba in application_manager::ApplicationManagerImpl::ManageHMICommand (this=0xb041ee20, message=<value temporarily unavailable, due to optimizations>) at src/components/application_manager/src/application_manager_impl.cc:158
#10 0x0001594c in application_manager::ApplicationManagerImpl::ProcessMessageFromHMI (this=<value temporarily unavailable, due to optimizations>, message=<value temporarily unavailable, due to optimizations>) at src/components/application_manager/src/application_manager_impl.cc:1412
#11 0x0002938f in utils::SharedPtr<application_manager::Message>::dropReference () at src/components/application_manager/src/from_hmh_thread_impl.cc:62
#12 0x0002938f in utils::SharedPtr<application_manager::Message>::~SharedPtr () at src/components/application_manager/src/from_hmh_thread_impl.cc:220
#13 0x0002938f in utils::SharedPtr<application_manager::Message>::~SharedPtr () at src/components/utils/include/utils/shared_ptr.h:219
#14 0x0002938f in application_manager::FromHMHThreadImpl::threadMain (this=0xa4d2f0) at src/components/application_manager/src/from_hmh_thread_impl.cc:158
#15 0x00341971 in (anonymous namespace)::threadFunc (closure=0xa4d2f0) at src/components/utils/src/threads/posix_thread.cc:44
#16 0x955cf5fb in _pthread_body ()
#17 0x955cf485 in _pthread_start ()
#18 0x955d4cf2 in thread_start ()
它失败的功能似乎是:
bool ApplicationManagerImpl::DecreaseMessageChain(
const unsigned int& hmi_correlation_id,
unsigned int& mobile_correlation_id) {
LOG4CXX_TRACE_ENTER(logger_);
bool result = false;
MessageChain::iterator i = message_chaining_.begin();
for (; message_chaining_.end() != i; ++i) {
MobileRequest::iterator j = i->second.begin();
for (; i->second.end() != j; ++j) {
HMIRequest::iterator it = j->second.find(hmi_correlation_id);
if (j->second.end() != it) {
(*it->second).DecrementCounter();
LOG4CXX_INFO(
logger_,
"ApplicationManagerImpl::DecreaseMessageChain "
"mobile request id " << (*it->second).correlation_id()
<< " is waiting for " << (*it->second).counter()
<< " responses");
if (0 == (*it->second).counter()) {
mobile_correlation_id = (*it->second).correlation_id();
LOG4CXX_INFO(
logger_,
"HMI response id " << hmi_correlation_id
<< " is the final for mobile request id "
<< mobile_correlation_id);
j->second.clear();
LOG4CXX_INFO(logger_, "value cleared");
i->second.erase(j);
LOG4CXX_INFO(logger_, "value cleared");
result = true;
}
}
}
}
return result;
}
但是日志显示
TRACE [10 Feb 2014 15:41:16,985][ApplicationManager] ENTER: bool application_manager::ApplicationManagerImpl::DecreaseMessageChain(const unsigned int &, unsigned int &)
INFO [10 Feb 2014 15:41:16,985][ApplicationManager] ApplicationManagerImpl::DecreaseMessageChain mobile request id 2 is waiting for 0 responses
INFO [10 Feb 2014 15:41:16,985][ApplicationManager] HMI response id 19 is the final for mobile request id 2
INFO [10 Feb 2014 15:41:16,986][ApplicationManager] value cleared
INFO [10 Feb 2014 15:41:16,986][ApplicationManager] value erased
这似乎表明该函数应弹出堆栈并返回true。如果需要,我有更详细的日志 - 我不确定如何继续调试此问题。我知道0x00000000
是null pointer dereference
,但它似乎是非常不明显的。我之前遇到过类似的错误,并且使用-O3进行编译似乎隐藏了它。这种情况发生在32位和64位,代码是用Clang 5.0
编译的。
答案 0 :(得分:4)
您没有在擦除操作上重置j
迭代器:
i->second.erase(j);
使j
迭代器无效。
你需要这样做:
j = i->second.erase(j);
更重要的是,跳过增量,这意味着将其移动到循环体中的else条件。像这样:
if (0 == (*it->second).counter())
{
// do your thing, then..
j = i->second.erase(j);
}
else
{
++j;
}
完全失去for-j-loop而转而使用while循环,因为没有增量步骤就是这样。仔细查看代码,在错误擦除之前有两级嵌套,因此在continue;
j = i->second.erase();