diff options
Diffstat (limited to 'toolkit/crashreporter/google-breakpad/src/client/windows/unittests')
10 files changed, 0 insertions, 2558 deletions
diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/client_tests.gyp b/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/client_tests.gyp deleted file mode 100644 index b13603ef4..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/client_tests.gyp +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright 2010 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. - -{ - 'includes': [ - '../../../build/common.gypi', - ], - 'targets': [ - { - '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', - 'crash_generation_server_test.cc' - ], - 'dependencies': [ - 'testing.gyp:gtest', - 'testing.gyp:gmock', - '../breakpad_client.gyp:common', - '../crash_generation/crash_generation.gyp:crash_generation_server', - '../crash_generation/crash_generation.gyp:crash_generation_client', - '../handler/exception_handler.gyp:exception_handler', - 'processor_bits', - ] - }, - { - 'target_name': 'processor_bits', - 'type': 'static_library', - 'include_dirs': [ - '<(DEPTH)', - ], - 'direct_dependent_settings': { - 'include_dirs': [ - '<(DEPTH)', - ] - }, - 'sources': [ - '<(DEPTH)/common/string_conversion.cc', - '<(DEPTH)/processor/basic_code_modules.cc', - '<(DEPTH)/processor/dump_context.cc', - '<(DEPTH)/processor/dump_object.cc', - '<(DEPTH)/processor/logging.cc', - '<(DEPTH)/processor/minidump.cc', - '<(DEPTH)/processor/pathname_stripper.cc', - '<(DEPTH)/processor/proc_maps_linux.cc', - ] - } - ], -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/crash_generation_server_test.cc b/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/crash_generation_server_test.cc deleted file mode 100644 index b7b2b84f2..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/crash_generation_server_test.cc +++ /dev/null @@ -1,305 +0,0 @@ -// Copyright 2010, 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 "testing/gtest/include/gtest/gtest.h" -#include "testing/include/gmock/gmock.h" - -#include "client/windows/crash_generation/crash_generation_server.h" -#include "client/windows/common/ipc_protocol.h" - -using testing::_; - -namespace { - -const wchar_t kPipeName[] = - L"\\\\.\\pipe\\CrashGenerationServerTest\\TestCaseServer"; - -const DWORD kPipeDesiredAccess = FILE_READ_DATA | - FILE_WRITE_DATA | - FILE_WRITE_ATTRIBUTES; - -const DWORD kPipeFlagsAndAttributes = SECURITY_IDENTIFICATION | - SECURITY_SQOS_PRESENT; - -const DWORD kPipeMode = PIPE_READMODE_MESSAGE; - -#define arraysize(f) (sizeof(f) / sizeof(*f)) -const google_breakpad::CustomInfoEntry kCustomInfoEntries[] = { - google_breakpad::CustomInfoEntry(L"prod", L"CrashGenerationServerTest"), - google_breakpad::CustomInfoEntry(L"ver", L"1.0"), -}; - -class CrashGenerationServerTest : public ::testing::Test { - public: - CrashGenerationServerTest() - : crash_generation_server_(kPipeName, - NULL, - CallOnClientConnected, &mock_callbacks_, - CallOnClientDumpRequested, &mock_callbacks_, - CallOnClientExited, &mock_callbacks_, - CallOnClientUploadRequested, &mock_callbacks_, - false, - NULL), - thread_id_(0), - exception_pointers_(NULL) { - memset(&assert_info_, 0, sizeof(assert_info_)); - } - - protected: - class MockCrashGenerationServerCallbacks { - public: - MOCK_METHOD1(OnClientConnected, - void(const google_breakpad::ClientInfo* client_info)); - MOCK_METHOD2(OnClientDumpRequested, - void(const google_breakpad::ClientInfo* client_info, - const std::wstring* file_path)); - MOCK_METHOD1(OnClientExited, - void(const google_breakpad::ClientInfo* client_info)); - MOCK_METHOD1(OnClientUploadRequested, - void(const DWORD crash_id)); - }; - - enum ClientFault { - NO_FAULT, - CLOSE_AFTER_CONNECT, - SEND_INVALID_REGISTRATION, - TRUNCATE_REGISTRATION, - CLOSE_AFTER_REGISTRATION, - RESPONSE_BUFFER_TOO_SMALL, - CLOSE_AFTER_RESPONSE, - SEND_INVALID_ACK - }; - - void SetUp() { - ASSERT_TRUE(crash_generation_server_.Start()); - } - - void FaultyClient(ClientFault fault_type) { - HANDLE pipe = CreateFile(kPipeName, - kPipeDesiredAccess, - 0, - NULL, - OPEN_EXISTING, - kPipeFlagsAndAttributes, - NULL); - - if (pipe == INVALID_HANDLE_VALUE) { - ASSERT_EQ(ERROR_PIPE_BUSY, GetLastError()); - - // Cannot continue retrying if wait on pipe fails. - ASSERT_TRUE(WaitNamedPipe(kPipeName, 500)); - - pipe = CreateFile(kPipeName, - kPipeDesiredAccess, - 0, - NULL, - OPEN_EXISTING, - kPipeFlagsAndAttributes, - NULL); - } - - ASSERT_NE(pipe, INVALID_HANDLE_VALUE); - - DWORD mode = kPipeMode; - ASSERT_TRUE(SetNamedPipeHandleState(pipe, &mode, NULL, NULL)); - - DoFaultyClient(fault_type, pipe); - - CloseHandle(pipe); - } - - void DoTestFault(ClientFault fault) { - EXPECT_CALL(mock_callbacks_, OnClientConnected(_)).Times(0); - ASSERT_NO_FATAL_FAILURE(FaultyClient(fault)); - ASSERT_NO_FATAL_FAILURE(FaultyClient(fault)); - ASSERT_NO_FATAL_FAILURE(FaultyClient(fault)); - - EXPECT_CALL(mock_callbacks_, OnClientConnected(_)); - - ASSERT_NO_FATAL_FAILURE(FaultyClient(NO_FAULT)); - - // Slight hack. The OnClientConnected is only invoked after the ack is - // received by the server. At that point, the FaultyClient call has already - // returned. The best way to wait until the server is done handling that is - // to send one more ping, whose processing will be blocked by delivery of - // the OnClientConnected message. - ASSERT_NO_FATAL_FAILURE(FaultyClient(CLOSE_AFTER_CONNECT)); - } - - MockCrashGenerationServerCallbacks mock_callbacks_; - - private: - // Depends on the caller to successfully open the pipe before invocation and - // to close it immediately afterwards. - void DoFaultyClient(ClientFault fault_type, HANDLE pipe) { - if (fault_type == CLOSE_AFTER_CONNECT) { - return; - } - - google_breakpad::CustomClientInfo custom_info = {kCustomInfoEntries, - arraysize(kCustomInfoEntries)}; - - google_breakpad::ProtocolMessage msg( - fault_type == SEND_INVALID_REGISTRATION ? - google_breakpad::MESSAGE_TAG_NONE : - google_breakpad::MESSAGE_TAG_REGISTRATION_REQUEST, - GetCurrentProcessId(), - MiniDumpNormal, - &thread_id_, - &exception_pointers_, - &assert_info_, - custom_info, - NULL, - NULL, - NULL); - - DWORD bytes_count = 0; - - ASSERT_TRUE(WriteFile(pipe, - &msg, - fault_type == TRUNCATE_REGISTRATION ? - sizeof(msg) / 2 : sizeof(msg), - &bytes_count, - NULL)); - - if (fault_type == CLOSE_AFTER_REGISTRATION) { - return; - } - - google_breakpad::ProtocolMessage reply; - - if (!ReadFile(pipe, - &reply, - fault_type == RESPONSE_BUFFER_TOO_SMALL ? - sizeof(google_breakpad::ProtocolMessage) / 2 : - sizeof(google_breakpad::ProtocolMessage), - &bytes_count, - NULL)) { - switch (fault_type) { - case TRUNCATE_REGISTRATION: - case RESPONSE_BUFFER_TOO_SMALL: - case SEND_INVALID_REGISTRATION: - return; - - default: - FAIL() << "Unexpectedly failed to register."; - } - } - - if (fault_type == CLOSE_AFTER_RESPONSE) { - return; - } - - google_breakpad::ProtocolMessage ack_msg; - ack_msg.tag = google_breakpad::MESSAGE_TAG_REGISTRATION_ACK; - - ASSERT_TRUE(WriteFile(pipe, - &ack_msg, - SEND_INVALID_ACK ? - sizeof(ack_msg) : sizeof(ack_msg) / 2, - &bytes_count, - NULL)); - - return; - } - - static void CallOnClientConnected( - void* context, const google_breakpad::ClientInfo* client_info) { - static_cast<MockCrashGenerationServerCallbacks*>(context)-> - OnClientConnected(client_info); - } - - static void CallOnClientDumpRequested( - void* context, - const google_breakpad::ClientInfo* client_info, - const std::wstring* file_path) { - static_cast<MockCrashGenerationServerCallbacks*>(context)-> - OnClientDumpRequested(client_info, file_path); - } - - static void CallOnClientExited( - void* context, const google_breakpad::ClientInfo* client_info) { - static_cast<MockCrashGenerationServerCallbacks*>(context)-> - OnClientExited(client_info); - } - - static void CallOnClientUploadRequested(void* context, const DWORD crash_id) { - static_cast<MockCrashGenerationServerCallbacks*>(context)-> - OnClientUploadRequested(crash_id); - } - - DWORD thread_id_; - EXCEPTION_POINTERS* exception_pointers_; - MDRawAssertionInfo assert_info_; - - google_breakpad::CrashGenerationServer crash_generation_server_; -}; - -TEST_F(CrashGenerationServerTest, PingServerTest) { - DoTestFault(CLOSE_AFTER_CONNECT); -} - -TEST_F(CrashGenerationServerTest, InvalidRegistration) { - DoTestFault(SEND_INVALID_REGISTRATION); -} - -TEST_F(CrashGenerationServerTest, TruncateRegistration) { - DoTestFault(TRUNCATE_REGISTRATION); -} - -TEST_F(CrashGenerationServerTest, CloseAfterRegistration) { - DoTestFault(CLOSE_AFTER_REGISTRATION); -} - -TEST_F(CrashGenerationServerTest, ResponseBufferTooSmall) { - DoTestFault(RESPONSE_BUFFER_TOO_SMALL); -} - -TEST_F(CrashGenerationServerTest, CloseAfterResponse) { - DoTestFault(CLOSE_AFTER_RESPONSE); -} - -// It turns out that, as long as you send one byte, the ACK is accepted and -// registration succeeds. -TEST_F(CrashGenerationServerTest, SendInvalidAck) { - EXPECT_CALL(mock_callbacks_, OnClientConnected(_)); - ASSERT_NO_FATAL_FAILURE(FaultyClient(SEND_INVALID_ACK)); - - // See DoTestFault for an explanation of this line - ASSERT_NO_FATAL_FAILURE(FaultyClient(CLOSE_AFTER_CONNECT)); - - EXPECT_CALL(mock_callbacks_, OnClientConnected(_)); - ASSERT_NO_FATAL_FAILURE(FaultyClient(NO_FAULT)); - - // See DoTestFault for an explanation of this line - ASSERT_NO_FATAL_FAILURE(FaultyClient(CLOSE_AFTER_CONNECT)); -} - -} // anonymous namespace diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/dump_analysis.cc b/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/dump_analysis.cc deleted file mode 100644 index 6bf854719..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/dump_analysis.cc +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright (c) 2010, 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 <objbase.h> -#include <dbghelp.h> - -#include "client/windows/unittests/dump_analysis.h" // NOLINT -#include "testing/gtest/include/gtest/gtest.h" - -DumpAnalysis::~DumpAnalysis() { - if (dump_file_view_ != NULL) { - EXPECT_TRUE(::UnmapViewOfFile(dump_file_view_)); - ::CloseHandle(dump_file_mapping_); - dump_file_mapping_ = NULL; - } - - if (dump_file_handle_ != NULL) { - ::CloseHandle(dump_file_handle_); - dump_file_handle_ = NULL; - } -} - -void DumpAnalysis::EnsureDumpMapped() { - if (dump_file_view_ == NULL) { - dump_file_handle_ = ::CreateFile(dump_file_.c_str(), - GENERIC_READ, - 0, - NULL, - OPEN_EXISTING, - 0, - NULL); - ASSERT_TRUE(dump_file_handle_ != NULL); - ASSERT_TRUE(dump_file_mapping_ == NULL); - - dump_file_mapping_ = ::CreateFileMapping(dump_file_handle_, - NULL, - PAGE_READONLY, - 0, - 0, - NULL); - ASSERT_TRUE(dump_file_mapping_ != NULL); - - dump_file_view_ = ::MapViewOfFile(dump_file_mapping_, - FILE_MAP_READ, - 0, - 0, - 0); - ASSERT_TRUE(dump_file_view_ != NULL); - } -} - -bool DumpAnalysis::HasTebs() const { - MINIDUMP_THREAD_LIST* thread_list = NULL; - size_t thread_list_size = GetStream(ThreadListStream, &thread_list); - - if (thread_list_size > 0 && thread_list != NULL) { - for (ULONG i = 0; i < thread_list->NumberOfThreads; ++i) { - if (!HasMemory(thread_list->Threads[i].Teb)) - return false; - } - - return true; - } - - // No thread list, no TEB info. - return false; -} - -bool DumpAnalysis::HasPeb() const { - MINIDUMP_THREAD_LIST* thread_list = NULL; - size_t thread_list_size = GetStream(ThreadListStream, &thread_list); - - if (thread_list_size > 0 && thread_list != NULL && - thread_list->NumberOfThreads > 0) { - FakeTEB* teb = NULL; - if (!HasMemory(thread_list->Threads[0].Teb, &teb)) - return false; - - return HasMemory(teb->peb); - } - - return false; -} - -bool DumpAnalysis::HasStream(ULONG stream_number) const { - void* stream = NULL; - size_t stream_size = GetStreamImpl(stream_number, &stream); - return stream_size > 0 && stream != NULL; -} - -size_t DumpAnalysis::GetStreamImpl(ULONG stream_number, void** stream) const { - MINIDUMP_DIRECTORY* directory = NULL; - ULONG memory_list_size = 0; - BOOL ret = ::MiniDumpReadDumpStream(dump_file_view_, - stream_number, - &directory, - stream, - &memory_list_size); - - return ret ? memory_list_size : 0; -} - -bool DumpAnalysis::HasMemoryImpl(const void *addr_in, size_t structuresize, - void **structure) const { - uintptr_t address = reinterpret_cast<uintptr_t>(addr_in); - MINIDUMP_MEMORY_LIST* memory_list = NULL; - size_t memory_list_size = GetStream(MemoryListStream, &memory_list); - if (memory_list_size > 0 && memory_list != NULL) { - for (ULONG i = 0; i < memory_list->NumberOfMemoryRanges; ++i) { - MINIDUMP_MEMORY_DESCRIPTOR& descr = memory_list->MemoryRanges[i]; - const uintptr_t range_start = - static_cast<uintptr_t>(descr.StartOfMemoryRange); - uintptr_t range_end = range_start + descr.Memory.DataSize; - - if (address >= range_start && - address + structuresize < range_end) { - // The start address falls in the range, and the end address is - // in bounds, return a pointer to the structure if requested. - if (structure != NULL) - *structure = RVA_TO_ADDR(dump_file_view_, descr.Memory.Rva); - - return true; - } - } - } - - // We didn't find the range in a MINIDUMP_MEMORY_LIST, so maybe this - // is a full dump using MINIDUMP_MEMORY64_LIST with all the memory at the - // end of the dump file. - MINIDUMP_MEMORY64_LIST* memory64_list = NULL; - memory_list_size = GetStream(Memory64ListStream, &memory64_list); - if (memory_list_size > 0 && memory64_list != NULL) { - // Keep track of where the current descriptor maps to. - RVA64 curr_rva = memory64_list->BaseRva; - for (ULONG i = 0; i < memory64_list->NumberOfMemoryRanges; ++i) { - MINIDUMP_MEMORY_DESCRIPTOR64& descr = memory64_list->MemoryRanges[i]; - uintptr_t range_start = - static_cast<uintptr_t>(descr.StartOfMemoryRange); - uintptr_t range_end = range_start + static_cast<size_t>(descr.DataSize); - - if (address >= range_start && - address + structuresize < range_end) { - // The start address falls in the range, and the end address is - // in bounds, return a pointer to the structure if requested. - if (structure != NULL) - *structure = RVA_TO_ADDR(dump_file_view_, curr_rva); - - return true; - } - - // Advance the current RVA. - curr_rva += descr.DataSize; - } - } - - return false; -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/dump_analysis.h b/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/dump_analysis.h deleted file mode 100644 index 6cef48d81..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/dump_analysis.h +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) 2010, 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_DUMP_ANALYSIS_H_ -#define CLIENT_WINDOWS_UNITTESTS_DUMP_ANALYSIS_H_ - -#include "client/windows/crash_generation/minidump_generator.h" - -// Convenience to get to the PEB pointer in a TEB. -struct FakeTEB { - char dummy[0x30]; - void* peb; -}; - -class DumpAnalysis { - public: - explicit DumpAnalysis(const std::wstring& file_path) - : dump_file_(file_path), dump_file_view_(NULL), dump_file_mapping_(NULL), - dump_file_handle_(NULL) { - EnsureDumpMapped(); - } - ~DumpAnalysis(); - - bool HasStream(ULONG stream_number) const; - - // This is template to keep type safety in the front, but we end up casting - // to void** inside the implementation to pass the pointer to Win32. So - // casting here is considered safe. - template <class StreamType> - size_t GetStream(ULONG stream_number, StreamType** stream) const { - return GetStreamImpl(stream_number, reinterpret_cast<void**>(stream)); - } - - bool HasTebs() const; - bool HasPeb() const; - bool HasMemory(ULONG64 address) const { - return HasMemory<BYTE>(address, NULL); - } - - bool HasMemory(const void* address) const { - return HasMemory<BYTE>(address, NULL); - } - - template <class StructureType> - bool HasMemory(ULONG64 address, StructureType** structure = NULL) const { - // We can't cope with 64 bit addresses for now. - if (address > 0xFFFFFFFFUL) - return false; - - return HasMemory(reinterpret_cast<void*>(address), structure); - } - - template <class StructureType> - bool HasMemory(const void* addr_in, StructureType** structure = NULL) const { - return HasMemoryImpl(addr_in, sizeof(StructureType), - reinterpret_cast<void**>(structure)); - } - - protected: - void EnsureDumpMapped(); - - HANDLE dump_file_mapping_; - HANDLE dump_file_handle_; - void* dump_file_view_; - std::wstring dump_file_; - - private: - // This is the implementation of GetStream<>. - size_t GetStreamImpl(ULONG stream_number, void** stream) const; - - // This is the implementation of HasMemory<>. - bool HasMemoryImpl(const void* addr_in, size_t pointersize, - void** structure) const; -}; - -#endif // CLIENT_WINDOWS_UNITTESTS_DUMP_ANALYSIS_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_death_test.cc b/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_death_test.cc deleted file mode 100644 index 079ca3d6f..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_death_test.cc +++ /dev/null @@ -1,582 +0,0 @@ -// Copyright 2009, 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 <dbghelp.h> -#include <strsafe.h> -#include <objbase.h> -#include <shellapi.h> - -#include <string> - -#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 { - -using std::wstring; -using namespace google_breakpad; - -const wchar_t kPipeName[] = L"\\\\.\\pipe\\BreakpadCrashTest\\TestCaseServer"; -const char kSuccessIndicator[] = "success"; -const char kFailureIndicator[] = "failure"; - -// Utility function to test for a path's existence. -BOOL DoesPathExist(const TCHAR *path_name); - -enum OutOfProcGuarantee { - OUT_OF_PROC_GUARANTEED, - OUT_OF_PROC_BEST_EFFORT, -}; - -class ExceptionHandlerDeathTest : public ::testing::Test { - protected: - // Member variable for each test that they can use - // for temporary storage. - TCHAR temp_path_[MAX_PATH]; - // Actually constructs a temp path name. - virtual void SetUp(); - // A helper method that tests can use to crash. - void DoCrashAccessViolation(const OutOfProcGuarantee out_of_proc_guarantee); - void DoCrashPureVirtualCall(); -}; - -void ExceptionHandlerDeathTest::SetUp() { - const ::testing::TestInfo* const test_info = - ::testing::UnitTest::GetInstance()->current_test_info(); - TCHAR temp_path[MAX_PATH] = { '\0' }; - TCHAR test_name_wide[MAX_PATH] = { '\0' }; - // We want the temporary directory to be what the OS returns - // to us, + the test case name. - GetTempPath(MAX_PATH, temp_path); - // The test case name is exposed as a c-style string, - // convert it to a wchar_t string. - int dwRet = MultiByteToWideChar(CP_ACP, 0, test_info->name(), - strlen(test_info->name()), - test_name_wide, - MAX_PATH); - if (!dwRet) { - assert(false); - } - StringCchPrintfW(temp_path_, MAX_PATH, L"%s%s", temp_path, test_name_wide); - CreateDirectory(temp_path_, NULL); -} - -BOOL DoesPathExist(const TCHAR *path_name) { - DWORD flags = GetFileAttributes(path_name); - if (flags == INVALID_FILE_ATTRIBUTES) { - return FALSE; - } - return TRUE; -} - -bool MinidumpWrittenCallback(const wchar_t* dump_path, - const wchar_t* minidump_id, - void* context, - EXCEPTION_POINTERS* exinfo, - MDRawAssertionInfo* assertion, - bool succeeded) { - if (succeeded && DoesPathExist(dump_path)) { - fprintf(stderr, kSuccessIndicator); - } else { - fprintf(stderr, kFailureIndicator); - } - // If we don't flush, the output doesn't get sent before - // this process dies. - fflush(stderr); - return succeeded; -} - -TEST_F(ExceptionHandlerDeathTest, InProcTest) { - // For the in-proc test, we just need to instantiate an exception - // handler in in-proc mode, and crash. Since the entire test is - // reexecuted in the child process, we don't have to worry about - // the semantics of the exception handler being inherited/not - // inherited across CreateProcess(). - ASSERT_TRUE(DoesPathExist(temp_path_)); - scoped_ptr<google_breakpad::ExceptionHandler> exc( - 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); -} - -static bool gDumpCallbackCalled = false; - -void clientDumpCallback(void *dump_context, - const google_breakpad::ClientInfo *client_info, - const std::wstring *dump_path) { - gDumpCallbackCalled = true; -} - -void ExceptionHandlerDeathTest::DoCrashAccessViolation( - const OutOfProcGuarantee out_of_proc_guarantee) { - scoped_ptr<google_breakpad::ExceptionHandler> exc; - - if (out_of_proc_guarantee == OUT_OF_PROC_GUARANTEED) { - google_breakpad::CrashGenerationClient *client = - new google_breakpad::CrashGenerationClient(kPipeName, - MiniDumpNormal, - NULL); // custom_info - ASSERT_TRUE(client->Register()); - exc.reset(new google_breakpad::ExceptionHandler( - temp_path_, - NULL, // filter - NULL, // callback - NULL, // callback_context - google_breakpad::ExceptionHandler::HANDLER_ALL, - client)); - } else { - ASSERT_TRUE(out_of_proc_guarantee == OUT_OF_PROC_BEST_EFFORT); - exc.reset(new google_breakpad::ExceptionHandler( - temp_path_, - NULL, // filter - NULL, // callback - NULL, // callback_context - google_breakpad::ExceptionHandler::HANDLER_ALL, - MiniDumpNormal, - kPipeName, - NULL)); // custom_info - } - - // 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. - ASSERT_TRUE(exc->IsOutOfProcess()); - int *i = NULL; - printf("%d\n", (*i)++); -} - -TEST_F(ExceptionHandlerDeathTest, OutOfProcTest) { - // We can take advantage of a detail of google test here to save some - // complexity in testing: when you do a death test, it actually forks. - // So we can make the main test harness the crash generation server, - // and call ASSERT_DEATH on a NULL dereference, it to expecting test - // the out of process scenario, since it's happening in a different - // process! This is different from the above because, above, we pass - // a NULL pipe name, and we also don't start a crash generation server. - - ASSERT_TRUE(DoesPathExist(temp_path_)); - std::wstring dump_path(temp_path_); - google_breakpad::CrashGenerationServer server( - kPipeName, NULL, NULL, NULL, &clientDumpCallback, NULL, NULL, NULL, NULL, - NULL, true, &dump_path); - - // This HAS to be EXPECT_, because when this test case is executed in the - // child process, the server registration will fail due to the named pipe - // being the same. - EXPECT_TRUE(server.Start()); - gDumpCallbackCalled = false; - ASSERT_DEATH(this->DoCrashAccessViolation(OUT_OF_PROC_BEST_EFFORT), ""); - EXPECT_TRUE(gDumpCallbackCalled); -} - -TEST_F(ExceptionHandlerDeathTest, OutOfProcGuaranteedTest) { - // This is similar to the previous test (OutOfProcTest). The only difference - // is that in this test, the crash generation client is created and registered - // with the crash generation server outside of the ExceptionHandler - // constructor which allows breakpad users to opt out of the default - // in-process dump generation when the registration with the crash generation - // server fails. - - ASSERT_TRUE(DoesPathExist(temp_path_)); - std::wstring dump_path(temp_path_); - google_breakpad::CrashGenerationServer server( - kPipeName, NULL, NULL, NULL, &clientDumpCallback, NULL, NULL, NULL, NULL, - NULL, true, &dump_path); - - // This HAS to be EXPECT_, because when this test case is executed in the - // child process, the server registration will fail due to the named pipe - // being the same. - EXPECT_TRUE(server.Start()); - gDumpCallbackCalled = false; - ASSERT_DEATH(this->DoCrashAccessViolation(OUT_OF_PROC_GUARANTEED), ""); - EXPECT_TRUE(gDumpCallbackCalled); -} - -TEST_F(ExceptionHandlerDeathTest, InvalidParameterTest) { - using google_breakpad::ExceptionHandler; - - ASSERT_TRUE(DoesPathExist(temp_path_)); - ExceptionHandler handler(temp_path_, NULL, NULL, NULL, - ExceptionHandler::HANDLER_INVALID_PARAMETER); - - // Disable the message box for assertions - _CrtSetReportMode(_CRT_ASSERT, 0); - - // Call with a bad argument. The invalid parameter will be swallowed - // and a dump will be generated, the process will exit(0). - ASSERT_EXIT(printf(NULL), ::testing::ExitedWithCode(0), ""); -} - - -struct PureVirtualCallBase { - PureVirtualCallBase() { - // We have to reinterpret so the linker doesn't get confused because the - // method isn't defined. - reinterpret_cast<PureVirtualCallBase*>(this)->PureFunction(); - } - virtual ~PureVirtualCallBase() {} - virtual void PureFunction() const = 0; -}; -struct PureVirtualCall : public PureVirtualCallBase { - PureVirtualCall() { PureFunction(); } - virtual void PureFunction() const {} -}; - -void ExceptionHandlerDeathTest::DoCrashPureVirtualCall() { - PureVirtualCall instance; -} - -TEST_F(ExceptionHandlerDeathTest, PureVirtualCallTest) { - using google_breakpad::ExceptionHandler; - - ASSERT_TRUE(DoesPathExist(temp_path_)); - ExceptionHandler handler(temp_path_, NULL, NULL, NULL, - ExceptionHandler::HANDLER_PURECALL); - - // Disable the message box for assertions - _CrtSetReportMode(_CRT_ASSERT, 0); - - // Calls a pure virtual function. - EXPECT_EXIT(DoCrashPureVirtualCall(), ::testing::ExitedWithCode(0), ""); -} - -wstring find_minidump_in_directory(const wstring &directory) { - wstring search_path = directory + L"\\*"; - WIN32_FIND_DATA find_data; - HANDLE find_handle = FindFirstFileW(search_path.c_str(), &find_data); - if (find_handle == INVALID_HANDLE_VALUE) - return wstring(); - - wstring filename; - do { - const wchar_t extension[] = L".dmp"; - const int extension_length = sizeof(extension) / sizeof(extension[0]) - 1; - const int filename_length = wcslen(find_data.cFileName); - if (filename_length > extension_length && - wcsncmp(extension, - find_data.cFileName + filename_length - extension_length, - extension_length) == 0) { - filename = directory + L"\\" + find_data.cFileName; - break; - } - } while (FindNextFile(find_handle, &find_data)); - FindClose(find_handle); - return filename; -} - -#ifndef ADDRESS_SANITIZER - -TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemory) { - ASSERT_TRUE(DoesPathExist(temp_path_)); - scoped_ptr<google_breakpad::ExceptionHandler> exc( - new google_breakpad::ExceptionHandler( - temp_path_, - NULL, - NULL, - NULL, - google_breakpad::ExceptionHandler::HANDLER_ALL)); - - // Disable GTest SEH handler - testing::DisableExceptionHandlerInScope disable_exception_handler; - - // Get some executable memory. - const uint32_t kMemorySize = 256; // bytes - const int kOffset = kMemorySize / 2; - // This crashes with SIGILL on x86/x86-64/arm. - const unsigned char instructions[] = { 0xff, 0xff, 0xff, 0xff }; - char* memory = reinterpret_cast<char*>(VirtualAlloc(NULL, - kMemorySize, - MEM_COMMIT | MEM_RESERVE, - PAGE_EXECUTE_READWRITE)); - ASSERT_TRUE(memory); - - // Write some instructions that will crash. Put them - // in the middle of the block of memory, because the - // minidump should contain 128 bytes on either side of the - // instruction pointer. - memcpy(memory + kOffset, instructions, sizeof(instructions)); - - // Now execute the instructions, which should crash. - typedef void (*void_function)(void); - void_function memory_function = - reinterpret_cast<void_function>(memory + kOffset); - ASSERT_DEATH(memory_function(), ""); - - // free the memory. - VirtualFree(memory, 0, MEM_RELEASE); - - // Verify that the resulting minidump contains the memory around the IP - wstring minidump_filename_wide = find_minidump_in_directory(temp_path_); - ASSERT_FALSE(minidump_filename_wide.empty()); - string minidump_filename; - ASSERT_TRUE(WindowsStringUtils::safe_wcstombs(minidump_filename_wide, - &minidump_filename)); - - // Read the minidump. Locate the exception record and the - // memory list, and then ensure that there is a memory region - // in the memory list that covers the instruction pointer from - // the exception record. - { - Minidump minidump(minidump_filename); - ASSERT_TRUE(minidump.Read()); - - MinidumpException* exception = minidump.GetException(); - MinidumpMemoryList* memory_list = minidump.GetMemoryList(); - ASSERT_TRUE(exception); - ASSERT_TRUE(memory_list); - ASSERT_LT((unsigned)0, memory_list->region_count()); - - MinidumpContext* context = exception->GetContext(); - ASSERT_TRUE(context); - - uint64_t instruction_pointer; - ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer)); - - MinidumpMemoryRegion* region = - memory_list->GetMemoryRegionForAddress(instruction_pointer); - ASSERT_TRUE(region); - - EXPECT_EQ(kMemorySize, region->GetSize()); - const uint8_t* bytes = region->GetMemory(); - ASSERT_TRUE(bytes); - - uint8_t prefix_bytes[kOffset]; - uint8_t suffix_bytes[kMemorySize - kOffset - sizeof(instructions)]; - memset(prefix_bytes, 0, sizeof(prefix_bytes)); - memset(suffix_bytes, 0, sizeof(suffix_bytes)); - EXPECT_EQ(0, memcmp(bytes, prefix_bytes, sizeof(prefix_bytes))); - EXPECT_EQ(0, memcmp(bytes + kOffset, instructions, sizeof(instructions))); - EXPECT_EQ(0, memcmp(bytes + kOffset + sizeof(instructions), - suffix_bytes, sizeof(suffix_bytes))); - } - - DeleteFileW(minidump_filename_wide.c_str()); -} - -TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemoryMinBound) { - ASSERT_TRUE(DoesPathExist(temp_path_)); - scoped_ptr<google_breakpad::ExceptionHandler> exc( - new google_breakpad::ExceptionHandler( - 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. - - const uint32_t kMemorySize = 256; // bytes - const DWORD kPageSize = sSysInfo.dwPageSize; - const int kOffset = 0; - // This crashes with SIGILL on x86/x86-64/arm. - const unsigned char instructions[] = { 0xff, 0xff, 0xff, 0xff }; - // Get some executable memory. Specifically, reserve two pages, - // but only commit the second. - char* all_memory = reinterpret_cast<char*>(VirtualAlloc(NULL, - kPageSize * 2, - MEM_RESERVE, - PAGE_NOACCESS)); - ASSERT_TRUE(all_memory); - char* memory = all_memory + kPageSize; - ASSERT_TRUE(VirtualAlloc(memory, kPageSize, - MEM_COMMIT, PAGE_EXECUTE_READWRITE)); - - // Write some instructions that will crash. Put them - // in the middle of the block of memory, because the - // minidump should contain 128 bytes on either side of the - // instruction pointer. - memcpy(memory + kOffset, instructions, sizeof(instructions)); - - // Now execute the instructions, which should crash. - typedef void (*void_function)(void); - void_function memory_function = - reinterpret_cast<void_function>(memory + kOffset); - ASSERT_DEATH(memory_function(), ""); - - // free the memory. - VirtualFree(memory, 0, MEM_RELEASE); - - // Verify that the resulting minidump contains the memory around the IP - wstring minidump_filename_wide = find_minidump_in_directory(temp_path_); - ASSERT_FALSE(minidump_filename_wide.empty()); - string minidump_filename; - ASSERT_TRUE(WindowsStringUtils::safe_wcstombs(minidump_filename_wide, - &minidump_filename)); - - // Read the minidump. Locate the exception record and the - // memory list, and then ensure that there is a memory region - // in the memory list that covers the instruction pointer from - // the exception record. - { - Minidump minidump(minidump_filename); - ASSERT_TRUE(minidump.Read()); - - MinidumpException* exception = minidump.GetException(); - MinidumpMemoryList* memory_list = minidump.GetMemoryList(); - ASSERT_TRUE(exception); - ASSERT_TRUE(memory_list); - ASSERT_LT((unsigned)0, memory_list->region_count()); - - MinidumpContext* context = exception->GetContext(); - ASSERT_TRUE(context); - - uint64_t instruction_pointer; - ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer)); - - MinidumpMemoryRegion* region = - memory_list->GetMemoryRegionForAddress(instruction_pointer); - ASSERT_TRUE(region); - - EXPECT_EQ(kMemorySize / 2, region->GetSize()); - const uint8_t* bytes = region->GetMemory(); - ASSERT_TRUE(bytes); - - uint8_t suffix_bytes[kMemorySize / 2 - sizeof(instructions)]; - memset(suffix_bytes, 0, sizeof(suffix_bytes)); - EXPECT_TRUE(memcmp(bytes + kOffset, - instructions, sizeof(instructions)) == 0); - EXPECT_TRUE(memcmp(bytes + kOffset + sizeof(instructions), - suffix_bytes, sizeof(suffix_bytes)) == 0); - } - - DeleteFileW(minidump_filename_wide.c_str()); -} - -TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemoryMaxBound) { - ASSERT_TRUE(DoesPathExist(temp_path_)); - scoped_ptr<google_breakpad::ExceptionHandler> exc( - new google_breakpad::ExceptionHandler( - 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. - - const DWORD kPageSize = sSysInfo.dwPageSize; - // This crashes with SIGILL on x86/x86-64/arm. - const unsigned char instructions[] = { 0xff, 0xff, 0xff, 0xff }; - const int kOffset = kPageSize - sizeof(instructions); - // Get some executable memory. Specifically, reserve two pages, - // but only commit the first. - char* memory = reinterpret_cast<char*>(VirtualAlloc(NULL, - kPageSize * 2, - MEM_RESERVE, - PAGE_NOACCESS)); - ASSERT_TRUE(memory); - ASSERT_TRUE(VirtualAlloc(memory, kPageSize, - MEM_COMMIT, PAGE_EXECUTE_READWRITE)); - - // Write some instructions that will crash. - memcpy(memory + kOffset, instructions, sizeof(instructions)); - - // Now execute the instructions, which should crash. - typedef void (*void_function)(void); - void_function memory_function = - reinterpret_cast<void_function>(memory + kOffset); - ASSERT_DEATH(memory_function(), ""); - - // free the memory. - VirtualFree(memory, 0, MEM_RELEASE); - - // Verify that the resulting minidump contains the memory around the IP - wstring minidump_filename_wide = find_minidump_in_directory(temp_path_); - ASSERT_FALSE(minidump_filename_wide.empty()); - string minidump_filename; - ASSERT_TRUE(WindowsStringUtils::safe_wcstombs(minidump_filename_wide, - &minidump_filename)); - - // Read the minidump. Locate the exception record and the - // memory list, and then ensure that there is a memory region - // in the memory list that covers the instruction pointer from - // the exception record. - { - Minidump minidump(minidump_filename); - ASSERT_TRUE(minidump.Read()); - - MinidumpException* exception = minidump.GetException(); - MinidumpMemoryList* memory_list = minidump.GetMemoryList(); - ASSERT_TRUE(exception); - ASSERT_TRUE(memory_list); - ASSERT_LT((unsigned)0, memory_list->region_count()); - - MinidumpContext* context = exception->GetContext(); - ASSERT_TRUE(context); - - uint64_t instruction_pointer; - ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer)); - - MinidumpMemoryRegion* region = - memory_list->GetMemoryRegionForAddress(instruction_pointer); - ASSERT_TRUE(region); - - const size_t kPrefixSize = 128; // bytes - EXPECT_EQ(kPrefixSize + sizeof(instructions), region->GetSize()); - const uint8_t* bytes = region->GetMemory(); - ASSERT_TRUE(bytes); - - uint8_t prefix_bytes[kPrefixSize]; - memset(prefix_bytes, 0, sizeof(prefix_bytes)); - EXPECT_EQ(0, memcmp(bytes, prefix_bytes, sizeof(prefix_bytes))); - EXPECT_EQ(0, memcmp(bytes + kPrefixSize, - instructions, sizeof(instructions))); - } - - DeleteFileW(minidump_filename_wide.c_str()); -} - -#endif // !ADDRESS_SANITIZER - -} // namespace diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_nesting_test.cc b/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_nesting_test.cc deleted file mode 100644 index 3ae1d7cd0..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_nesting_test.cc +++ /dev/null @@ -1,327 +0,0 @@ -// 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/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_test.cc b/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_test.cc deleted file mode 100644 index 55275323e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_test.cc +++ /dev/null @@ -1,501 +0,0 @@ -// Copyright 2009, 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 "client/windows/unittests/exception_handler_test.h" - -#include <windows.h> -#include <dbghelp.h> -#include <strsafe.h> -#include <objbase.h> -#include <shellapi.h> - -#include <string> - -#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 { - -using std::wstring; -using namespace google_breakpad; - -const wchar_t kPipeName[] = L"\\\\.\\pipe\\BreakpadCrashTest\\TestCaseServer"; -const char kSuccessIndicator[] = "success"; -const char kFailureIndicator[] = "failure"; - -const MINIDUMP_TYPE kFullDumpType = static_cast<MINIDUMP_TYPE>( - MiniDumpWithFullMemory | // Full memory from process. - MiniDumpWithProcessThreadData | // Get PEB and TEB. - MiniDumpWithHandleData); // Get all handle information. - -class ExceptionHandlerTest : public ::testing::Test { - protected: - // Member variable for each test that they can use - // for temporary storage. - TCHAR temp_path_[MAX_PATH]; - - // Actually constructs a temp path name. - virtual void SetUp(); - - // Deletes temporary files. - virtual void TearDown(); - - void DoCrashInvalidParameter(); - void DoCrashPureVirtualCall(); - - // Utility function to test for a path's existence. - static BOOL DoesPathExist(const TCHAR *path_name); - - // Client callback. - static void ClientDumpCallback( - void *dump_context, - const google_breakpad::ClientInfo *client_info, - const std::wstring *dump_path); - - static bool DumpCallback(const wchar_t* dump_path, - const wchar_t* minidump_id, - void* context, - EXCEPTION_POINTERS* exinfo, - MDRawAssertionInfo* assertion, - bool succeeded); - - static std::wstring dump_file; - static std::wstring full_dump_file; -}; - -std::wstring ExceptionHandlerTest::dump_file; -std::wstring ExceptionHandlerTest::full_dump_file; - -void ExceptionHandlerTest::SetUp() { - const ::testing::TestInfo* const test_info = - ::testing::UnitTest::GetInstance()->current_test_info(); - TCHAR temp_path[MAX_PATH] = { '\0' }; - TCHAR test_name_wide[MAX_PATH] = { '\0' }; - // We want the temporary directory to be what the OS returns - // to us, + the test case name. - GetTempPath(MAX_PATH, temp_path); - // THe test case name is exposed to use as a c-style string, - // But we might be working in UNICODE here on Windows. - int dwRet = MultiByteToWideChar(CP_ACP, 0, test_info->name(), - strlen(test_info->name()), - test_name_wide, - MAX_PATH); - if (!dwRet) { - assert(false); - } - StringCchPrintfW(temp_path_, MAX_PATH, L"%s%s", temp_path, test_name_wide); - CreateDirectory(temp_path_, NULL); -} - -void ExceptionHandlerTest::TearDown() { - if (!dump_file.empty()) { - ::DeleteFile(dump_file.c_str()); - dump_file = L""; - } - if (!full_dump_file.empty()) { - ::DeleteFile(full_dump_file.c_str()); - full_dump_file = L""; - } -} - -BOOL ExceptionHandlerTest::DoesPathExist(const TCHAR *path_name) { - DWORD flags = GetFileAttributes(path_name); - if (flags == INVALID_FILE_ATTRIBUTES) { - return FALSE; - } - return TRUE; -} - -// static -void ExceptionHandlerTest::ClientDumpCallback( - void *dump_context, - const google_breakpad::ClientInfo *client_info, - const wstring *dump_path) { - dump_file = *dump_path; - // Create the full dump file name from the dump path. - full_dump_file = dump_file.substr(0, dump_file.length() - 4) + L"-full.dmp"; -} - -// static -bool ExceptionHandlerTest::DumpCallback(const wchar_t* dump_path, - const wchar_t* minidump_id, - void* context, - EXCEPTION_POINTERS* exinfo, - MDRawAssertionInfo* assertion, - bool succeeded) { - dump_file = dump_path; - dump_file += L"\\"; - dump_file += minidump_id; - dump_file += L".dmp"; - return succeeded; -} - -void ExceptionHandlerTest::DoCrashInvalidParameter() { - google_breakpad::ExceptionHandler *exc = - new google_breakpad::ExceptionHandler( - temp_path_, NULL, NULL, NULL, - google_breakpad::ExceptionHandler::HANDLER_INVALID_PARAMETER, - kFullDumpType, kPipeName, NULL); - - // Disable the message box for assertions - _CrtSetReportMode(_CRT_ASSERT, 0); - - // 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. - ASSERT_TRUE(exc->IsOutOfProcess()); - printf(NULL); -} - - -struct PureVirtualCallBase { - PureVirtualCallBase() { - // We have to reinterpret so the linker doesn't get confused because the - // method isn't defined. - reinterpret_cast<PureVirtualCallBase*>(this)->PureFunction(); - } - virtual ~PureVirtualCallBase() {} - virtual void PureFunction() const = 0; -}; -struct PureVirtualCall : public PureVirtualCallBase { - PureVirtualCall() { PureFunction(); } - virtual void PureFunction() const {} -}; - -void ExceptionHandlerTest::DoCrashPureVirtualCall() { - google_breakpad::ExceptionHandler *exc = - new google_breakpad::ExceptionHandler( - temp_path_, NULL, NULL, NULL, - google_breakpad::ExceptionHandler::HANDLER_PURECALL, - kFullDumpType, kPipeName, NULL); - - // Disable the message box for assertions - _CrtSetReportMode(_CRT_ASSERT, 0); - - // 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. - ASSERT_TRUE(exc->IsOutOfProcess()); - - // Create a new frame to ensure PureVirtualCall is not optimized to some - // other line in this function. - { - PureVirtualCall instance; - } -} - -// This test validates that the minidump is written correctly. -TEST_F(ExceptionHandlerTest, InvalidParameterMiniDumpTest) { - ASSERT_TRUE(DoesPathExist(temp_path_)); - - // Call with a bad argument - ASSERT_TRUE(DoesPathExist(temp_path_)); - wstring dump_path(temp_path_); - google_breakpad::CrashGenerationServer server( - kPipeName, NULL, NULL, NULL, ClientDumpCallback, NULL, NULL, NULL, NULL, - NULL, true, &dump_path); - - ASSERT_TRUE(dump_file.empty() && full_dump_file.empty()); - - // This HAS to be EXPECT_, because when this test case is executed in the - // child process, the server registration will fail due to the named pipe - // being the same. - EXPECT_TRUE(server.Start()); - EXPECT_EXIT(DoCrashInvalidParameter(), ::testing::ExitedWithCode(0), ""); - ASSERT_TRUE(!dump_file.empty() && !full_dump_file.empty()); - ASSERT_TRUE(DoesPathExist(dump_file.c_str())); - - // Verify the dump for infos. - DumpAnalysis mini(dump_file); - DumpAnalysis full(full_dump_file); - - // The dump should have all of these streams. - EXPECT_TRUE(mini.HasStream(ThreadListStream)); - EXPECT_TRUE(full.HasStream(ThreadListStream)); - EXPECT_TRUE(mini.HasStream(ModuleListStream)); - EXPECT_TRUE(full.HasStream(ModuleListStream)); - EXPECT_TRUE(mini.HasStream(ExceptionStream)); - EXPECT_TRUE(full.HasStream(ExceptionStream)); - EXPECT_TRUE(mini.HasStream(SystemInfoStream)); - EXPECT_TRUE(full.HasStream(SystemInfoStream)); - EXPECT_TRUE(mini.HasStream(MiscInfoStream)); - EXPECT_TRUE(full.HasStream(MiscInfoStream)); - EXPECT_TRUE(mini.HasStream(HandleDataStream)); - EXPECT_TRUE(full.HasStream(HandleDataStream)); - - // We expect PEB and TEBs in this dump. - EXPECT_TRUE(mini.HasTebs() || full.HasTebs()); - EXPECT_TRUE(mini.HasPeb() || full.HasPeb()); - - // Minidump should have a memory listing, but no 64-bit memory. - EXPECT_TRUE(mini.HasStream(MemoryListStream)); - EXPECT_FALSE(mini.HasStream(Memory64ListStream)); - - EXPECT_FALSE(full.HasStream(MemoryListStream)); - EXPECT_TRUE(full.HasStream(Memory64ListStream)); - - // This is the only place we don't use OR because we want both not - // to have the streams. - EXPECT_FALSE(mini.HasStream(ThreadExListStream)); - EXPECT_FALSE(full.HasStream(ThreadExListStream)); - EXPECT_FALSE(mini.HasStream(CommentStreamA)); - EXPECT_FALSE(full.HasStream(CommentStreamA)); - EXPECT_FALSE(mini.HasStream(CommentStreamW)); - EXPECT_FALSE(full.HasStream(CommentStreamW)); - EXPECT_FALSE(mini.HasStream(FunctionTableStream)); - EXPECT_FALSE(full.HasStream(FunctionTableStream)); - EXPECT_FALSE(mini.HasStream(MemoryInfoListStream)); - EXPECT_FALSE(full.HasStream(MemoryInfoListStream)); - EXPECT_FALSE(mini.HasStream(ThreadInfoListStream)); - EXPECT_FALSE(full.HasStream(ThreadInfoListStream)); - EXPECT_FALSE(mini.HasStream(HandleOperationListStream)); - EXPECT_FALSE(full.HasStream(HandleOperationListStream)); - EXPECT_FALSE(mini.HasStream(TokenStream)); - EXPECT_FALSE(full.HasStream(TokenStream)); -} - - -// This test validates that the minidump is written correctly. -TEST_F(ExceptionHandlerTest, PureVirtualCallMiniDumpTest) { - ASSERT_TRUE(DoesPathExist(temp_path_)); - - // Call with a bad argument - ASSERT_TRUE(DoesPathExist(temp_path_)); - wstring dump_path(temp_path_); - google_breakpad::CrashGenerationServer server( - kPipeName, NULL, NULL, NULL, ClientDumpCallback, NULL, NULL, NULL, NULL, - NULL, true, &dump_path); - - ASSERT_TRUE(dump_file.empty() && full_dump_file.empty()); - - // This HAS to be EXPECT_, because when this test case is executed in the - // child process, the server registration will fail due to the named pipe - // being the same. - EXPECT_TRUE(server.Start()); - EXPECT_EXIT(DoCrashPureVirtualCall(), ::testing::ExitedWithCode(0), ""); - ASSERT_TRUE(!dump_file.empty() && !full_dump_file.empty()); - ASSERT_TRUE(DoesPathExist(dump_file.c_str())); - - // Verify the dump for infos. - DumpAnalysis mini(dump_file); - DumpAnalysis full(full_dump_file); - - // The dump should have all of these streams. - EXPECT_TRUE(mini.HasStream(ThreadListStream)); - EXPECT_TRUE(full.HasStream(ThreadListStream)); - EXPECT_TRUE(mini.HasStream(ModuleListStream)); - EXPECT_TRUE(full.HasStream(ModuleListStream)); - EXPECT_TRUE(mini.HasStream(ExceptionStream)); - EXPECT_TRUE(full.HasStream(ExceptionStream)); - EXPECT_TRUE(mini.HasStream(SystemInfoStream)); - EXPECT_TRUE(full.HasStream(SystemInfoStream)); - EXPECT_TRUE(mini.HasStream(MiscInfoStream)); - EXPECT_TRUE(full.HasStream(MiscInfoStream)); - EXPECT_TRUE(mini.HasStream(HandleDataStream)); - EXPECT_TRUE(full.HasStream(HandleDataStream)); - - // We expect PEB and TEBs in this dump. - EXPECT_TRUE(mini.HasTebs() || full.HasTebs()); - EXPECT_TRUE(mini.HasPeb() || full.HasPeb()); - - // Minidump should have a memory listing, but no 64-bit memory. - EXPECT_TRUE(mini.HasStream(MemoryListStream)); - EXPECT_FALSE(mini.HasStream(Memory64ListStream)); - - EXPECT_FALSE(full.HasStream(MemoryListStream)); - EXPECT_TRUE(full.HasStream(Memory64ListStream)); - - // This is the only place we don't use OR because we want both not - // to have the streams. - EXPECT_FALSE(mini.HasStream(ThreadExListStream)); - EXPECT_FALSE(full.HasStream(ThreadExListStream)); - EXPECT_FALSE(mini.HasStream(CommentStreamA)); - EXPECT_FALSE(full.HasStream(CommentStreamA)); - EXPECT_FALSE(mini.HasStream(CommentStreamW)); - EXPECT_FALSE(full.HasStream(CommentStreamW)); - EXPECT_FALSE(mini.HasStream(FunctionTableStream)); - EXPECT_FALSE(full.HasStream(FunctionTableStream)); - EXPECT_FALSE(mini.HasStream(MemoryInfoListStream)); - EXPECT_FALSE(full.HasStream(MemoryInfoListStream)); - EXPECT_FALSE(mini.HasStream(ThreadInfoListStream)); - EXPECT_FALSE(full.HasStream(ThreadInfoListStream)); - EXPECT_FALSE(mini.HasStream(HandleOperationListStream)); - EXPECT_FALSE(full.HasStream(HandleOperationListStream)); - EXPECT_FALSE(mini.HasStream(TokenStream)); - EXPECT_FALSE(full.HasStream(TokenStream)); -} - -// Test that writing a minidump produces a valid minidump containing -// some expected structures. -TEST_F(ExceptionHandlerTest, WriteMinidumpTest) { - ExceptionHandler handler(temp_path_, - NULL, - DumpCallback, - NULL, - ExceptionHandler::HANDLER_ALL); - - // Disable GTest SEH handler - testing::DisableExceptionHandlerInScope disable_exception_handler; - - ASSERT_TRUE(handler.WriteMinidump()); - ASSERT_FALSE(dump_file.empty()); - - string minidump_filename; - ASSERT_TRUE(WindowsStringUtils::safe_wcstombs(dump_file, - &minidump_filename)); - - // Read the minidump and verify some info. - Minidump minidump(minidump_filename); - ASSERT_TRUE(minidump.Read()); - // TODO(ted): more comprehensive tests... -} - -// Test that an additional memory region can be included in the minidump. -TEST_F(ExceptionHandlerTest, AdditionalMemory) { - SYSTEM_INFO si; - GetSystemInfo(&si); - const uint32_t kMemorySize = si.dwPageSize; - - // Get some heap memory. - uint8_t* memory = new uint8_t[kMemorySize]; - const uintptr_t kMemoryAddress = reinterpret_cast<uintptr_t>(memory); - ASSERT_TRUE(memory); - - // Stick some data into the memory so the contents can be verified. - for (uint32_t i = 0; i < kMemorySize; ++i) { - memory[i] = i % 255; - } - - ExceptionHandler handler(temp_path_, - NULL, - DumpCallback, - 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()); - ASSERT_FALSE(dump_file.empty()); - - string minidump_filename; - ASSERT_TRUE(WindowsStringUtils::safe_wcstombs(dump_file, - &minidump_filename)); - - // Read the minidump. Ensure that the memory region is present - Minidump minidump(minidump_filename); - ASSERT_TRUE(minidump.Read()); - - MinidumpMemoryList* dump_memory_list = minidump.GetMemoryList(); - ASSERT_TRUE(dump_memory_list); - const MinidumpMemoryRegion* region = - dump_memory_list->GetMemoryRegionForAddress(kMemoryAddress); - ASSERT_TRUE(region); - - EXPECT_EQ(kMemoryAddress, region->GetBase()); - EXPECT_EQ(kMemorySize, region->GetSize()); - - // Verify memory contents. - EXPECT_EQ(0, memcmp(region->GetMemory(), memory, kMemorySize)); - - delete[] memory; -} - -// Test that a memory region that was previously registered -// can be unregistered. -TEST_F(ExceptionHandlerTest, AdditionalMemoryRemove) { - SYSTEM_INFO si; - GetSystemInfo(&si); - const uint32_t kMemorySize = si.dwPageSize; - - // Get some heap memory. - uint8_t* memory = new uint8_t[kMemorySize]; - const uintptr_t kMemoryAddress = reinterpret_cast<uintptr_t>(memory); - ASSERT_TRUE(memory); - - // Stick some data into the memory so the contents can be verified. - for (uint32_t i = 0; i < kMemorySize; ++i) { - memory[i] = i % 255; - } - - ExceptionHandler handler(temp_path_, - NULL, - DumpCallback, - 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); - - // ...and then remove it - handler.UnregisterAppMemory(memory); - - ASSERT_TRUE(handler.WriteMinidump()); - ASSERT_FALSE(dump_file.empty()); - - string minidump_filename; - ASSERT_TRUE(WindowsStringUtils::safe_wcstombs(dump_file, - &minidump_filename)); - - // Read the minidump. Ensure that the memory region is not present. - Minidump minidump(minidump_filename); - ASSERT_TRUE(minidump.Read()); - - MinidumpMemoryList* dump_memory_list = minidump.GetMemoryList(); - ASSERT_TRUE(dump_memory_list); - const MinidumpMemoryRegion* region = - dump_memory_list->GetMemoryRegionForAddress(kMemoryAddress); - EXPECT_FALSE(region); - - delete[] memory; -} - -} // namespace diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_test.h b/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_test.h deleted file mode 100644 index ef973e539..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_test.h +++ /dev/null @@ -1,61 +0,0 @@ -// 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/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/minidump_test.cc b/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/minidump_test.cc deleted file mode 100644 index 8d2d726c4..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/minidump_test.cc +++ /dev/null @@ -1,333 +0,0 @@ -// Copyright (c) 2010, 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 <objbase.h> -#include <dbghelp.h> - -#include "client/windows/crash_generation/minidump_generator.h" -#include "client/windows/unittests/dump_analysis.h" // NOLINT - -#include "gtest/gtest.h" - -namespace { - -// Minidump with stacks, PEB, TEB, and unloaded module list. -const MINIDUMP_TYPE kSmallDumpType = static_cast<MINIDUMP_TYPE>( - MiniDumpWithProcessThreadData | // Get PEB and TEB. - MiniDumpWithUnloadedModules); // Get unloaded modules when available. - -// Minidump with all of the above, plus memory referenced from stack. -const MINIDUMP_TYPE kLargerDumpType = static_cast<MINIDUMP_TYPE>( - MiniDumpWithProcessThreadData | // Get PEB and TEB. - MiniDumpWithUnloadedModules | // Get unloaded modules when available. - MiniDumpWithIndirectlyReferencedMemory); // Get memory referenced by stack. - -// Large dump with all process memory. -const MINIDUMP_TYPE kFullDumpType = static_cast<MINIDUMP_TYPE>( - MiniDumpWithFullMemory | // Full memory from process. - MiniDumpWithProcessThreadData | // Get PEB and TEB. - MiniDumpWithHandleData | // Get all handle information. - MiniDumpWithUnloadedModules); // Get unloaded modules when available. - -class MinidumpTest: public testing::Test { - public: - MinidumpTest() { - wchar_t temp_dir_path[ MAX_PATH ] = {0}; - ::GetTempPath(MAX_PATH, temp_dir_path); - dump_path_ = temp_dir_path; - } - - virtual void SetUp() { - // Make sure URLMon isn't loaded into our process. - ASSERT_EQ(NULL, ::GetModuleHandle(L"urlmon.dll")); - - // Then load and unload it to ensure we have something to - // stock the unloaded module list with. - HMODULE urlmon = ::LoadLibrary(L"urlmon.dll"); - ASSERT_TRUE(urlmon != NULL); - ASSERT_TRUE(::FreeLibrary(urlmon)); - } - - virtual void TearDown() { - if (!dump_file_.empty()) { - ::DeleteFile(dump_file_.c_str()); - dump_file_ = L""; - } - if (!full_dump_file_.empty()) { - ::DeleteFile(full_dump_file_.c_str()); - full_dump_file_ = L""; - } - } - - bool WriteDump(ULONG flags) { - using google_breakpad::MinidumpGenerator; - - // Fake exception is access violation on write to this. - EXCEPTION_RECORD ex_record = { - STATUS_ACCESS_VIOLATION, // ExceptionCode - 0, // ExceptionFlags - NULL, // ExceptionRecord; - reinterpret_cast<void*>(0xCAFEBABE), // ExceptionAddress; - 2, // NumberParameters; - { EXCEPTION_WRITE_FAULT, reinterpret_cast<ULONG_PTR>(this) } - }; - CONTEXT ctx_record = {}; - EXCEPTION_POINTERS ex_ptrs = { - &ex_record, - &ctx_record, - }; - - MinidumpGenerator generator(dump_path_, - ::GetCurrentProcess(), - ::GetCurrentProcessId(), - ::GetCurrentThreadId(), - ::GetCurrentThreadId(), - &ex_ptrs, - NULL, - static_cast<MINIDUMP_TYPE>(flags), - TRUE); - generator.GenerateDumpFile(&dump_file_); - generator.GenerateFullDumpFile(&full_dump_file_); - // And write a dump - bool result = generator.WriteMinidump(); - return result == TRUE; - } - - protected: - std::wstring dump_file_; - std::wstring full_dump_file_; - - std::wstring dump_path_; -}; - -// We need to be able to get file information from Windows -bool HasFileInfo(const std::wstring& file_path) { - DWORD dummy; - const wchar_t* path = file_path.c_str(); - DWORD length = ::GetFileVersionInfoSize(path, &dummy); - if (length == 0) - return NULL; - - void* data = calloc(length, 1); - if (!data) - return false; - - if (!::GetFileVersionInfo(path, dummy, length, data)) { - free(data); - return false; - } - - void* translate = NULL; - UINT page_count; - BOOL query_result = VerQueryValue( - data, - L"\\VarFileInfo\\Translation", - static_cast<void**>(&translate), - &page_count); - - free(data); - if (query_result && translate) { - return true; - } else { - return false; - } -} - -TEST_F(MinidumpTest, Version) { - // Loads DbgHelp.dll in process - ImagehlpApiVersion(); - - HMODULE dbg_help = ::GetModuleHandle(L"dbghelp.dll"); - ASSERT_TRUE(dbg_help != NULL); - - wchar_t dbg_help_file[1024] = {}; - ASSERT_TRUE(::GetModuleFileName(dbg_help, - dbg_help_file, - sizeof(dbg_help_file) / - sizeof(*dbg_help_file))); - ASSERT_TRUE(HasFileInfo(std::wstring(dbg_help_file)) != NULL); - -// LOG(INFO) << "DbgHelp.dll version: " << file_info->file_version(); -} - -TEST_F(MinidumpTest, Normal) { - EXPECT_TRUE(WriteDump(MiniDumpNormal)); - DumpAnalysis mini(dump_file_); - - // We expect threads, modules and some memory. - EXPECT_TRUE(mini.HasStream(ThreadListStream)); - EXPECT_TRUE(mini.HasStream(ModuleListStream)); - EXPECT_TRUE(mini.HasStream(MemoryListStream)); - EXPECT_TRUE(mini.HasStream(ExceptionStream)); - EXPECT_TRUE(mini.HasStream(SystemInfoStream)); - EXPECT_TRUE(mini.HasStream(MiscInfoStream)); - - EXPECT_FALSE(mini.HasStream(ThreadExListStream)); - EXPECT_FALSE(mini.HasStream(Memory64ListStream)); - EXPECT_FALSE(mini.HasStream(CommentStreamA)); - EXPECT_FALSE(mini.HasStream(CommentStreamW)); - EXPECT_FALSE(mini.HasStream(HandleDataStream)); - EXPECT_FALSE(mini.HasStream(FunctionTableStream)); - EXPECT_FALSE(mini.HasStream(UnloadedModuleListStream)); - EXPECT_FALSE(mini.HasStream(MemoryInfoListStream)); - EXPECT_FALSE(mini.HasStream(ThreadInfoListStream)); - EXPECT_FALSE(mini.HasStream(HandleOperationListStream)); - EXPECT_FALSE(mini.HasStream(TokenStream)); - - // We expect no PEB nor TEBs in this dump. - EXPECT_FALSE(mini.HasTebs()); - EXPECT_FALSE(mini.HasPeb()); - - // We expect no off-stack memory in this dump. - EXPECT_FALSE(mini.HasMemory(this)); -} - -TEST_F(MinidumpTest, SmallDump) { - ASSERT_TRUE(WriteDump(kSmallDumpType)); - DumpAnalysis mini(dump_file_); - - EXPECT_TRUE(mini.HasStream(ThreadListStream)); - EXPECT_TRUE(mini.HasStream(ModuleListStream)); - EXPECT_TRUE(mini.HasStream(MemoryListStream)); - EXPECT_TRUE(mini.HasStream(ExceptionStream)); - EXPECT_TRUE(mini.HasStream(SystemInfoStream)); - EXPECT_TRUE(mini.HasStream(UnloadedModuleListStream)); - EXPECT_TRUE(mini.HasStream(MiscInfoStream)); - - // We expect PEB and TEBs in this dump. - EXPECT_TRUE(mini.HasTebs()); - EXPECT_TRUE(mini.HasPeb()); - - EXPECT_FALSE(mini.HasStream(ThreadExListStream)); - EXPECT_FALSE(mini.HasStream(Memory64ListStream)); - EXPECT_FALSE(mini.HasStream(CommentStreamA)); - EXPECT_FALSE(mini.HasStream(CommentStreamW)); - EXPECT_FALSE(mini.HasStream(HandleDataStream)); - EXPECT_FALSE(mini.HasStream(FunctionTableStream)); - EXPECT_FALSE(mini.HasStream(MemoryInfoListStream)); - EXPECT_FALSE(mini.HasStream(ThreadInfoListStream)); - EXPECT_FALSE(mini.HasStream(HandleOperationListStream)); - EXPECT_FALSE(mini.HasStream(TokenStream)); - - // We expect no off-stack memory in this dump. - EXPECT_FALSE(mini.HasMemory(this)); -} - -TEST_F(MinidumpTest, LargerDump) { - ASSERT_TRUE(WriteDump(kLargerDumpType)); - DumpAnalysis mini(dump_file_); - - // The dump should have all of these streams. - EXPECT_TRUE(mini.HasStream(ThreadListStream)); - EXPECT_TRUE(mini.HasStream(ModuleListStream)); - EXPECT_TRUE(mini.HasStream(MemoryListStream)); - EXPECT_TRUE(mini.HasStream(ExceptionStream)); - EXPECT_TRUE(mini.HasStream(SystemInfoStream)); - EXPECT_TRUE(mini.HasStream(UnloadedModuleListStream)); - EXPECT_TRUE(mini.HasStream(MiscInfoStream)); - - // We expect memory referenced by stack in this dump. - EXPECT_TRUE(mini.HasMemory(this)); - - // We expect PEB and TEBs in this dump. - EXPECT_TRUE(mini.HasTebs()); - EXPECT_TRUE(mini.HasPeb()); - - EXPECT_FALSE(mini.HasStream(ThreadExListStream)); - EXPECT_FALSE(mini.HasStream(Memory64ListStream)); - EXPECT_FALSE(mini.HasStream(CommentStreamA)); - EXPECT_FALSE(mini.HasStream(CommentStreamW)); - EXPECT_FALSE(mini.HasStream(HandleDataStream)); - EXPECT_FALSE(mini.HasStream(FunctionTableStream)); - EXPECT_FALSE(mini.HasStream(MemoryInfoListStream)); - EXPECT_FALSE(mini.HasStream(ThreadInfoListStream)); - EXPECT_FALSE(mini.HasStream(HandleOperationListStream)); - EXPECT_FALSE(mini.HasStream(TokenStream)); -} - -TEST_F(MinidumpTest, FullDump) { - ASSERT_TRUE(WriteDump(kFullDumpType)); - ASSERT_TRUE(dump_file_ != L""); - ASSERT_TRUE(full_dump_file_ != L""); - DumpAnalysis mini(dump_file_); - DumpAnalysis full(full_dump_file_); - - // Either dumps can contain part of the information. - - // The dump should have all of these streams. - EXPECT_TRUE(mini.HasStream(ThreadListStream)); - EXPECT_TRUE(full.HasStream(ThreadListStream)); - EXPECT_TRUE(mini.HasStream(ModuleListStream)); - EXPECT_TRUE(full.HasStream(ModuleListStream)); - EXPECT_TRUE(mini.HasStream(ExceptionStream)); - EXPECT_TRUE(full.HasStream(ExceptionStream)); - EXPECT_TRUE(mini.HasStream(SystemInfoStream)); - EXPECT_TRUE(full.HasStream(SystemInfoStream)); - EXPECT_TRUE(mini.HasStream(UnloadedModuleListStream)); - EXPECT_TRUE(full.HasStream(UnloadedModuleListStream)); - EXPECT_TRUE(mini.HasStream(MiscInfoStream)); - EXPECT_TRUE(full.HasStream(MiscInfoStream)); - EXPECT_TRUE(mini.HasStream(HandleDataStream)); - EXPECT_TRUE(full.HasStream(HandleDataStream)); - - // We expect memory referenced by stack in this dump. - EXPECT_FALSE(mini.HasMemory(this)); - EXPECT_TRUE(full.HasMemory(this)); - - // We expect PEB and TEBs in this dump. - EXPECT_TRUE(mini.HasTebs() || full.HasTebs()); - EXPECT_TRUE(mini.HasPeb() || full.HasPeb()); - - EXPECT_TRUE(mini.HasStream(MemoryListStream)); - EXPECT_TRUE(full.HasStream(Memory64ListStream)); - EXPECT_FALSE(mini.HasStream(Memory64ListStream)); - EXPECT_FALSE(full.HasStream(MemoryListStream)); - - // This is the only place we don't use OR because we want both not - // to have the streams. - EXPECT_FALSE(mini.HasStream(ThreadExListStream)); - EXPECT_FALSE(full.HasStream(ThreadExListStream)); - EXPECT_FALSE(mini.HasStream(CommentStreamA)); - EXPECT_FALSE(full.HasStream(CommentStreamA)); - EXPECT_FALSE(mini.HasStream(CommentStreamW)); - EXPECT_FALSE(full.HasStream(CommentStreamW)); - EXPECT_FALSE(mini.HasStream(FunctionTableStream)); - EXPECT_FALSE(full.HasStream(FunctionTableStream)); - EXPECT_FALSE(mini.HasStream(MemoryInfoListStream)); - EXPECT_FALSE(full.HasStream(MemoryInfoListStream)); - EXPECT_FALSE(mini.HasStream(ThreadInfoListStream)); - EXPECT_FALSE(full.HasStream(ThreadInfoListStream)); - EXPECT_FALSE(mini.HasStream(HandleOperationListStream)); - EXPECT_FALSE(full.HasStream(HandleOperationListStream)); - EXPECT_FALSE(mini.HasStream(TokenStream)); - EXPECT_FALSE(full.HasStream(TokenStream)); -} - -} // namespace diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/testing.gyp b/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/testing.gyp deleted file mode 100644 index 141d0ed0c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/testing.gyp +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright 2010 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. - -{ - 'includes': [ - '../../../build/common.gypi', - ], - 'target_defaults': { - }, - 'targets': [ - { - 'target_name': 'gtest', - 'type': 'static_library', - 'include_dirs': [ - '<(DEPTH)/testing/include', - '<(DEPTH)/testing/gtest', - '<(DEPTH)/testing/gtest/include', - ], - 'sources': [ - '<(DEPTH)/testing/gtest/src/gtest-all.cc', - ], - 'direct_dependent_settings': { - 'include_dirs': [ - '<(DEPTH)/testing/include', - '<(DEPTH)/testing/gtest/include', - ], - # Visual C++ implements variadic templates strangely, and - # VC++2012 broke Google Test by lowering this value. See - # http://stackoverflow.com/questions/12558327/google-test-in-visual-studio-2012 - 'defines': ['_VARIADIC_MAX=10'], - }, - 'defines': ['_VARIADIC_MAX=10'], - }, - { - 'target_name': 'gmock', - 'type': 'static_library', - 'include_dirs': [ - '<(DEPTH)/testing/include', - '<(DEPTH)/testing/', - '<(DEPTH)/testing/gtest', - '<(DEPTH)/testing/gtest/include', - ], - 'sources': [ - '<(DEPTH)/testing/src/gmock-all.cc', - '<(DEPTH)/testing/src/gmock_main.cc', - ], - 'direct_dependent_settings': { - 'include_dirs': [ - '<(DEPTH)/testing/include', - '<(DEPTH)/testing/gtest/include', - ], - 'defines': ['_VARIADIC_MAX=10'], - }, - 'defines': ['_VARIADIC_MAX=10'], - }, - - ], -} |