2010-11-04 10 views
5

Ich versuche MiniDumpWriteDump() API zu verwenden, um einen abgestürzten Prozess B von einem anderen Prozess A. dump Ich tue dies, weil MSDN sagte so:Gibt es eine Möglichkeit, die Thread-ID in einem anderen Prozess zu kennen, der eine Ausnahme auslöst?

MiniDumpWriteDump sollte von einem separaten Prozess, wenn überhaupt aufgerufen werden möglich, anstatt von innerhalb des Zielprozesses gedumpt werden.

Die MiniDumpWriteDump() als das definiert:

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

Insbesondere die ExceptionParam ist vom Typ PMINIDUMP_EXCEPTION_INFORMATION, die wie unten definiert ist:

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

Jetzt frage ich bin wie die folgenden 2 Parameter vorbereitet werden:

ThreadId Der Bezeichner des Threads, der die Ausnahme auslöst.

ExceptionPointers Ein Zeiger auf eine Struktur, die eine EXCEPTION_POINTERS rechnerunabhängige Beschreibung der Ausnahme und der Prozessorkontext zum Zeitpunkt der Ausnahme angibt.

Wie konnte ich die fehlerhaften Thread-ID- und Ausnahmezeiger in Prozess B erhalten, während ich in Prozess A lief?

Danke.

+0

Ich stehe vor einem ähnlichen Problem. Ich bin nicht in der Lage, PEXCEPTION_POINTERS ExceptionPointers an andere Prozesse zu übergeben. (Wenn ich das FileMapping-Konzept verwende, bekomme ich einen Nullzeiger). Bitte erläutern Sie, wie Sie sich auf diesen Punkt festgelegt haben. –

Antwort

0

Um einen automatischen Speicherauszug für eine bestimmte Ausnahme für einen bestimmten Prozessnamen erstellen zu lassen, wäre es ratsam, DebugDiag oder AdPlus zu verwenden. Dies sind externe (und kostenlose!) Software, die Sie dazu konfigurieren können.

Wenn Sie wirklich den Dump selbst schreiben möchten, können Sie es in Prozess B tun: MSDN warnen Sie, dass das keine gute Idee ist, weil böse Fehler wie nicht genügend Arbeitsspeicher, Stapelüberlauf oder Stapel Korruption (Liste ist) nicht erschöpfend) wird sicherlich Speicher und Stack verwenden, und so kann es passieren, dass es überhaupt keinen Speicherabzug gibt (und einen sehr schlechten Prozessabsturz). Aus meiner Erfahrung ist das ziemlich selten (ich habe früher an einer sehr gestressten verteilten C++ - Software gearbeitet). Für andere Ausnahme sollte es in Ordnung sein. In diesem Fall können Sie einen Exception-Translator (siehe _set_se_translator) oder einen Vectored-Exception-Handler (siehe AddVectoredContinueHandler) oder die Funktion GetExceptionInformation() verwenden, um die EXCEPTION_RECORD-Struktur zu erhalten (möglicherweise gibt es andere Möglichkeiten, die mir nicht bekannt sind).

Erstellen des Dump von Prozess A nach einer Ausnahme in Prozess B bedeutet, dass Sie alle Informationen über die Ausnahme kopieren müssen, und den Prozess A warnen, dass es etwas mit dieser Ausnahme ablegen muss. Dies wird Speicher und Stack verbrauchen, und Sie werden die gleiche Einschränkung als zuvor haben.

Hoffnung, die

2

Ein Zeiger auf eine MINIDUMP_EXCEPTION_INFORMATION Struktur beschreibt die Client-Ausnahme, die minidump verursacht generiert werden helfen. Wenn der Wert dieses Parameters NULL ist, sind keine Ausnahmeinformationen in der Minidump-Datei enthalten.

Trotz der Tatsache, dass die Paramter __in markiert ist und nicht __in_opt Sie können in der Tat NULL hier passieren. Um diese Information in erster Linie aus dem Zielprozess zu bekommen, müsste Ihr Prozess trotzdem debuggen.

Wie und wann ist Prozess A bekannt, um einen Minidump von Prozess B zu nehmen? Wenn A tatsächlich B debuggt, wenn WaitForDebugEvent mit einem EXCEPTION_DEBUG_EVENT zurückkehrt, ist die Information in der Infostruktur verfügbar.

Wenn A B nicht debuggt, dann sagt B vielleicht A durch einen IPC-Mechanismus "Hey, ich stürze, nimm einen Minidump". In diesem Fall könnte entweder B den Dump selbst übernehmen oder die Ausnahmeinformationen durch den gleichen IPC-Mechanismus an A weitergeben. Dies ist jedoch aus den gleichen Gründen problematisch, da das Aufrufen von MiniDumpWriteDump im Absturzprozess problematisch ist, wenn Dinge in die Luft gehen Das könnte in die Luft gegangen sein, was Sie brauchen, um A davon zu erzählen. Der andere Mechanismus, der A möglicherweise einen Speicherauszug für B haben kann, ist A als der JIT-Debugger installiert, in diesem Fall wird A debuggen B und Sie können die Debugging-APIs verwenden, um die Ausnahmeinformationen zu erhalten.

Wenn A nur in regelmäßigen Abständen Minidumps von B verwendet, dann gibt es nicht unbedingt Ausnahmen, so dass Sie in diesem Fall einfach NULL übergeben können.

Beachten Sie, dass, wenn Sie etwas auf dem Tun wie

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

sind die beabsichtigen, dass dies nicht funktionieren wird. Das Betriebssystem enthält nur ein paar wenige Dinge, hauptsächlich den Exit-Code für den Prozess, nicht den virtuellen Adressraum und die Stacks, die Sie für einen Minidump benötigen.