Reputation: 14975
My program crashes with:
Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_PROTECTION_FAILURE at address: 0x00000000
When I use gdb's backtrace
I get:
#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 ()
It appears the function it is failing at is:
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;
}
But the logs show
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
Which seem to indicate that the function should pop off the stack and return true. I have more verbose logs if needed - I'm not really sure how to continue debugging this issue. I know that 0x00000000
is a null pointer dereference
, but it seems like a very non-obvious one. I ran into a similar error previously and compiling with -O3 seemed to hide it.. This happens with 32 and 64-bit, the code is compiled with Clang 5.0
.
Upvotes: 2
Views: 673
Reputation: 66234
You're not resetting the j
iterator on the erase action:
i->second.erase(j);
invalidates the j
iterator.
You need to do this:
j = i->second.erase(j);
and more importantly, skip the increment, which means move it to an else condition in the body of the loop. Something like this:
if (0 == (*it->second).counter())
{
// do your thing, then..
j = i->second.erase(j);
}
else
{
++j;
}
And lose the for-j-loop entirely in favor of a while-loop instead, since that's all it is without the increment-step. Looking closer at your code you have two levels of nesting before that incorrect erasure, so you may need two else-condtions, or none and a continue;
after the j = i->second.erase();
Upvotes: 4