2011-12-09 31 views
2

我一直在試圖創建一個函數來爲給定的進程ID寫一個minidump文件。到目前爲止,我有這個:使用Python編寫windows迷你轉儲文件

import win32con, win32api, win32file, ctypes 
dbghelp = ctypes.windll.dbghelp 

def createMiniDump(pid, file_name): 
    # Adjust privileges. 
    adjustPrivilege(win32security.SE_DEBUG_NAME) 
    pHandle = win32api.OpenProcess(
       win32con.PROCESS_QUERY_INFORMATION | win32con.PROCESS_VM_READ , 
       0, pid) 
    print 'pHandle Status: ', win32api.FormatMessage(win32api.GetLastError()) 
    fHandle = win32file.CreateFile(file_name, 
           win32file.GENERIC_READ | win32file.GENERIC_WRITE, 
           win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE, 
           None, 
           win32file.CREATE_ALWAYS, 
           win32file.FILE_ATTRIBUTE_NORMAL, 
           None) 

    print 'fHandle Status: ', win32api.FormatMessage(win32api.GetLastError()) 
    success = dbghelp.MiniDumpWriteDump(pHandle.handle, # Process handle 
            pid,     # Process ID 
            fHandle.handle,  # File handle 
            0,   # Dump type - MiniDumpNormal 
            None,  # Exception parameter 
            None,  # User stream parameter 
            None,  # Callback parameter 
            ) 
    print 'MiniDump Status: ', win32api.FormatMessage(win32api.GetLastError()) 
    return success 

進程和文件句柄已成功創建。但是,對MiniDumpWriteDump的調用設置以下錯誤: Only part of a ReadProcessMemory or WriteProcessMemory request was completed.

有沒有人有任何想法,爲什麼會發生這種情況?

+0

'dump_type'的值是什麼?我認爲這是外部設置的功能? – icabod

+0

dump_type的值爲0(MiniDumpNormal)。對不起,我的錯誤複製和粘貼。修正了這個問題。 –

+0

我過去成功地創建了一個轉儲文件,該文件沒有通過使用不同的工具引發異常。 –

回答

2

我遇到的唯一問題是跨架構轉儲,即當您的本地進程是64位進程或反之亦然轉儲32位進程。如果你環顧網絡,你可以找到大量的參考標準推薦是從一個32位進程的32位轉儲和一個64位的64.請參閱Do not collect 32bit process' dumps with 64 bit task managerCapturing memory dumps for 32-bit processes on an x64 machine 我不知道爲什麼,但我' d喜歡。 (即使在技術上在x64上的窗戶都 64位的過程中,32位的有隻是躺在自己..一個額外的線程堆棧和TEB和PEB。

異常指針和當前線程ID只如果你完全閱讀MSDN條目,它建議創建一個幫助線程並將其從轉儲中排除,以便有意義地獲得當前線程堆棧,這顯然只有在你傾銷當前進程時纔有意義。 也傾銷一個非常有用的外部過程,有時在診斷掛起過程中不會有PEXCEPTION_POINTER信息。我也做了大量外部過程的小型轉儲沒有設置PEXCEPTION_POINTER或回調,但回調非常有用。

+0

代碼一直工作!只要調用進程的體系結構與目標進程匹配,它就開始工作。謝謝你的回答! –

0

您錯過了準備好的MINIDUMP_EXCEPTION_INFORMATION結構作爲MiniDumpWriteDump()的第5個參數。這是成功轉儲的必要條件。

將其ThreadId字段設置爲GetCurrentThreadId()。將其ClientPointers字段設置爲FALSE。這裏真正的技巧是ExceptionPointers字段。我知道獲得PEXCEPTION_POINTERS的唯一方法是通過AddVectoredExceptionHandler()指定的回調。回調獲得一個參數PEXCEPTION_POINTERS。因此,您需要將所有轉儲代碼移動到該回調中,以便在轉儲時訪問PEXCEPTION_POINTERS。不幸的是,這也意味着你處於觸發轉儲的未處理異常的擺佈之下(除非你能找到另一種方式獲得PEXCEPTION_POINTERS)。

+0

這很有道理。但是,不應將ClientPointers設置爲True,因爲所收集的轉儲與調用過程處於不同的進程空間中?另外,我並不在乎在發生異常時創建轉儲。我的想法是按需創建轉儲文件,即使目標進程沒有例外情況。 –

+0

對不起,我不認爲有可能在不觸發異常的情況下生成完整的小型轉儲文件。請參閱關於[MiniDumpWriteDump](http://msdn.microsoft.com/en-us/library/windows/desktop/ms680360(v = vs.85).aspx)的備註的第3段。 – kipkennedy

+0

我過去成功地創建了一個轉儲文件,這個文件沒有通過使用不同的工具引發異常。 –