2014-04-11 591 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