2010-11-04 35 views
5

Je suis en train d'utiliser MiniDumpWriteDump() API pour vider un processus écrasé B d'un autre processus R. Je fais cela parce que MSDN a dit:Existe-t-il un moyen de connaître l'ID de thread dans un autre processus qui déclenche une exception?

MiniDumpWriteDump devrait être appelé d'un processus distinct si tout possible, plutôt qu'à partir du processus cible en cours de vidage.

Le MiniDumpWriteDump() est définie comme ceci:

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

Surtout, le ExceptionParam est de type PMINIDUMP_EXCEPTION_INFORMATION, qui est défini comme suit:

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

Maintenant, je me demande comment préparer les 2 paramètres suivants:

ThreadId Identificateur du thread lançant l'exception.

ExceptionPointers Un pointeur vers une structure EXCEPTION_POINTERS spécifiant une description d'ordinateur indépendant de l'exception et le contexte du processeur au moment de l'exception.

Comment puis-je obtenir l'identificateur de thread défaillant et les pointeurs d'exception dans le processus B pendant le processus A?

Merci.

+0

Je suis confronté à un problème similaire. Je ne suis pas en mesure de passer PEXCEPTION_POINTERS ExceptionPointers à un autre processus. (Si j'utilise le concept FileMapping je finis par obtenir un pointeur nul). Veuillez préciser comment vous vous êtes fixé sur celui-ci. –

Répondre

0

Pour avoir un vidage automatique créé sur une exception donnée sur un nom de processus spécifique, mon conseil serait d'utiliser DebugDiag ou AdPlus. Ce sont des logiciels externes (et gratuits!) Que vous pouvez configurer pour le faire. Si vous voulez vraiment écrire la sauvegarde par vous-même, vous pouvez le faire dans le processus B: MSDN vous avertir que ce n'est pas une bonne idée, car des erreurs désagréables comme un manque de mémoire, un débordement de pile ou une corruption de pile non exhaustif) utilisera certainement la mémoire et la pile, et ainsi vous pouvez finir par ne pas dump du tout (et un très mauvais plantage du processus). D'après mon expérience, c'est assez rare (je travaillais sur un logiciel C++ distribué très stressé). Pour d'autres exceptions, ça devrait aller. Dans ce cas, vous pouvez utiliser un traducteur d'exception (voir _set_se_translator) ou un gestionnaire d'exceptions vectoriel (voir AddVectoredContinueHandler) ou la fonction GetExceptionInformation() pour obtenir la structure EXCEPTION_RECORD (il peut y avoir d'autres façons que je ne connais pas).

La création du vidage à partir du processus A après une exception dans le processus B signifie que vous devez copier toutes les informations sur l'exception et avertir le processus A qu'il doit vider quelque chose avec cette exception. Cela consommera de la mémoire et de la pile, et ainsi vous aurez la même limite qu'expliquée auparavant.

Espoir qui aidera

2

Un pointeur sur une structure MINIDUMP_EXCEPTION_INFORMATION décrivant l'exception du client qui a provoqué la minidump à générer. Si la valeur de ce paramètre est NULL, aucune information d'exception n'est incluse dans le fichier minidump.

Malgré le fait que le paramter est marqué __in et non __in_opt vous pouvez en effet passer NULL ici. Pour obtenir cette information en premier lieu du processus cible, votre processus devrait être débogué de toute façon.

Comment et quand le processus A est-il connu pour prendre un minidump de processus B? Si A est en train de déboguer B, lorsque WaitForDebugEvent renvoie avec un EXCEPTION_DEBUG_EVENT, les informations sont disponibles dans la structure d'informations.

Si A ne débogue pas B, alors B peut dire à A via un mécanisme IPC "Hey je plante, prenez un minidump". Dans ce cas, soit B peut prendre la sauvegarde elle-même, soit transmettre les informations d'exception via le même mécanisme IPC à A. Encore une fois, cela est problématique pour les mêmes raisons que l'appel de MiniDumpWriteDump dans le processus d'écrasement est problématique. qui pourrait avoir explosé peut être ce que vous devez dire à ce sujet. L'autre mécanisme qui pourrait avoir A prendre une sauvegarde pour B est A est installé en tant que débogueur JIT, auquel cas A va déboguer B et vous pouvez utiliser les API de débogage pour obtenir les informations d'exception.

Si A prend périodiquement des minidumps de B, il n'y aura pas forcément d'exception, donc vous pouvez simplement passer NULL dans ce cas.

Notez que si vous avez l'intention de faire quelque chose comme

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

que cela ne fonctionnera pas. Le système d'exploitation conserve un très petit nombre de choses, principalement le code de sortie du processus, pas l'espace d'adressage virtuel et les piles dont vous avez besoin pour prendre un minidump.