Program crashes with Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_PROTECTION_FAILURE at address: 0x00000000

StackOverflow https://stackoverflow.com/questions/21687853

  •  09-10-2022
  •  | 
  •  

Question

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.

Was it helpful?

Solution

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();

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top