2013-04-22 67 views
2

我想做一個進程外的異常處理程序,我創建了一個看門狗進程,它在子進程引發異常時執行專門的異常處理。我通過事件成功地調用了看門狗進程。我面臨的問題是在嘗試將異常信息指針傳遞給其他進程時。麻煩通過_EXCEPTION_POINTERS *使用FileMapping

我在這裏登陸Passing a pointer to process spawned with exec()來到知道,傳遞指針在共享內存有這個問題:

「如果您使用的共享內存,你不能傳遞指針的指針將包含虛擬地址,如果你不使用共享內存,你不能交換任何類型的指針:其他的指針不同於其他指針,如果你不使用共享內存,你不能交換任何類型的指針:其他進程將無法訪問您的進程的內存。「

現在我該如何克服這一點?

方法1:

struct mytest 
    { 
     _EXCEPTION_POINTERS * except ; 
     DWORD ThreadId ; 
     DWORD ProcessId ; 
    } 

    OpenFileMapping () ; 

    void * pBuf = MapViewOfFile () ; 

    mytest passdata ; 

    CopyMemory (pBuf , &passdata , sizeof (passdata)) ; 

    UnMapView () ; 

    CloseHandle () ; 

(對於離)方法2:

cout << passdata->except->ExceptionRecord->ExceptionCode << endl ; 

會崩潰。我明白這是因爲虛擬地址是特定於進程的。但在這種情況下如何將異常信息傳遞給不同的進程並寫入一個小型轉儲器?

P.S:我甚至嘗試過單獨傳遞PEXCEPTION_RECORD結構,但不起作用。

回答

1

對,你不能取消引用另一個進程中的指針,它只在崩潰的進程中有效。它只傳遞給MiniDumpWriteDump(),MINIDUMP_EXCEPTION_INFORMATION.ExceptionPointers字段。從技術上講,你可以使用ReadProcessMemory(),但這樣做對於崩潰的進程是不必要的風險。簡單的解決方案是在存儲異常代碼並由異常過濾器編寫的結構中添加一個額外的字段。

mytest passdata ; 
passdata.except = ExceptionInfo; 
// Note: added field 
passdata.ExceptionCode = ExceptionInfo->ExceptionRecord->ExceptionCode; 
passdata.ThreadId = GetCurrentThreadId(); 
// etc.. 

而且避免調用WINAPI功能,如OpenFileMapping和MapViewOfFile,實在是太冒險了。當程序因進程堆堆損壞而崩潰時,它們往往會陷入僵局。崩潰和死鎖的常見原因是因爲堆鎖仍然存在。只需在程序初始化時執行此操作您不需要麻煩清理任何事情,當您的看門狗進程在採取小型轉儲後終止崩潰的進程時,Windows會照顧它。

+0

Thans @Hans Passant!我只有一個澄清。你有沒有嘗試傳遞MINIDUMP_EXCEPTION_INFORMATION.ExceptionPointers字段。它會在子進程中可讀嗎? – 2013-04-22 14:45:32

+0

是的,這就是爲什麼該領域在那裏。不,它在「客戶端進程」中不可讀。或者我解釋過的監督程序。它由MiniDumpWriteDump使用並記錄在小型轉儲文件中。因此,當您在調試器中打開小型轉儲程序時,它可以向您顯示發生異常的位置。調試器在使用指針時沒有問題,因爲它正在調試擁有指針的進程。 – 2013-04-22 14:50:33

+0

然後,如何以及如何在看門狗中調用MiniDumpWriteDump所需的步驟? – 2013-04-22 14:56:48

3

我會把這個一起作爲一個答案,但它確實應該是Hans's answer(有評論)評論,但似乎一些解釋是必要的:

張貼在討論的代碼正確地傳遞值(s)的struct mytest結構分成共享內存。

第二代碼片斷:

(對於離)方法2:

cout << passdata->except->ExceptionRecord->ExceptionCode << endl ; 

示出了誤解雖然:雖然可以讀取指針passdata.except的值,在處理2中這只是一個任意的32/64位值,它不是一個有效的指針。

可以傳遞給MiniDumpWriteDump,這個函數將在目標進程(proc1)的上下文中平衡這個指針值。但是你在不能在進程#2中對其進行解引用。

Hans的例子給出瞭解決方案,如果在進程#2中需要ExeptionCode的值,則需要對proc#1中的指針取消引用,並將該值寫入您寫入共享內存的數據中。

+0

很酷,謝謝@馬丁巴。將按照您的指導繼續操作。 – 2013-04-23 15:16:53

+0

終於完成了它。如果未來有人遇到無法寫入MiniDump的問題請檢查您的進程安全訪問權限。 – 2013-04-25 04:41:48