用Python编写windows小型转储

2024-09-27 04:28:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在尝试创建一个函数,该函数将为给定的进程ID写入一个小型转储文件。到目前为止,我有这样一个:

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.

有人知道为什么会这样吗?在


Tags: nonereadstatuspidfilehandleprintwin32api
2条回答

缺少一个准备好的MINIDUMP_EXCEPTION_INFORMATION结构作为MiniDumpWriteDump()的第五个参数。这是一个成功的倾倒的必要条件。在

将其ThreadId字段设置为GetCurrentThreadId()。将其ClientPointers字段设置为FALSE。这里真正的诀窍是ExceptionPointers字段。我所知道的获得PEXCEPTION_POINTERS的唯一方法是通过AddVectoredExceptionHandler()分配一个回调。回调通过一个PEXCEPTION_POINTERS参数。因此,您需要将所有转储代码移到该回调中,以便在转储时访问PEXCEPTION_POINTERS。不幸的是,这也意味着您将受到触发转储的未处理异常的摆布(除非您可以找到另一种方法来获得PEXCEPTION_POINTERS)。在

我遇到的唯一问题是跨体系结构转储,即当本地进程是64位进程时转储32位进程,反之亦然。如果你环顾网络,你会发现大量的参考标准建议是从32位进程中获取32位转储,从64位进程获取64位转储。参见Do not collect 32bit process' dumps with 64 bit task manager 和{a2} 我不知道为什么,但我愿意。(即使从技术上讲,在x64 windows上,它们都是64位进程,而32位进程只是在自欺欺人。。有一个额外的线程堆栈和TEB和PEB。在

异常指针和当前线程id只有在从进程内转储时才相关。 如果您完全读取MSDN条目,它建议您创建一个helper线程,并将其从转储中排除,以获得有意义的当前线程堆栈,这显然只有在您正在转储当前进程时才有意义。 另外,转储一个外部进程(有时在诊断挂起进程时非常有用)不会有peexception_指针信息。我还做了大量的外部进程的小转储,没有设置peexception_指针,也没有回调,但是回调非常有用。在

相关问题 更多 >

    热门问题