Написать Windows Mini дампов с Python
Я пытался создать функцию, которая будет писать файл мини-дамп для данного идентификатора процесса. Пока у меня есть это:
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.
У кого-нибудь есть идеи, почему это происходит?
2 ответа
Единственные проблемы, с которыми я когда-либо сталкивался, - это дампы между архитектурами, то есть дамп 32-битных процессов, когда ваш локальный процесс является 64-битным процессом или наоборот. Если вы посмотрите по сети, то сможете найти множество ссылок на стандартную рекомендацию: взять 32-разрядный дамп из 32-разрядного процесса и 64-разрядный из 64-го. См. Не собирать дампы 32-разрядного процесса с помощью 64-разрядного диспетчера задач и захвата. дампы памяти для 32-битных процессов на компьютере x64, я не знаю почему, но я бы хотел. (хотя технически в 64-битных окнах все они являются 64-битными процессами, 32-битные просто лгут сами себе... с дополнительным стеком потоков и TEB и PEB.
Указатели исключений и текущий идентификатор потока имеют значение только при выгрузке из процесса. Если вы полностью прочитаете запись MSDN, она предложит создать вспомогательный поток и исключить его из дампа, чтобы получить значительный стек текущего потока, что, очевидно, имеет смысл только в том случае, если вы сбрасываете текущий процесс. Также дамп внешнего процесса, который иногда очень полезен при диагностике зависающих процессов, не будет содержать информацию PEXCEPTION_POINTER. Также я выполнил множество мини-дампов внешних процессов без установки PEXCEPTION_POINTER или обратного вызова, но обратный вызов очень полезен.
Вы скучаете по подготовленным MINIDUMP_EXCEPTION_INFORMATION
структура в качестве 5-го параметра MiniDumpWriteDump()
, Это необходимо для успешного сброса.
Установите его ThreadId
поле для GetCurrentThreadId()
, Установите его ClientPointers
поле в ЛОЖЬ. Настоящий трюк здесь ExceptionPointers
поле. Единственный способ, которым я знаю, получить PEXCEPTION_POINTERS
через обратный вызов, назначенный через AddVectoredExceptionHandler()
, Обратный звонок получает один раз PEXCEPTION_POINTERS
параметр. Итак, вам нужно переместить весь код дампа в этот обратный вызов, чтобы иметь доступ к PEXCEPTION_POINTERS
во время свалки. К сожалению, это также означает, что вы находитесь во власти необработанного исключения, запускающего дамп (если вы не можете найти другой способ получить PEXCEPTION_POINTERS
).