程序因程序接收信号EXC_BAD_ACCESS而崩溃,无法访问内存。原因:地址为0x00000000的KERN_PROTECTION_FAILURE

时间:2014-02-10 21:03:35

标签: c++ pthreads exc-bad-access

我的程序崩溃了:

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。如果需要,我有更详细的日志 - 我不确定如何继续调试此问题。我知道0x00000000null pointer dereference,但它似乎是非常不明显的。我之前遇到过类似的错误,并且使用-O3进行编译似乎隐藏了它。这种情况发生在32位和64位,代码是用Clang 5.0编译的。

1 个答案:

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