我一直在尝试创建一个函数来为给定的进程 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 会设置以下错误:
只完成了 ReadProcessMemory 或 WriteProcessMemory 请求的一部分。
有人知道为什么会这样吗?
最佳答案
我遇到的唯一问题是跨架构转储,即当您的本地进程是 64 位进程时转储 32 位进程,反之亦然。如果您环顾网络,您会发现很多关于标准建议的引用资料是从 32 位进程中获取 32 位转储,从 64 位进程中获取 64 位转储。参见 Do not collect 32bit process' dumps with 64 bit task manager 和 Capturing memory dumps for 32-bit processes on an x64 machine 我不知道为什么,但我愿意。 (尽管从技术上讲,在 x64 windows 上它们都是 64 位进程,但 32 位进程只是在自欺欺人......有一个额外的线程堆栈和 TEB 和 PEB。
异常指针和当前线程 ID 仅在您从进程内转储时才相关。 如果您完整阅读了 MSDN 条目,它建议创建一个辅助线程并将其从转储中排除,以有意义地获取当前线程堆栈,这显然只有在转储当前进程时才有意义。 同时转储有时对诊断挂起进程非常有帮助的外部进程不会有 PEXCEPTION_POINTER 信息。此外,我还完成了 大量 外部进程的小型转储,但没有设置 PEXCEPTION_POINTER 或回调,但回调非常有用。
关于python - 用 Python 编写 Windows 迷你转储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8452382/