2009-11-25 4 views
2

Je réalise que ce sera spécifique à la plate-forme: est-il possible d'obtenir une trace de pile à partir d'une exception C++ non interceptée, mais à partir du moment où l'exception est levée?Obtenir la trace de la pile à partir d'une exception non interceptée?

J'ai un gestionnaire d'exceptions structurées Windows pour intercepter les violations d'accès, etc. et générer un minidump. Mais bien sûr, cela ne sera pas appelé en cas de résiliation en raison d'une exception C++ non interceptée, et donc il n'y a pas de vidage sur incident.

Je suis à la recherche d'une solution Windows pour le moment (peu importe comment sale!), Mais je voudrais entendre parler d'autres plates-formes si possible.

Merci.

Répondre

2

Nous avons mis en minidumps pour les exceptions non gérées dans notre dernier titre en utilisant les informations de ce site:

http://www.debuginfo.com/articles/effminidumps.html

Et pour attraper les exceptions non gérées sur les fenêtres ont un regard sur:

SetUnhandledExceptionFilter (http://msdn.microsoft.com/en-us/library/ms680634%28VS.85%29.aspx). En tant qu'Autde, nous avons passé beaucoup de temps à expérimenter avec les différents niveaux de minidump jusqu'à ce que nous nous sommes installés sur un. Cela s'est avéré ne pas être vraiment utile dans les accidents du monde réel, car nous n'avions aucune idée de ce qu'ils seraient au moment de la mise en œuvre des mini-pompes. C'est très spécifique à l'application, et aussi spécifique au crash, donc ma recommandation est d'ajouter le gestionnaire minidump le plus tôt possible, il va grandir avec le projet et via QA et il sera un épargnant de vie à un moment donné (et espérons-le dans le monde réel aussi).

+2

Cela fonctionne pour les exceptions C++ non interceptées (enfin, pour les applications créées avec Visual Studio). Mon incompréhension originelle était due à un blocage caché (...) dans les profondeurs d'une bibliothèque quelque part ...! –

1

Essayez d'utiliser set_terminate pour installer le gestionnaire de terminaison. Et à l'intérieur, tracez la pile en utilisant les fonctions de mini-dump. Peut-être que ça va marcher.

+0

C'est exactement ce que je fais, basé sur cet article: http://www.codeproject.com/debug/XCrashReportPt1.asp –

2

Vous pouvez utiliser le try-except Statement pour "convertir" une exception C++ en une exception structurée (à partir de laquelle vous pouvez ensuite obtenir une belle trace de pile). Considérez ceci:

// Your function to get a backtrace from a CONTEXT 
const char *readBacktrace(CONTEXT &ctx); 

extern "C" 
static DWORD exceptFilter(struct _EXCEPTION_POINTERS* exInf) 
{ 
    OutputDebugStringA(readBacktrace(*exInf->ContextRecord)); 
    return EXCEPTION_EXECUTE_HANDLER; 
} 

try { 
    // your C++ code which might yield exceptions 
} catch (...) { 
    // In case a C++ exception occurs, raise a structured exception and catch it immediately 
    // so that we get a CONTEXT object which we can use to generate a stack trace. 
    __try { 
    RaiseException(1, 0, 0, NULL); 
    } __except(exceptFilter(GetExceptionInformation())) { 
    } 
} 

C'est un peu maladroit, mais la bonne chose est que vous pouvez mettre la partie __try {} __except() {} en fonction d'usage général dumpStackTrace(). Vous pouvez ensuite générer des traces de pile à partir de n'importe quel point de votre programme, comme vous le souhaitez.

+0

ce code ne compile pas vraiment car vous ne pouvez pas utiliser __try/__ sauf à l'intérieur essayer /capture. –

Questions connexes