开发者

Is there a way to know the thread id in another process which throws an exception?

开发者 https://www.devze.com 2023-01-24 00:00 出处:网络
I am trying to use MiniDumpWriteDump() API to dump a crashed process B from another process A. I am doing this because MSDN said so:

I am trying to use MiniDumpWriteDump() API to dump a crashed process B from another process A. I am doing this because MSDN said so:

MiniDumpWriteDump should be called from a separate process if at all possible, rather than from within the target process being dum开发者_StackOverflowped.

The MiniDumpWriteDump() is defined as this:

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
);

Especially, the ExceptionParam is of type PMINIDUMP_EXCEPTION_INFORMATION, which is defined as below:

typedef struct _MINIDUMP_EXCEPTION_INFORMATION {
  DWORD               ThreadId;
  PEXCEPTION_POINTERS ExceptionPointers;
  BOOL                ClientPointers;
} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION;

Now I am wondering how to prepare the following 2 parameters:

ThreadId The identifier of the thread throwing the exception.

ExceptionPointers A pointer to an EXCEPTION_POINTERS structure specifying a computer-independent description of the exception and the processor context at the time of the exception.

How could I get the faulting thread id and exception pointers in process B while running in process A?

Thanks.


A pointer to a MINIDUMP_EXCEPTION_INFORMATION structure describing the client exception that caused the minidump to be generated. If the value of this parameter is NULL, no exception information is included in the minidump file.

Despite the fact that the paramter is marked __in and not __in_opt you can indeed pass NULL here. To get that information in the first place from the target process your process would have to be debugging it anyway.

How and when does process A known to take a minidump of process B? If A is indeed debugging B, when WaitForDebugEvent returns with an EXCEPTION_DEBUG_EVENT, the information is available in the info structure.

If A isn't debugging B, then perhaps B is telling A through some IPC mechanism "Hey I'm crashing, take a minidump". In this case either B could take the dump itself or pass the exception information through the same IPC mechansim to A. Again though, this is problematic for the same reasons calling MiniDumpWriteDump in the crashing process is problematic, if things are blowing up, the thing that might have blown up may be what you need to tell A about it.

The other mechanism that might have A take a dump for B is A is installed as the JIT debugger, in which case, A will be debugging B and you can use the debugging APIs to get the exception information.

If A is just periodically taking minidumps of B, then there won't necessarily be any exceptions, so you can just pass NULL in this case.

Note that if you're intending on doing something like

WaitForSingleObject(handleToProcessB, INFINITE);
MiniDumpWriteDump(handleToProcessB, ...)

that this will not work. The OS keeps around a very few things, mainly the exit code for the process, not the virtual address space and the stacks which you need to take a minidump.


To have an automatic dump created on a given exception on a specific process name, my advise would be to use DebugDiag or AdPlus. Those are external (and free !) software that you can configure to do so.

If you really want to write the dump by yourself, you can do it in process B : MSDN warn you that is not a good idea, because nasty errors like out of memory, stack overflow, or stack corruption (list is not exhaustive) will certainly use memory and stack, and so you may ends up with no dump at all (and a very bad process crash). From my experience, this is pretty rare (I used to work on a very stressed distributed C++ software). For others exception, it should be ok. In that case, you can use an exception translator (see _set_se_translator) or a vectored exception handler (see AddVectoredContinueHandler) or the function GetExceptionInformation() to get the EXCEPTION_RECORD structure (there may be others ways that I'm not aware of).

Creating the dump from process A after an exception in process B means that you have to copy all informations about the exception, and warn the process A that it has to dump something with this exception. This will consume memory and stack, and so you will have the same limitation than explained before.

Hope that will help

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号