2014-04-11 332 views
1

我有以下的代码,随机崩溃我的应用程序,未处理的异常异常

for(map<_type, boost::shared_ptr<CRowHeaderEx<_type> > >::iterator itr = m_RowMap.begin(); itr != m_RowMap.end(); ++itr) 
{ 
    boost::shared_ptr<CRowHeaderEx<_type> > pRow = itr->second; 
    time_t previoustime = pRow->get_DataReceived(); 
    if(currenttime - previoustime > Threshold) 
    { 
     listofdeletedkey.push_back(itr->first); 
    } 
} 

坠机发生在结束对在shared_ptr的析构函数中循环。而这个崩溃是随机的,不容易重现。

异常: 未处理的异常在0x00000752 in memory.hdmp:0xC0000005:访问冲突读取位置0x00000752。

堆栈跟踪:

xxx.exe!boost::detail::sp_counted_base::release() Line 103 C++ 
xxx.exe!boost::detail::shared_count::~shared_count() Line 309 C++ 
xxx.exe!boost::shared_ptr<CRowHeaderEx<int> >::~shared_ptr<CRowHeaderEx<int> >() C++ 
xxx.exe!CRowManagerEx<int>::PurgeRecords(int Threshold) Line 385 C++ 

而崩溃时的Dispose()函数获取调用中的boost ::详细:: sp_counted_base ::释放()。

void release() // nothrow 
{ 
    if(BOOST_INTERLOCKED_DECREMENT(&use_count_) == 0) 
    { 
     dispose(); 
     weak_release(); 
    } 
} 

拆解:

 { 
      dispose(); 
00412B57 mov   edx,dword ptr [this] 
00412B5A mov   eax,dword ptr [edx] 
00412B5C mov   ecx,dword ptr [this] 
00412B5F mov   edx,dword ptr [eax+4] 
00412B62 call  edx 

EDX值这里0x00000752。这是导致访问冲突。

回答

0

而且这个崩溃是随机的,不容易重现。

您的程序正在经历某种形式的内存损坏。我相信我以前的文章对于如何在Windows平台上使用WinDBG/Pageheap来识别内存损坏很有用。

https://stackoverflow.com/a/22074401/2724703

EDX值这里0x00000752。这是导致访问冲突。

这表明您正试图访问空指针内存(偏移量为+ 1874/0x752字节)。这可能有几个原因,并且不可能通过查看当前的信息来了解所有信息。其中一个原因可能是您的程序是多线程的,而其他某个线程正试图与此线程同时释放此共享内存。

编辑

以下信息可以从boost文档中找到。

shared_ptr对象提供与内置的 类型相同的线程安全级别。一个shared_ptr实例可以被多个线程同时“读取”(仅使用const 操作访问)。不同的shared_ptr 实例可以被“写入” simultaneosly由多个线程(使用可变操作,例如 如操作者访问=或复位)(即使当 这些实例是副本,并共享下方相同的参考计数 。)

任何其他同时访问都会导致未定义的行为

+0

感谢您的回复。该应用程序是多线程的。但是对m_RowMap的所有访问都受到关键部分的保护。抛出异常的代码在smart ptr析构函数中。底层对象通过shared_ptr访问,绝不会直接在代码中的任何地方访问。不应该shared_ptr维护引用计数,并且只有在没有代码引用时才删除对象? – Krishna

+0

@Krishna:我已经更新了关于shared_ptr线程安全性的帖子。你已经提到所有访问m_RowMap变量都受CS保护。但是从析构函数中抛出异常表明在你的程序中发生了一些严重的事情。好吧,我仍然觉得由于程序的多线程特性,会出现某种内存损坏情况。如上所述,动态工具在这些情况下会很有用。那么我没有什么可以添加在我的这篇文章上。 –

+0

我同意这是某种堆腐败。它与提升无关。我查看了存储在特定范围的内存中的行映射条目和对象具有损坏的值。现在最难的部分是找出哪部分代码正在破坏堆。感谢您的帮助。 – Krishna