Question

I've been trying to create a function that will write a minidump file for a given process ID. So far I have this:

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

The process and file handles are created successfully. However, the call to MiniDumpWriteDump sets the following error: Only part of a ReadProcessMemory or WriteProcessMemory request was completed.

Does anyone have any ideas of why this is happening?

Was it helpful?

Solution

The only issues I've ever encountered would be is cross architecture dumps ie dumping a 32 bit processes when your local process is a 64 bit process or vice versa. If you look around the net you can find plenty of references to the standard recomendation is to take a 32 bit dump from a 32 bit process and a 64 from a 64. see Do not collect 32bit process' dumps with 64 bit task manager and Capturing memory dumps for 32-bit processes on an x64 machine I don't know why, but I'd like to. (even though technically on x64 windows they all are 64 bit processes, the 32 bit ones are just lying to themselves.. with an extra thread stack and TEB and PEB.

The exception pointers and current Thread id are only relevant when you are dumping from within the process. If you read the MSDN entry completely it suggests creating a helper thread and excluding it from the dump to get the current thread stack meaningfully which obviously only has meaning if you are dumping the current process. Also dumping an external process which is very helpful sometimes in diagnosing hanging processes wouldn't have PEXCEPTION_POINTER information. Also I have done plenty of minidumps of external processes without PEXCEPTION_POINTER being set, or callback, but callback is very useful.

OTHER TIPS

You're missing a prepared MINIDUMP_EXCEPTION_INFORMATION structure as the 5th parameter to MiniDumpWriteDump(). It's necessary for a successful dump.

Set its ThreadId field to GetCurrentThreadId(). Set its ClientPointers field to FALSE. The real trick here is the ExceptionPointers field. The only way I know of getting a PEXCEPTION_POINTERS is via a callback assigned through AddVectoredExceptionHandler(). The callback gets passed a single PEXCEPTION_POINTERS parameter. So, you'll need to move all your dump code into that callback to have access to a PEXCEPTION_POINTERS at the time of the dump. Unfortunately, this also means that you're at the mercy of an unhandled exception triggering the dump (unless you can find another way to get a PEXCEPTION_POINTERS).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top