我有下面的「一次機會異常」消息,它來自我寫的一個DLL,它運行在我沒有寫入的可執行文件中。也就是說,DLL是一個插件。這個異常第一次觸發時,嘗試打開共享內存映射文件失敗。如果我忽略第一次機會異常並運行,應用程序最終會凍結或崩潰。如何調試或修復無盡循環和堆腐敗問題,涉及boost :: interprocess managed_shared_memory?
First-chance exception at 0x76a7c41f in notmyexe.exe: Microsoft C++ exception: boost::interprocess::interprocess_exception at memory location 0x002bc644..
幾個小時後,它似乎是由被不斷地循環,直到預期的異常條件清除的代碼塊引起的。事實證明,如果它永遠不會清除,那麼最終,這個異常會變成另一個低級異常條件和/或變成堆損壞。所有這些只是爲了使用Boost :: interprocess打開共享內存區域。
使事情複雜化的第一件事是,在我基於Visual C++ 2008的項目中,第一個機會異常不會被拋出並被識別爲它的來源,因爲Visual C++ 2008編譯器無法找到複雜的提升有問題的味道模板代碼。然而,通過單步執行彙編語言視圖,我發現了代碼爆炸。
的我自己的代碼的頂層線,這一切都開始走壞的是:
segment = new managed_shared_memory( open_or_create
, MEMORY_AREA_NAME
, SHARED_AREA_SIZE);
以上managed_shared_memory
類是interprocess_fwd.hpp,並且大於助推共享內存API標準的一部分/頭。因爲它是基於模板的,所以上面擴展爲大約2Kchars長的C++ boost模板表達式,它由鏈接器和調試器以不同的長度截斷。 Visual C++ 2008沒有更多的源代碼調試功能,看起來這些限制在起作用。
例如,當它炸燬我得到這個調用堆棧:
KernelBase.dll!76a7c41f()
[Frames below may be incorrect and/or missing, no symbols loaded for KernelBase.dll]
KernelBase.dll!76a7c41f()
> msvcr90d.dll!_malloc_dbg(unsigned int nSize=2290875461, int nBlockUse=264, const char * szFileName=0x01fcb983, int nLine=1962999808) Line 160 + 0x1b bytes C++
8bfc4d89()
沒有實際最終用戶編寫的源功能出現在堆棧轉儲以上。
我應該如何調試?其次,在Visual C++ 2008中,是否存在boost-interprocess的一些已知問題?第三,下面的boost代碼是什麼,爲什麼它必須無止境地循環?
boost::interprocess::basic_managed_shared_memory<char,
boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family,
boost::interprocess::offset_ptr<void,int,unsigned int,0>,0>,
boost::interprocess::iset_index>::basic_managed_shared_memory<char,boo...
而且層下來,我們得到:
basic_managed_shared_memory (open_or_create_t,
const char *name, size_type size,
const void *addr = 0, const permissions& perm = permissions())
: base_t()
, base2_t(open_or_create, name, size, read_write, addr,
create_open_func_t(get_this_pointer(),
ipcdetail::DoOpenOrCreate), perm)
{}
不管怎麼說,不要試圖在家裏的孩子調試此,這裏是發生了什麼:
最後,使用我的忍者式功能單步執行數百萬行彙編語言我已經擊敗了Visual C++ 2008的惡意調試器限制,並且已經找到了代碼estion。
這是事實上吹起來的東西:create_device<FileBased>(dev...
。
一些背景這裏: managed_open_or_create_impl.h線351 ...
else if(type == DoOpenOrCreate){
//This loop is very ugly, but brute force is sometimes better
//than diplomacy. If someone knows how to open or create a
//file and know if we have really created it or just open it
//drop me a e-mail!
bool completed = false;
while(!completed){
try{
create_device<FileBased>(dev, id, size, perm, file_like_t()); // <-- KABOOM!
created = true;
completed = true;
}
catch(interprocess_exception &ex){
if(ex.get_error_code() != already_exists_error){
throw;
}
else{
try{
DeviceAbstraction tmp(open_only, id, read_write);
dev.swap(tmp);
created = false;
completed = true;
}
catch(interprocess_exception &e){
if(e.get_error_code() != not_found_error){
throw;
}
}
catch(...){
throw;
}
}
}
catch(...){
throw;
}
thread_yield();
}
}
+1爲寫意的脾氣暴躁的臉。 –
這裏有很多東西需要吸收,但是你有沒有考慮過First-Chance異常可能完全沒有問題的可能性? –
我做了一些編輯並刪除了這個問題中的一些非常不專業的東西。我爲任何必須閱讀原始版本的人道歉。 –