2010-11-04 23 views
5

我想使用MiniDumpWriteDump()API轉儲從另一個進程A.崩潰的進程B,我這樣做是因爲MSDN是這麼說的:有沒有辦法在另一個引發異常的進程中知道線程ID?

MiniDumpWriteDump應該叫 從一個單獨的進程,如果在所有 可能的,而不是從被傾銷的目標進程中獲取。

的MiniDumpWriteDump()被定義爲這樣的:

BOOL WINAPI MiniDumpWriteDump(
    __in HANDLE hProcess, 
    __in DWORD ProcessId, 
    __in HANDLE hFile, 
    __in MINIDUMP_TYPE DumpType, 
    __in PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, 
    __in PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, 
    __in PMINIDUMP_CALLBACK_INFORMATION CallbackParam 
); 

特別地,ExceptionParam是類型的PMINIDUMP_EXCEPTION_INFORMATION,其被定義爲如下:

typedef struct _MINIDUMP_EXCEPTION_INFORMATION { 
    DWORD    ThreadId; 
    PEXCEPTION_POINTERS ExceptionPointers; 
    BOOL    ClientPointers; 
} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION; 

現在我想知道如何準備以下2個參數:

線程ID 拋出異常的線程的標識符。

ExceptionPointers 一個指向EXCEPTION_POINTERS結構指明該異常的計算機獨立描述,並在異常時的處理器的上下文。

如何在進程A中運行時如何獲得進程B中的錯誤線程標識和異常指針?

謝謝。

+0

我正面臨類似的問題。我無法將PEXCEPTION_POINTERS ExceptionPointers傳遞給其他進程。 (如果我使用FileMapping概念,我最終得到空指針)。請詳細說明你如何解決這個問題。 – 2013-04-23 10:30:54

回答

0

要在特定進程名稱上給定的異常上創建自動轉儲,我的建議是使用DebugDiag或AdPlus。這些是可以配置的外部(和免費!)軟件。

如果你真的想自己寫轉儲,你可以在進程B中做:MSDN警告你,這不是一個好主意,因爲討厭的錯誤,如內存不足,堆棧溢出或堆棧損壞(列表是不完全)將肯定使用內存和堆棧,所以你可能最終沒有轉儲(和一個非常糟糕的進程崩潰)。根據我的經驗,這是非常罕見的(我曾經在一個非常強調的分佈式C++軟件上工作)。 對於其他例外,它應該沒問題。在這種情況下,您可以使用異常轉換器(請參閱_set_se_translator)或向量化異常處理程序(請參閱AddVectoredContinueHandler)或函數GetExceptionInformation()來獲取EXCEPTION_RECORD結構(可能有其他方法我不知道)。

在進程B中發生異常後,從進程A創建轉儲意味着您必須複製有關該異常的所有信息,並警告進程A必須轉儲具有此異常的內容。這會消耗內存和堆棧,所以你將會有和前面解釋的相同的限制。

希望,這將有助於

2

甲指向描述導致要產生的小型轉儲客戶端異常的MINIDUMP_EXCEPTION_INFORMATION結構。如果此參數的值爲NULL,則不會在小型轉儲文件中包含異常信息。

儘管該放慢參數標記__in而不是__in_opt你確實可以傳遞NULL在這裏。要從目標流程中首先獲取這些信息,您的流程將不得不進行調試。

過程A如何以及何時已知採用進程B的轉儲?如果A確實正在調試B,那麼當WaitForDebugEvent以EXCEPTION_DEBUG_EVENT返回時,信息在信息結構中可用。

如果A不調試B,那麼也許B通過一些IPC機制告訴A「嘿,我正在崩潰,需要一個小型轉儲器」。在這種情況下,B可以自己接受轉儲或通過相同的IPC機制將異常信息傳遞給A.同樣,這也是有問題的,因爲在崩潰過程中調用MiniDumpWriteDump存在問題,如果事情正在爆炸,可能已經炸燬的可能是你需要告訴A的事情。

另一種可能將A轉儲給B的機制是A作爲JIT調試器安裝,在這種情況下,A將調試B,並且可以使用調試API來獲取異常信息。

如果A只是週期性地使用B的小轉儲,那麼不一定會有任何異常,所以您可以在這種情況下傳遞NULL。

請注意,如果你在做一些打算像

WaitForSingleObject(handleToProcessB, INFINITE); 
MiniDumpWriteDump(handleToProcessB, ...) 

,這是行不通的。操作系統保留了很少的東西,主要是進程的退出代碼,而不是虛擬地址空間和你需要使用小型轉儲的堆棧。

相關問題