我正在尝试使用MiniDumpWriteDump()API从另一个进程A转储崩溃的进程B.我这样做是因为MSDN这样说:
应该调用MiniDumpWriteDump 如果有的话,从一个单独的过程 可能,而不是从内部 目标进程被抛弃。
MiniDumpWriteDump()定义如下:
BOOL WINAPI MiniDumpWriteDump(
__in HANDLE hProcess,
__in DWORD ProcessId,
__in HANDLE hFile,
__in MINIDUMP_TYPE DumpType,
__in PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
__in PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
__in PMINIDUMP_CALLBACK_INFORMATION CallbackParam
);
特别是,ExceptionParam的类型为 PMINIDUMP_EXCEPTION_INFORMATION ,其定义如下:
typedef struct _MINIDUMP_EXCEPTION_INFORMATION {
DWORD ThreadId;
PEXCEPTION_POINTERS ExceptionPointers;
BOOL ClientPointers;
} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION;
现在我想知道如何准备以下两个参数:
的ThreadId 抛出异常的线程的标识符。
ExceptionPointers 指向EXCEPTION_POINTERS结构的指针,指定异常时与异常和处理器上下文无关的计算机描述。
在进程A中运行时,如何在进程B中获取错误的线程id和异常指针?
感谢。
答案 0 :(得分:2)
指向MINIDUMP_EXCEPTION_INFORMATION结构的指针,该结构描述导致生成minidump的客户端异常。如果此参数的值为NULL,则minidump文件中不包含任何异常信息。
尽管参数标记为__in
而不是__in_opt
,但您确实可以在此处传递NULL。要从目标流程首先获取该信息,您的流程无论如何都必须进行调试。
过程A如何以及何时采取过程B的小型转储?如果A确实在调试B,当WaitForDebugEvent返回EXCEPTION_DEBUG_EVENT时,信息在信息结构中可用。
如果A没有调试B,那么也许B通过一些IPC机制告诉A“嘿我正在崩溃,拿一个小型转储”。在这种情况下,B可以自己获取转储或通过相同的IPC mechansim将异常信息传递给A.再次,这是有问题的,因为在崩溃过程中调用MiniDumpWriteDump是有问题的,如果事情正在爆炸,那么事情可能已经爆炸的可能是你需要告诉A的事情。
可能有A对B进行转储的另一种机制是A安装为JIT调试器,在这种情况下,A将调试B,您可以使用调试API来获取异常信息。
如果A只是定期获取B的小型转储,那么就不一定会有任何异常,所以在这种情况下你只能传递NULL。
请注意,如果您打算执行类似
的操作WaitForSingleObject(handleToProcessB, INFINITE);
MiniDumpWriteDump(handleToProcessB, ...)
这不起作用。操作系统保留了很少的东西,主要是进程的退出代码,而不是虚拟地址空间和你需要使用minidump的堆栈。
答案 1 :(得分:0)
要在特定进程名称的给定异常上创建自动转储,我的建议是使用DebugDiag或AdPlus。这些是您可以配置的外部(和免费!)软件。
如果您真的想自己编写转储,可以在进程B中执行:MSDN警告您这不是一个好主意,因为内存不足,堆栈溢出或堆栈损坏等令人讨厌的错误(列表不是详尽的)肯定会使用内存和堆栈,所以你可能最终没有转储(并且一个非常糟糕的进程崩溃)。根据我的经验,这是非常罕见的(我曾经在一个非常紧张的分布式C ++软件上工作)。 对于其他例外,应该没问题。在这种情况下,您可以使用异常转换器(请参阅_set_se_translator)或向量异常处理程序(请参阅AddVectoredContinueHandler)或函数GetExceptionInformation()来获取EXCEPTION_RECORD结构(可能还有其他方法我不知道)。 / p>
在进程B中的异常之后从进程A创建转储意味着您必须复制有关该异常的所有信息,并警告进程A它必须转储具有此异常的内容。这将消耗内存和堆栈,因此您将具有与之前解释相同的限制。
希望有所帮助