aboutsummaryrefslogtreecommitdiff
path: root/src/client/windows/unittests
diff options
context:
space:
mode:
authorivan.penkov@gmail.com <ivan.penkov@gmail.com@4c0a9323-5329-0410-9bdc-e9ce6186880e>2012-10-19 18:51:05 +0000
committerivan.penkov@gmail.com <ivan.penkov@gmail.com@4c0a9323-5329-0410-9bdc-e9ce6186880e>2012-10-19 18:51:05 +0000
commitdf8e3973f49e9320464f20b62953998736fe9b9e (patch)
tree308dbe8b4ea5f18a62c6195b4a89c70d89ba524a /src/client/windows/unittests
parentFix some compiler errors in exception_handler_unittest by casting like crazy (diff)
downloadbreakpad-df8e3973f49e9320464f20b62953998736fe9b9e.tar.xz
Fixing Windows client unit tests. They were broken in r1034 due to gMock and
gTest upgrade. While fixing the broken tests I also used the opportunity to add a few more tests that cover filter and callback execution, and nesting of exception handlers. https://breakpad.appspot.com/489002/ git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1073 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/client/windows/unittests')
-rw-r--r--src/client/windows/unittests/client_tests.gyp2
-rw-r--r--src/client/windows/unittests/dump_analysis.cc4
-rw-r--r--src/client/windows/unittests/dump_analysis.h2
-rw-r--r--src/client/windows/unittests/exception_handler_death_test.cc28
-rwxr-xr-xsrc/client/windows/unittests/exception_handler_nesting_test.cc327
-rw-r--r--src/client/windows/unittests/exception_handler_test.cc37
-rwxr-xr-xsrc/client/windows/unittests/exception_handler_test.h61
-rw-r--r--src/client/windows/unittests/minidump_test.cc4
8 files changed, 449 insertions, 16 deletions
diff --git a/src/client/windows/unittests/client_tests.gyp b/src/client/windows/unittests/client_tests.gyp
index 6563ecf0..6dc9fe71 100644
--- a/src/client/windows/unittests/client_tests.gyp
+++ b/src/client/windows/unittests/client_tests.gyp
@@ -36,8 +36,10 @@
'target_name': 'client_tests',
'type': 'executable',
'sources': [
+ 'exception_handler_test.h',
'exception_handler_test.cc',
'exception_handler_death_test.cc',
+ 'exception_handler_nesting_test.cc',
'minidump_test.cc',
'dump_analysis.cc',
'dump_analysis.h',
diff --git a/src/client/windows/unittests/dump_analysis.cc b/src/client/windows/unittests/dump_analysis.cc
index b57b03da..6bf85471 100644
--- a/src/client/windows/unittests/dump_analysis.cc
+++ b/src/client/windows/unittests/dump_analysis.cc
@@ -31,8 +31,8 @@
#include <objbase.h>
#include <dbghelp.h>
-#include "dump_analysis.h" // NOLINT
-#include "gtest/gtest.h"
+#include "client/windows/unittests/dump_analysis.h" // NOLINT
+#include "testing/gtest/include/gtest/gtest.h"
DumpAnalysis::~DumpAnalysis() {
if (dump_file_view_ != NULL) {
diff --git a/src/client/windows/unittests/dump_analysis.h b/src/client/windows/unittests/dump_analysis.h
index b3155691..6cef48d8 100644
--- a/src/client/windows/unittests/dump_analysis.h
+++ b/src/client/windows/unittests/dump_analysis.h
@@ -30,7 +30,7 @@
#ifndef CLIENT_WINDOWS_UNITTESTS_DUMP_ANALYSIS_H_
#define CLIENT_WINDOWS_UNITTESTS_DUMP_ANALYSIS_H_
-#include "../crash_generation/minidump_generator.h"
+#include "client/windows/crash_generation/minidump_generator.h"
// Convenience to get to the PEB pointer in a TEB.
struct FakeTEB {
diff --git a/src/client/windows/unittests/exception_handler_death_test.cc b/src/client/windows/unittests/exception_handler_death_test.cc
index a50f9134..9d6acbc9 100644
--- a/src/client/windows/unittests/exception_handler_death_test.cc
+++ b/src/client/windows/unittests/exception_handler_death_test.cc
@@ -35,11 +35,12 @@
#include <string>
-#include "../../../breakpad_googletest_includes.h"
-#include "../../../../common/windows/string_utils-inl.h"
-#include "../crash_generation/crash_generation_server.h"
-#include "../handler/exception_handler.h"
-#include "../../../../google_breakpad/processor/minidump.h"
+#include "breakpad_googletest_includes.h"
+#include "client/windows/crash_generation/crash_generation_server.h"
+#include "client/windows/handler/exception_handler.h"
+#include "client/windows/unittests/exception_handler_test.h"
+#include "common/windows/string_utils-inl.h"
+#include "google_breakpad/processor/minidump.h"
namespace {
@@ -122,6 +123,10 @@ TEST_F(ExceptionHandlerDeathTest, InProcTest) {
new google_breakpad::ExceptionHandler(
temp_path_, NULL, &MinidumpWrittenCallback, NULL,
google_breakpad::ExceptionHandler::HANDLER_ALL);
+
+ // Disable GTest SEH handler
+ testing::DisableExceptionHandlerInScope disable_exception_handler;
+
int *i = NULL;
ASSERT_DEATH((*i)++, kSuccessIndicator);
delete exc;
@@ -141,6 +146,10 @@ void ExceptionHandlerDeathTest::DoCrashAccessViolation() {
temp_path_, NULL, NULL, NULL,
google_breakpad::ExceptionHandler::HANDLER_ALL, MiniDumpNormal, kPipeName,
NULL);
+
+ // Disable GTest SEH handler
+ testing::DisableExceptionHandlerInScope disable_exception_handler;
+
// Although this is executing in the child process of the death test,
// if it's not true we'll still get an error rather than the crash
// being expected.
@@ -252,6 +261,9 @@ TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemory) {
temp_path_, NULL, NULL, NULL,
google_breakpad::ExceptionHandler::HANDLER_ALL);
+ // Disable GTest SEH handler
+ testing::DisableExceptionHandlerInScope disable_exception_handler;
+
// Get some executable memory.
const u_int32_t kMemorySize = 256; // bytes
const int kOffset = kMemorySize / 2;
@@ -334,6 +346,9 @@ TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemoryMinBound) {
temp_path_, NULL, NULL, NULL,
google_breakpad::ExceptionHandler::HANDLER_ALL);
+ // Disable GTest SEH handler
+ testing::DisableExceptionHandlerInScope disable_exception_handler;
+
SYSTEM_INFO sSysInfo; // Useful information about the system
GetSystemInfo(&sSysInfo); // Initialize the structure.
@@ -421,6 +436,9 @@ TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemoryMaxBound) {
temp_path_, NULL, NULL, NULL,
google_breakpad::ExceptionHandler::HANDLER_ALL);
+ // Disable GTest SEH handler
+ testing::DisableExceptionHandlerInScope disable_exception_handler;
+
SYSTEM_INFO sSysInfo; // Useful information about the system
GetSystemInfo(&sSysInfo); // Initialize the structure.
diff --git a/src/client/windows/unittests/exception_handler_nesting_test.cc b/src/client/windows/unittests/exception_handler_nesting_test.cc
new file mode 100755
index 00000000..0cf30013
--- /dev/null
+++ b/src/client/windows/unittests/exception_handler_nesting_test.cc
@@ -0,0 +1,327 @@
+// Copyright 2012, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <windows.h>
+
+#include <string>
+
+#include "breakpad_googletest_includes.h"
+#include "client/windows/handler/exception_handler.h"
+#include "client/windows/unittests/exception_handler_test.h"
+
+namespace {
+
+const char kFoo[] = "foo";
+const char kBar[] = "bar";
+
+const char kStartOfLine[] = "^";
+const char kEndOfLine[] = "$";
+
+const char kFilterReturnsTrue[] = "filter_returns_true";
+const char kFilterReturnsFalse[] = "filter_returns_false";
+
+const char kCallbackReturnsTrue[] = "callback_returns_true";
+const char kCallbackReturnsFalse[] = "callback_returns_false";
+
+bool DoesPathExist(const wchar_t *path_name) {
+ DWORD flags = GetFileAttributes(path_name);
+ if (flags == INVALID_FILE_ATTRIBUTES) {
+ return false;
+ }
+ return true;
+}
+
+// A callback function to run before Breakpad performs any substantial
+// processing of an exception. A FilterCallback is called before writing
+// a minidump. context is the parameter supplied by the user as
+// callback_context when the handler was created. exinfo points to the
+// exception record, if any; assertion points to assertion information,
+// if any.
+//
+// If a FilterCallback returns true, Breakpad will continue processing,
+// attempting to write a minidump. If a FilterCallback returns false,
+// Breakpad will immediately report the exception as unhandled without
+// writing a minidump, allowing another handler the opportunity to handle it.
+template <bool filter_return_value>
+bool CrashHandlerFilter(void* context,
+ EXCEPTION_POINTERS* exinfo,
+ MDRawAssertionInfo* assertion) {
+ if (filter_return_value) {
+ fprintf(stderr, kFilterReturnsTrue);
+ } else {
+ fprintf(stderr, kFilterReturnsFalse);
+ }
+ fflush(stderr);
+
+ return filter_return_value;
+}
+
+// A callback function to run after the minidump has been written.
+// minidump_id is a unique id for the dump, so the minidump
+// file is <dump_path>\<minidump_id>.dmp. context is the parameter supplied
+// by the user as callback_context when the handler was created. exinfo
+// points to the exception record, or NULL if no exception occurred.
+// succeeded indicates whether a minidump file was successfully written.
+// assertion points to information about an assertion if the handler was
+// invoked by an assertion.
+//
+// If an exception occurred and the callback returns true, Breakpad will treat
+// the exception as fully-handled, suppressing any other handlers from being
+// notified of the exception. If the callback returns false, Breakpad will
+// treat the exception as unhandled, and allow another handler to handle it.
+// If there are no other handlers, Breakpad will report the exception to the
+// system as unhandled, allowing a debugger or native crash dialog the
+// opportunity to handle the exception. Most callback implementations
+// should normally return the value of |succeeded|, or when they wish to
+// not report an exception of handled, false. Callbacks will rarely want to
+// return true directly (unless |succeeded| is true).
+//
+// For out-of-process dump generation, dump path and minidump ID will always
+// be NULL. In case of out-of-process dump generation, the dump path and
+// minidump id are controlled by the server process and are not communicated
+// back to the crashing process.
+template <bool callback_return_value>
+bool MinidumpWrittenCallback(const wchar_t* dump_path,
+ const wchar_t* minidump_id,
+ void* context,
+ EXCEPTION_POINTERS* exinfo,
+ MDRawAssertionInfo* assertion,
+ bool succeeded) {
+ bool rv = false;
+ if (callback_return_value &&
+ succeeded &&
+ DoesPathExist(dump_path)) {
+ rv = true;
+ fprintf(stderr, kCallbackReturnsTrue);
+ } else {
+ fprintf(stderr, kCallbackReturnsFalse);
+ }
+ fflush(stderr);
+
+ return rv;
+}
+
+
+void DoCrash(const char *message) {
+ if (message) {
+ fprintf(stderr, "%s", message);
+ fflush(stderr);
+ }
+ int *i = NULL;
+ (*i)++;
+
+ ASSERT_TRUE(false);
+}
+
+void InstallExceptionHandlerAndCrash(bool install_filter,
+ bool filter_return_value,
+ bool install_callback,
+ bool callback_return_value) {
+ wchar_t temp_path[MAX_PATH] = { '\0' };
+ GetTempPath(MAX_PATH, temp_path);
+
+ ASSERT_TRUE(DoesPathExist(temp_path));
+ google_breakpad::ExceptionHandler exc(
+ temp_path,
+ install_filter ?
+ (filter_return_value ?
+ &CrashHandlerFilter<true> :
+ &CrashHandlerFilter<false>) :
+ NULL,
+ install_callback ?
+ (callback_return_value ?
+ &MinidumpWrittenCallback<true> :
+ &MinidumpWrittenCallback<false>) :
+ NULL,
+ NULL, // callback_context
+ google_breakpad::ExceptionHandler::HANDLER_EXCEPTION);
+
+ // Disable GTest SEH handler
+ testing::DisableExceptionHandlerInScope disable_exception_handler;
+
+ DoCrash(NULL);
+}
+
+TEST(AssertDeathSanity, Simple) {
+ ASSERT_DEATH(DoCrash(NULL), "");
+}
+
+TEST(AssertDeathSanity, Regex) {
+ ASSERT_DEATH(DoCrash(kFoo),
+ std::string(kStartOfLine) +
+ std::string(kFoo) +
+ std::string(kEndOfLine));
+
+ ASSERT_DEATH(DoCrash(kBar),
+ std::string(kStartOfLine) +
+ std::string(kBar) +
+ std::string(kEndOfLine));
+}
+
+TEST(ExceptionHandlerCallbacks, FilterTrue_No_Callback) {
+ ASSERT_DEATH(
+ InstallExceptionHandlerAndCrash(true, // install_filter
+ true, // filter_return_value
+ false, // install_callback
+ false), // callback_return_value
+ std::string(kStartOfLine) +
+ std::string(kFilterReturnsTrue) +
+ std::string(kEndOfLine));
+}
+
+TEST(ExceptionHandlerCallbacks, FilterTrue_Callback) {
+ ASSERT_DEATH(
+ InstallExceptionHandlerAndCrash(true, // install_filter
+ true, // filter_return_value
+ true, // install_callback
+ false), // callback_return_value
+ std::string(kStartOfLine) +
+ std::string(kFilterReturnsTrue) +
+ std::string(kCallbackReturnsFalse) +
+ std::string(kEndOfLine));
+}
+
+TEST(ExceptionHandlerCallbacks, FilterFalse_No_Callback) {
+ ASSERT_DEATH(
+ InstallExceptionHandlerAndCrash(true, // install_filter
+ false, // filter_return_value
+ false, // install_callback
+ false), // callback_return_value
+ std::string(kStartOfLine) +
+ std::string(kFilterReturnsFalse) +
+ std::string(kEndOfLine));
+}
+
+// Callback shouldn't be executed when filter returns false
+TEST(ExceptionHandlerCallbacks, FilterFalse_Callback) {
+ ASSERT_DEATH(
+ InstallExceptionHandlerAndCrash(true, // install_filter
+ false, // filter_return_value
+ true, // install_callback
+ false), // callback_return_value
+ std::string(kStartOfLine) +
+ std::string(kFilterReturnsFalse) +
+ std::string(kEndOfLine));
+}
+
+TEST(ExceptionHandlerCallbacks, No_Filter_No_Callback) {
+ ASSERT_DEATH(
+ InstallExceptionHandlerAndCrash(false, // install_filter
+ true, // filter_return_value
+ false, // install_callback
+ false), // callback_return_value
+ std::string(kStartOfLine) +
+ std::string(kEndOfLine));
+}
+
+TEST(ExceptionHandlerCallbacks, No_Filter_Callback) {
+ ASSERT_DEATH(
+ InstallExceptionHandlerAndCrash(false, // install_filter
+ true, // filter_return_value
+ true, // install_callback
+ false), // callback_return_value
+ std::string(kStartOfLine) +
+ std::string(kCallbackReturnsFalse) +
+ std::string(kEndOfLine));
+}
+
+
+TEST(ExceptionHandlerNesting, Skip_From_Inner_Filter) {
+ wchar_t temp_path[MAX_PATH] = { '\0' };
+ GetTempPath(MAX_PATH, temp_path);
+
+ ASSERT_TRUE(DoesPathExist(temp_path));
+ google_breakpad::ExceptionHandler exc(
+ temp_path,
+ &CrashHandlerFilter<true>,
+ &MinidumpWrittenCallback<false>,
+ NULL, // callback_context
+ google_breakpad::ExceptionHandler::HANDLER_EXCEPTION);
+
+ ASSERT_DEATH(
+ InstallExceptionHandlerAndCrash(true, // install_filter
+ false, // filter_return_value
+ true, // install_callback
+ true), // callback_return_value
+ std::string(kStartOfLine) +
+ std::string(kFilterReturnsFalse) + // inner filter
+ std::string(kFilterReturnsTrue) + // outer filter
+ std::string(kCallbackReturnsFalse) + // outer callback
+ std::string(kEndOfLine));
+}
+
+TEST(ExceptionHandlerNesting, Skip_From_Inner_Callback) {
+ wchar_t temp_path[MAX_PATH] = { '\0' };
+ GetTempPath(MAX_PATH, temp_path);
+
+ ASSERT_TRUE(DoesPathExist(temp_path));
+ google_breakpad::ExceptionHandler exc(
+ temp_path,
+ &CrashHandlerFilter<true>,
+ &MinidumpWrittenCallback<false>,
+ NULL, // callback_context
+ google_breakpad::ExceptionHandler::HANDLER_EXCEPTION);
+
+ ASSERT_DEATH(
+ InstallExceptionHandlerAndCrash(true, // install_filter
+ true, // filter_return_value
+ true, // install_callback
+ false), // callback_return_value
+ std::string(kStartOfLine) +
+ std::string(kFilterReturnsTrue) + // inner filter
+ std::string(kCallbackReturnsFalse) + // inner callback
+ std::string(kFilterReturnsTrue) + // outer filter
+ std::string(kCallbackReturnsFalse) + // outer callback
+ std::string(kEndOfLine));
+}
+
+TEST(ExceptionHandlerNesting, Handled_By_Inner_Handler) {
+ wchar_t temp_path[MAX_PATH] = { '\0' };
+ GetTempPath(MAX_PATH, temp_path);
+
+ ASSERT_TRUE(DoesPathExist(temp_path));
+ google_breakpad::ExceptionHandler exc(
+ temp_path,
+ &CrashHandlerFilter<true>,
+ &MinidumpWrittenCallback<true>,
+ NULL, // callback_context
+ google_breakpad::ExceptionHandler::HANDLER_EXCEPTION);
+
+ ASSERT_DEATH(
+ InstallExceptionHandlerAndCrash(true, // install_filter
+ true, // filter_return_value
+ true, // install_callback
+ true), // callback_return_value
+ std::string(kStartOfLine) +
+ std::string(kFilterReturnsTrue) + // inner filter
+ std::string(kCallbackReturnsTrue) + // inner callback
+ std::string(kEndOfLine));
+}
+
+} // namespace
diff --git a/src/client/windows/unittests/exception_handler_test.cc b/src/client/windows/unittests/exception_handler_test.cc
index 9851998e..be9397b8 100644
--- a/src/client/windows/unittests/exception_handler_test.cc
+++ b/src/client/windows/unittests/exception_handler_test.cc
@@ -27,6 +27,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#include "client/windows/unittests/exception_handler_test.h"
+
#include <windows.h>
#include <dbghelp.h>
#include <strsafe.h>
@@ -35,12 +37,25 @@
#include <string>
-#include "../../../breakpad_googletest_includes.h"
-#include "../../../../common/windows/string_utils-inl.h"
-#include "../../../../google_breakpad/processor/minidump.h"
-#include "../crash_generation/crash_generation_server.h"
-#include "../handler/exception_handler.h"
-#include "dump_analysis.h" // NOLINT
+#include "breakpad_googletest_includes.h"
+#include "client/windows/crash_generation/crash_generation_server.h"
+#include "client/windows/handler/exception_handler.h"
+#include "client/windows/unittests/dump_analysis.h" // NOLINT
+#include "common/windows/string_utils-inl.h"
+#include "google_breakpad/processor/minidump.h"
+
+namespace testing {
+
+DisableExceptionHandlerInScope::DisableExceptionHandlerInScope() {
+ catch_exceptions_ = GTEST_FLAG(catch_exceptions);
+ GTEST_FLAG(catch_exceptions) = false;
+}
+
+DisableExceptionHandlerInScope::~DisableExceptionHandlerInScope() {
+ GTEST_FLAG(catch_exceptions) = catch_exceptions_;
+}
+
+} // namespace testing
namespace {
@@ -361,6 +376,10 @@ TEST_F(ExceptionHandlerTest, WriteMinidumpTest) {
DumpCallback,
NULL,
ExceptionHandler::HANDLER_ALL);
+
+ // Disable GTest SEH handler
+ testing::DisableExceptionHandlerInScope disable_exception_handler;
+
ASSERT_TRUE(handler.WriteMinidump());
ASSERT_FALSE(dump_file.empty());
@@ -396,6 +415,9 @@ TEST_F(ExceptionHandlerTest, AdditionalMemory) {
NULL,
ExceptionHandler::HANDLER_ALL);
+ // Disable GTest SEH handler
+ testing::DisableExceptionHandlerInScope disable_exception_handler;
+
// Add the memory region to the list of memory to be included.
handler.RegisterAppMemory(memory, kMemorySize);
ASSERT_TRUE(handler.WriteMinidump());
@@ -447,6 +469,9 @@ TEST_F(ExceptionHandlerTest, AdditionalMemoryRemove) {
NULL,
ExceptionHandler::HANDLER_ALL);
+ // Disable GTest SEH handler
+ testing::DisableExceptionHandlerInScope disable_exception_handler;
+
// Add the memory region to the list of memory to be included.
handler.RegisterAppMemory(memory, kMemorySize);
diff --git a/src/client/windows/unittests/exception_handler_test.h b/src/client/windows/unittests/exception_handler_test.h
new file mode 100755
index 00000000..ef973e53
--- /dev/null
+++ b/src/client/windows/unittests/exception_handler_test.h
@@ -0,0 +1,61 @@
+// Copyright 2012, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef CLIENT_WINDOWS_UNITTESTS_EXCEPTION_HANDLER_TEST_H_
+#define CLIENT_WINDOWS_UNITTESTS_EXCEPTION_HANDLER_TEST_H_
+
+namespace testing {
+
+// By default, GTest (on Windows) installs a SEH filter (and a handler) before
+// starting to run all the tests in order to avoid test interruptions is some
+// of the tests are crashing. Unfortunately, this functionality prevents the
+// execution to reach the UnhandledExceptionFilter installed by Google-Breakpad
+// ExceptionHandler so in order to test the Google-Breakpad exception handling
+// code the exception handling done by GTest must be disabled.
+// Usage:
+//
+// google_breakpad::ExceptionHandler exc(...);
+//
+// // Disable GTest SEH handler
+// testing::DisableExceptionHandlerInScope disable_exception_handler;
+// ...
+// ASSERT_DEATH( ... some crash ...);
+//
+class DisableExceptionHandlerInScope {
+ public:
+ DisableExceptionHandlerInScope();
+ ~DisableExceptionHandlerInScope();
+
+ private:
+ bool catch_exceptions_;
+};
+
+} // namespace testing
+
+#endif // CLIENT_WINDOWS_UNITTESTS_EXCEPTION_HANDLER_TEST_H_
diff --git a/src/client/windows/unittests/minidump_test.cc b/src/client/windows/unittests/minidump_test.cc
index ab7ae3b7..62f212f8 100644
--- a/src/client/windows/unittests/minidump_test.cc
+++ b/src/client/windows/unittests/minidump_test.cc
@@ -31,8 +31,8 @@
#include <objbase.h>
#include <dbghelp.h>
-#include "../crash_generation/minidump_generator.h"
-#include "dump_analysis.h" // NOLINT
+#include "client/windows/crash_generation/minidump_generator.h"
+#include "client/windows/unittests/dump_analysis.h" // NOLINT
#include "gtest/gtest.h"