2017-10-04 2 views
2

Unser Projekt verwendet Boost.Test für unsere Unit Tests. Wir möchten Minidumps erhalten, wenn unerwartete Ausnahmen auch in unseren Testfällen auftreten. Daher haben wir begonnen, Google Breakpad in die Minidumps zu integrieren.Wie Boost Test und Minidumps produzieren?

Offenbar fängt Boost.Test alle ausgelösten Ausnahmen von Benutzertests ab - ich nehme an, weil Boost-Testfälle jede Funktion mit einem try/catch umhüllen und der Komponententest einfach fehlschlägt, wenn eine unerwartete Ausnahme ausgelöst wird. Dies verhindert, dass der Breakpad-Ausnahme-Handler Minidumps auslöst und schreibt.

Ist es möglich, dass Boost.Test bei unerwarteten Ausnahmen in Komponententests nicht nur abfängt und fehlschlägt? Und lassen Sie stattdessen die Ausnahmen unbehandelt (oder erneut) gehen, damit Breakpad oder ein anderer Ausnahmebehandler ausgelöst werden kann, um einen Minidump zu schreiben?

Antwort

1

Ich habe ein paar verschiedene Ansätze versucht, aber die folgende Lösung bietet das beste Ergebnis. Definieren eines Makros zum Umbrechen des BOOST_AUTO_TEST_CASE-Makros und Umgeben des aufrufenden Codes mit SEH __try/__, außer dass die Ausnahmedaten in Breakpad übertragen werden.

#define CUSTOM_AUTO_TEST_CASE(test_name)                 \ 
void test_name##_custom_wrapper();                   \ 
                              \ 
BOOST_AUTO_TEST_CASE(test_name)                   \ 
{                           \ 
    __try                         \ 
    {                          \ 
     test_name##_custom_wrapper();                  \ 
    }                          \ 
    __except(pHandler->WriteMinidumpForException(GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER) {} \ 
}                           \ 
                              \ 
void test_name##_custom_wrapper()                   \ 

Wo pHandler ist ein Breakpad ExceptionHandler Zeiger.

Der Nachteil ist, dass Sie jedes Auftreten von BOOST_AUTO_TEST_CAST mit dem Wrapper-Makro ersetzen müssen. Aber es macht den Trick.

1

Boost.Test dient dazu, alle Ausnahmen von einem Testfall abzufangen, um weitere Testfälle auszuführen. Ich denke nicht, dass Sie dieses Verhalten ausschalten können, aber Sie können immer den Quellcode konsultieren.

Um zu erreichen, wonach Sie suchen, würde ich den Körper der Testfälle selbst umwickeln und Ausnahmen fangen und breakpad Minidumps geschrieben haben, wenn unerwartete Ausnahmen geworfen werden. Sie können diese genericize durch den Fang/Dump-Handler als eine Funktion zu schreiben, die einen Funktor akzeptiert, dass Ihr Testfall Körper und Ihre Handler mit dem Testgehäusekörper in einem Lambda-Aufruf:

void handler(std::function<void()> test_case) 
{ 
    try { 
    test_case(); 
    } catch (...) { 
    write_minidump(); 
    } 
} 

BOOST_AUTO_TEST_CASE(doit) 
{ 
    handler([] { 
    // do testing here 
    }); 
} 

Es wird mehr beteiligt, wenn Sie verwenden Fixtures, aber die gleiche Idee würde gelten.

+0

Ich mag diesen Vorschlag, aber zu dem Zeitpunkt, in dem der Minidump in den Catch-Block geschrieben wird, zeigt der Callstack, der im Minidump gespeichert ist, nur "Handler" an der Spitze des Stapels. Wenn jedoch ein 'unhandled exception filter' ausgelöst wird und der Dump geschrieben wird, wird der störende Callstack beibehalten. – mbradber

+0

Wie setzt Breakpad den Exception-Handler ein? – legalize

+0

https://chromium.googlesource.com/breakpad/breakpad/+/master/docs/windows_client_integration.md Ich habe einen ExceptionHandler basierend auf dem Dokument dort erstellt. Mit nur diesem setzt Breakpad seinen eigenen unbehandelten Ausnahmefilter-Callback, und unbehandelte Exceptions erzeugen Minidumps schön. Allerdings verwende ich die WriteMinidump-API explizit in einem catch-Block, der dem ähnlich ist, was Sie gepostet haben. – mbradber

Verwandte Themen