1f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// Copyright 2009, Google Inc. 2f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// All rights reserved. 3f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// 4f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// Redistribution and use in source and binary forms, with or without 5f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// modification, are permitted provided that the following conditions are 6f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// met: 7f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// 8f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// * Redistributions of source code must retain the above copyright 9f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// notice, this list of conditions and the following disclaimer. 10f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// * Redistributions in binary form must reproduce the above 11f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// copyright notice, this list of conditions and the following disclaimer 12f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// in the documentation and/or other materials provided with the 13f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// distribution. 14f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// * Neither the name of Google Inc. nor the names of its 15f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// contributors may be used to endorse or promote products derived from 16f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// this software without specific prior written permission. 17f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// 18f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid 30cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com#include "client/windows/unittests/exception_handler_test.h" 31cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com 32f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid#include <windows.h> 33f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid#include <dbghelp.h> 34f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid#include <strsafe.h> 35f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid#include <objbase.h> 36f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid#include <shellapi.h> 37f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid 389220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek#include <string> 399220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek 40cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com#include "breakpad_googletest_includes.h" 41cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com#include "client/windows/crash_generation/crash_generation_server.h" 42cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com#include "client/windows/handler/exception_handler.h" 43cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com#include "client/windows/unittests/dump_analysis.h" // NOLINT 44cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com#include "common/windows/string_utils-inl.h" 45cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com#include "google_breakpad/processor/minidump.h" 46cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com 47cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.comnamespace testing { 48cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com 49cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.comDisableExceptionHandlerInScope::DisableExceptionHandlerInScope() { 50cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com catch_exceptions_ = GTEST_FLAG(catch_exceptions); 51cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com GTEST_FLAG(catch_exceptions) = false; 52cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com} 53cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com 54cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.comDisableExceptionHandlerInScope::~DisableExceptionHandlerInScope() { 55cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com GTEST_FLAG(catch_exceptions) = catch_exceptions_; 56cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com} 57cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com 58cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com} // namespace testing 59ffedcd49454ce56a8136489c2e60bb840e6205dahansl@google.com 60f4f249e54475c88e5c0092633c2c31dd9ce18712nealsidnamespace { 619220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek 629220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarekusing std::wstring; 639220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarekusing namespace google_breakpad; 649220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek 65f4f249e54475c88e5c0092633c2c31dd9ce18712nealsidconst wchar_t kPipeName[] = L"\\\\.\\pipe\\BreakpadCrashTest\\TestCaseServer"; 66f4f249e54475c88e5c0092633c2c31dd9ce18712nealsidconst char kSuccessIndicator[] = "success"; 67f4f249e54475c88e5c0092633c2c31dd9ce18712nealsidconst char kFailureIndicator[] = "failure"; 68f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid 698cf0a52becf937650056dad55769a2d85d30f75dhansl@google.comconst MINIDUMP_TYPE kFullDumpType = static_cast<MINIDUMP_TYPE>( 708cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com MiniDumpWithFullMemory | // Full memory from process. 718cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com MiniDumpWithProcessThreadData | // Get PEB and TEB. 728cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com MiniDumpWithHandleData); // Get all handle information. 73f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid 748cf0a52becf937650056dad55769a2d85d30f75dhansl@google.comclass ExceptionHandlerTest : public ::testing::Test { 75ffedcd49454ce56a8136489c2e60bb840e6205dahansl@google.com protected: 76f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid // Member variable for each test that they can use 77f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid // for temporary storage. 78f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid TCHAR temp_path_[MAX_PATH]; 798cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com 80f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid // Actually constructs a temp path name. 81f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid virtual void SetUp(); 828cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com 838cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com // Deletes temporary files. 848cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com virtual void TearDown(); 858cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com 86bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com void DoCrashInvalidParameter(); 87bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com void DoCrashPureVirtualCall(); 888cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com 898cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com // Utility function to test for a path's existence. 908cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com static BOOL DoesPathExist(const TCHAR *path_name); 918cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com 928cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com // Client callback. 938cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com static void ClientDumpCallback( 948cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com void *dump_context, 958cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com const google_breakpad::ClientInfo *client_info, 968cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com const std::wstring *dump_path); 978cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com 989220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek static bool DumpCallback(const wchar_t* dump_path, 999220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek const wchar_t* minidump_id, 1009220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek void* context, 1019220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek EXCEPTION_POINTERS* exinfo, 1029220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek MDRawAssertionInfo* assertion, 1039220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek bool succeeded); 1049220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek 1058cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com static std::wstring dump_file; 1068cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com static std::wstring full_dump_file; 107f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid}; 108f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid 1098cf0a52becf937650056dad55769a2d85d30f75dhansl@google.comstd::wstring ExceptionHandlerTest::dump_file; 1108cf0a52becf937650056dad55769a2d85d30f75dhansl@google.comstd::wstring ExceptionHandlerTest::full_dump_file; 1118cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com 1128cf0a52becf937650056dad55769a2d85d30f75dhansl@google.comvoid ExceptionHandlerTest::SetUp() { 113f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid const ::testing::TestInfo* const test_info = 114f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid ::testing::UnitTest::GetInstance()->current_test_info(); 115f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid TCHAR temp_path[MAX_PATH] = { '\0' }; 116f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid TCHAR test_name_wide[MAX_PATH] = { '\0' }; 117f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid // We want the temporary directory to be what the OS returns 118ffedcd49454ce56a8136489c2e60bb840e6205dahansl@google.com // to us, + the test case name. 119f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid GetTempPath(MAX_PATH, temp_path); 120f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid // THe test case name is exposed to use as a c-style string, 121f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid // But we might be working in UNICODE here on Windows. 122ffedcd49454ce56a8136489c2e60bb840e6205dahansl@google.com int dwRet = MultiByteToWideChar(CP_ACP, 0, test_info->name(), 123ffedcd49454ce56a8136489c2e60bb840e6205dahansl@google.com strlen(test_info->name()), 124ffedcd49454ce56a8136489c2e60bb840e6205dahansl@google.com test_name_wide, 125ffedcd49454ce56a8136489c2e60bb840e6205dahansl@google.com MAX_PATH); 126f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid if (!dwRet) { 127f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid assert(false); 128f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid } 129f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid StringCchPrintfW(temp_path_, MAX_PATH, L"%s%s", temp_path, test_name_wide); 130f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid CreateDirectory(temp_path_, NULL); 131f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid} 132f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid 1338cf0a52becf937650056dad55769a2d85d30f75dhansl@google.comvoid ExceptionHandlerTest::TearDown() { 1348cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com if (!dump_file.empty()) { 1358cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com ::DeleteFile(dump_file.c_str()); 1368cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com dump_file = L""; 1378cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com } 1388cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com if (!full_dump_file.empty()) { 1398cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com ::DeleteFile(full_dump_file.c_str()); 1408cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com full_dump_file = L""; 1418cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com } 1428cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com} 1438cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com 1448cf0a52becf937650056dad55769a2d85d30f75dhansl@google.comBOOL ExceptionHandlerTest::DoesPathExist(const TCHAR *path_name) { 145f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid DWORD flags = GetFileAttributes(path_name); 146f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid if (flags == INVALID_FILE_ATTRIBUTES) { 147f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid return FALSE; 148f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid } 149f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid return TRUE; 150f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid} 151f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid 1529220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek// static 1538cf0a52becf937650056dad55769a2d85d30f75dhansl@google.comvoid ExceptionHandlerTest::ClientDumpCallback( 1548cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com void *dump_context, 1558cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com const google_breakpad::ClientInfo *client_info, 1569220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek const wstring *dump_path) { 1578cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com dump_file = *dump_path; 1588cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com // Create the full dump file name from the dump path. 1598cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com full_dump_file = dump_file.substr(0, dump_file.length() - 4) + L"-full.dmp"; 160f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid} 161f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid 1629220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek// static 1639220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarekbool ExceptionHandlerTest::DumpCallback(const wchar_t* dump_path, 1649220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek const wchar_t* minidump_id, 1659220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek void* context, 1669220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek EXCEPTION_POINTERS* exinfo, 1679220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek MDRawAssertionInfo* assertion, 1689220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek bool succeeded) { 1699220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek dump_file = dump_path; 1709220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek dump_file += L"\\"; 1719220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek dump_file += minidump_id; 1729220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek dump_file += L".dmp"; 1739220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek return succeeded; 1749220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek} 1759220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek 176bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.comvoid ExceptionHandlerTest::DoCrashInvalidParameter() { 177ffedcd49454ce56a8136489c2e60bb840e6205dahansl@google.com google_breakpad::ExceptionHandler *exc = 1788cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com new google_breakpad::ExceptionHandler( 1798cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com temp_path_, NULL, NULL, NULL, 1808cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com google_breakpad::ExceptionHandler::HANDLER_INVALID_PARAMETER, 1818cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com kFullDumpType, kPipeName, NULL); 182f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid 1838cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com // Disable the message box for assertions 1848cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com _CrtSetReportMode(_CRT_ASSERT, 0); 185f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid 186f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid // Although this is executing in the child process of the death test, 187ffedcd49454ce56a8136489c2e60bb840e6205dahansl@google.com // if it's not true we'll still get an error rather than the crash 188f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid // being expected. 189f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid ASSERT_TRUE(exc->IsOutOfProcess()); 1908cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com printf(NULL); 191f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid} 192f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid 193bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com 194bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.comstruct PureVirtualCallBase { 195bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com PureVirtualCallBase() { 196bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com // We have to reinterpret so the linker doesn't get confused because the 197bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com // method isn't defined. 198bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com reinterpret_cast<PureVirtualCallBase*>(this)->PureFunction(); 199bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com } 200bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com virtual ~PureVirtualCallBase() {} 201bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com virtual void PureFunction() const = 0; 202bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com}; 203bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.comstruct PureVirtualCall : public PureVirtualCallBase { 204bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com PureVirtualCall() { PureFunction(); } 205bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com virtual void PureFunction() const {} 206bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com}; 207bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com 208bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.comvoid ExceptionHandlerTest::DoCrashPureVirtualCall() { 209bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com google_breakpad::ExceptionHandler *exc = 210bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com new google_breakpad::ExceptionHandler( 211bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com temp_path_, NULL, NULL, NULL, 212bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com google_breakpad::ExceptionHandler::HANDLER_PURECALL, 213bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com kFullDumpType, kPipeName, NULL); 214bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com 215bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com // Disable the message box for assertions 216bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com _CrtSetReportMode(_CRT_ASSERT, 0); 217bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com 218bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com // Although this is executing in the child process of the death test, 219bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com // if it's not true we'll still get an error rather than the crash 220bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com // being expected. 221bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com ASSERT_TRUE(exc->IsOutOfProcess()); 222bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com 223bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com // Create a new frame to ensure PureVirtualCall is not optimized to some 224bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com // other line in this function. 225bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com { 226bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com PureVirtualCall instance; 227bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com } 228bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com} 229bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com 2308cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com// This test validates that the minidump is written correctly. 2318cf0a52becf937650056dad55769a2d85d30f75dhansl@google.comTEST_F(ExceptionHandlerTest, InvalidParameterMiniDumpTest) { 2328cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com ASSERT_TRUE(DoesPathExist(temp_path_)); 233f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid 2348cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com // Call with a bad argument 235f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid ASSERT_TRUE(DoesPathExist(temp_path_)); 2369220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek wstring dump_path(temp_path_); 237f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid google_breakpad::CrashGenerationServer server( 238eb991531e31b7c001200cf23ce07efc5a32b41aecdn@chromium.org kPipeName, NULL, NULL, NULL, ClientDumpCallback, NULL, NULL, NULL, NULL, 239eb991531e31b7c001200cf23ce07efc5a32b41aecdn@chromium.org NULL, true, &dump_path); 2408cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com 2418cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com ASSERT_TRUE(dump_file.empty() && full_dump_file.empty()); 242ffedcd49454ce56a8136489c2e60bb840e6205dahansl@google.com 243f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid // This HAS to be EXPECT_, because when this test case is executed in the 244f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid // child process, the server registration will fail due to the named pipe 245f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid // being the same. 246f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid EXPECT_TRUE(server.Start()); 247bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_EXIT(DoCrashInvalidParameter(), ::testing::ExitedWithCode(0), ""); 248bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com ASSERT_TRUE(!dump_file.empty() && !full_dump_file.empty()); 249bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com ASSERT_TRUE(DoesPathExist(dump_file.c_str())); 250bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com 251bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com // Verify the dump for infos. 252bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com DumpAnalysis mini(dump_file); 253bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com DumpAnalysis full(full_dump_file); 254bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com 255bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com // The dump should have all of these streams. 256bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_TRUE(mini.HasStream(ThreadListStream)); 257bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_TRUE(full.HasStream(ThreadListStream)); 258bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_TRUE(mini.HasStream(ModuleListStream)); 259bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_TRUE(full.HasStream(ModuleListStream)); 260bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_TRUE(mini.HasStream(ExceptionStream)); 261bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_TRUE(full.HasStream(ExceptionStream)); 262bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_TRUE(mini.HasStream(SystemInfoStream)); 263bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_TRUE(full.HasStream(SystemInfoStream)); 264bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_TRUE(mini.HasStream(MiscInfoStream)); 265bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_TRUE(full.HasStream(MiscInfoStream)); 266bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_TRUE(mini.HasStream(HandleDataStream)); 267bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_TRUE(full.HasStream(HandleDataStream)); 268bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com 269bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com // We expect PEB and TEBs in this dump. 270bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_TRUE(mini.HasTebs() || full.HasTebs()); 271bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_TRUE(mini.HasPeb() || full.HasPeb()); 272bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com 273bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com // Minidump should have a memory listing, but no 64-bit memory. 274bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_TRUE(mini.HasStream(MemoryListStream)); 275bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_FALSE(mini.HasStream(Memory64ListStream)); 276bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com 277bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_FALSE(full.HasStream(MemoryListStream)); 278bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_TRUE(full.HasStream(Memory64ListStream)); 279bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com 280bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com // This is the only place we don't use OR because we want both not 281bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com // to have the streams. 282bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_FALSE(mini.HasStream(ThreadExListStream)); 283bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_FALSE(full.HasStream(ThreadExListStream)); 284bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_FALSE(mini.HasStream(CommentStreamA)); 285bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_FALSE(full.HasStream(CommentStreamA)); 286bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_FALSE(mini.HasStream(CommentStreamW)); 287bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_FALSE(full.HasStream(CommentStreamW)); 288bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_FALSE(mini.HasStream(FunctionTableStream)); 289bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_FALSE(full.HasStream(FunctionTableStream)); 290bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_FALSE(mini.HasStream(MemoryInfoListStream)); 291bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_FALSE(full.HasStream(MemoryInfoListStream)); 292bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_FALSE(mini.HasStream(ThreadInfoListStream)); 293bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_FALSE(full.HasStream(ThreadInfoListStream)); 294bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_FALSE(mini.HasStream(HandleOperationListStream)); 295bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_FALSE(full.HasStream(HandleOperationListStream)); 296bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_FALSE(mini.HasStream(TokenStream)); 297bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_FALSE(full.HasStream(TokenStream)); 298bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com} 299bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com 300bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com 301bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com// This test validates that the minidump is written correctly. 302bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.comTEST_F(ExceptionHandlerTest, PureVirtualCallMiniDumpTest) { 303bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com ASSERT_TRUE(DoesPathExist(temp_path_)); 304bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com 305bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com // Call with a bad argument 306bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com ASSERT_TRUE(DoesPathExist(temp_path_)); 3079220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek wstring dump_path(temp_path_); 308bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com google_breakpad::CrashGenerationServer server( 309eb991531e31b7c001200cf23ce07efc5a32b41aecdn@chromium.org kPipeName, NULL, NULL, NULL, ClientDumpCallback, NULL, NULL, NULL, NULL, 310eb991531e31b7c001200cf23ce07efc5a32b41aecdn@chromium.org NULL, true, &dump_path); 311bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com 312bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com ASSERT_TRUE(dump_file.empty() && full_dump_file.empty()); 313bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com 314bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com // This HAS to be EXPECT_, because when this test case is executed in the 315bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com // child process, the server registration will fail due to the named pipe 316bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com // being the same. 317bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_TRUE(server.Start()); 318bcf885c8079b1742bfd93de722afceb26237ce4fhansl@google.com EXPECT_EXIT(DoCrashPureVirtualCall(), ::testing::ExitedWithCode(0), ""); 3198cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com ASSERT_TRUE(!dump_file.empty() && !full_dump_file.empty()); 3208cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com ASSERT_TRUE(DoesPathExist(dump_file.c_str())); 3218cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com 3228cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com // Verify the dump for infos. 3238cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com DumpAnalysis mini(dump_file); 3248cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com DumpAnalysis full(full_dump_file); 3258cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com 3268cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com // The dump should have all of these streams. 3278cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_TRUE(mini.HasStream(ThreadListStream)); 3288cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_TRUE(full.HasStream(ThreadListStream)); 3298cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_TRUE(mini.HasStream(ModuleListStream)); 3308cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_TRUE(full.HasStream(ModuleListStream)); 3318cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_TRUE(mini.HasStream(ExceptionStream)); 3328cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_TRUE(full.HasStream(ExceptionStream)); 3338cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_TRUE(mini.HasStream(SystemInfoStream)); 3348cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_TRUE(full.HasStream(SystemInfoStream)); 3358cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_TRUE(mini.HasStream(MiscInfoStream)); 3368cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_TRUE(full.HasStream(MiscInfoStream)); 3378cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_TRUE(mini.HasStream(HandleDataStream)); 3388cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_TRUE(full.HasStream(HandleDataStream)); 3398cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com 3408cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com // We expect PEB and TEBs in this dump. 3418cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_TRUE(mini.HasTebs() || full.HasTebs()); 3428cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_TRUE(mini.HasPeb() || full.HasPeb()); 3438cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com 3448cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com // Minidump should have a memory listing, but no 64-bit memory. 3458cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_TRUE(mini.HasStream(MemoryListStream)); 3468cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_FALSE(mini.HasStream(Memory64ListStream)); 3478cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com 3488cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_FALSE(full.HasStream(MemoryListStream)); 3498cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_TRUE(full.HasStream(Memory64ListStream)); 3508cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com 3518cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com // This is the only place we don't use OR because we want both not 3528cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com // to have the streams. 3538cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_FALSE(mini.HasStream(ThreadExListStream)); 3548cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_FALSE(full.HasStream(ThreadExListStream)); 3558cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_FALSE(mini.HasStream(CommentStreamA)); 3568cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_FALSE(full.HasStream(CommentStreamA)); 3578cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_FALSE(mini.HasStream(CommentStreamW)); 3588cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_FALSE(full.HasStream(CommentStreamW)); 3598cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_FALSE(mini.HasStream(FunctionTableStream)); 3608cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_FALSE(full.HasStream(FunctionTableStream)); 3618cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_FALSE(mini.HasStream(MemoryInfoListStream)); 3628cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_FALSE(full.HasStream(MemoryInfoListStream)); 3638cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_FALSE(mini.HasStream(ThreadInfoListStream)); 3648cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_FALSE(full.HasStream(ThreadInfoListStream)); 3658cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_FALSE(mini.HasStream(HandleOperationListStream)); 3668cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_FALSE(full.HasStream(HandleOperationListStream)); 3678cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_FALSE(mini.HasStream(TokenStream)); 3688cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com EXPECT_FALSE(full.HasStream(TokenStream)); 369f4f249e54475c88e5c0092633c2c31dd9ce18712nealsid} 3709220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek 3719220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek// Test that writing a minidump produces a valid minidump containing 3729220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek// some expected structures. 3739220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarekTEST_F(ExceptionHandlerTest, WriteMinidumpTest) { 3749220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek ExceptionHandler handler(temp_path_, 3759220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek NULL, 3769220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek DumpCallback, 3779220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek NULL, 3789220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek ExceptionHandler::HANDLER_ALL); 379cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com 380cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com // Disable GTest SEH handler 381cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com testing::DisableExceptionHandlerInScope disable_exception_handler; 382cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com 3839220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek ASSERT_TRUE(handler.WriteMinidump()); 3849220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek ASSERT_FALSE(dump_file.empty()); 3859220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek 3869220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek string minidump_filename; 3879220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek ASSERT_TRUE(WindowsStringUtils::safe_wcstombs(dump_file, 3889220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek &minidump_filename)); 3899220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek 3909220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek // Read the minidump and verify some info. 3919220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek Minidump minidump(minidump_filename); 3929220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek ASSERT_TRUE(minidump.Read()); 393f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // TODO(ted): more comprehensive tests... 394ffedcd49454ce56a8136489c2e60bb840e6205dahansl@google.com} 3959220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek 39686f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com// Test that an additional memory region can be included in the minidump. 39786f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.comTEST_F(ExceptionHandlerTest, AdditionalMemory) { 39886f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com SYSTEM_INFO si; 39986f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com GetSystemInfo(&si); 4006162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com const uint32_t kMemorySize = si.dwPageSize; 40186f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com 40286f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com // Get some heap memory. 4036162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint8_t* memory = new uint8_t[kMemorySize]; 40486f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com const uintptr_t kMemoryAddress = reinterpret_cast<uintptr_t>(memory); 40586f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com ASSERT_TRUE(memory); 40686f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com 40786f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com // Stick some data into the memory so the contents can be verified. 4086162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com for (uint32_t i = 0; i < kMemorySize; ++i) { 40986f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com memory[i] = i % 255; 41086f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com } 41186f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com 41286f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com ExceptionHandler handler(temp_path_, 41386f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com NULL, 41486f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com DumpCallback, 41586f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com NULL, 41686f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com ExceptionHandler::HANDLER_ALL); 41786f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com 418cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com // Disable GTest SEH handler 419cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com testing::DisableExceptionHandlerInScope disable_exception_handler; 420cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com 42186f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com // Add the memory region to the list of memory to be included. 42286f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com handler.RegisterAppMemory(memory, kMemorySize); 42386f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com ASSERT_TRUE(handler.WriteMinidump()); 42486f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com ASSERT_FALSE(dump_file.empty()); 42586f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com 42686f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com string minidump_filename; 42786f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com ASSERT_TRUE(WindowsStringUtils::safe_wcstombs(dump_file, 42886f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com &minidump_filename)); 42986f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com 43086f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com // Read the minidump. Ensure that the memory region is present 43186f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com Minidump minidump(minidump_filename); 43286f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com ASSERT_TRUE(minidump.Read()); 43386f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com 43486f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com MinidumpMemoryList* dump_memory_list = minidump.GetMemoryList(); 43586f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com ASSERT_TRUE(dump_memory_list); 43686f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com const MinidumpMemoryRegion* region = 43786f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com dump_memory_list->GetMemoryRegionForAddress(kMemoryAddress); 43886f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com ASSERT_TRUE(region); 43986f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com 44086f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com EXPECT_EQ(kMemoryAddress, region->GetBase()); 44186f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com EXPECT_EQ(kMemorySize, region->GetSize()); 44286f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com 44386f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com // Verify memory contents. 44486f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com EXPECT_EQ(0, memcmp(region->GetMemory(), memory, kMemorySize)); 44586f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com 44686f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com delete[] memory; 44786f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com} 44886f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com 44986f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com// Test that a memory region that was previously registered 45086f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com// can be unregistered. 45186f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.comTEST_F(ExceptionHandlerTest, AdditionalMemoryRemove) { 45286f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com SYSTEM_INFO si; 45386f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com GetSystemInfo(&si); 4546162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com const uint32_t kMemorySize = si.dwPageSize; 45586f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com 45686f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com // Get some heap memory. 4576162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint8_t* memory = new uint8_t[kMemorySize]; 45886f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com const uintptr_t kMemoryAddress = reinterpret_cast<uintptr_t>(memory); 45986f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com ASSERT_TRUE(memory); 46086f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com 46186f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com // Stick some data into the memory so the contents can be verified. 4626162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com for (uint32_t i = 0; i < kMemorySize; ++i) { 46386f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com memory[i] = i % 255; 46486f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com } 46586f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com 46686f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com ExceptionHandler handler(temp_path_, 46786f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com NULL, 46886f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com DumpCallback, 46986f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com NULL, 47086f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com ExceptionHandler::HANDLER_ALL); 47186f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com 472cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com // Disable GTest SEH handler 473cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com testing::DisableExceptionHandlerInScope disable_exception_handler; 474cc95c874b64b4f55bb8c4997a54b6ee1e2d2e9b7ivan.penkov@gmail.com 47586f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com // Add the memory region to the list of memory to be included. 47686f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com handler.RegisterAppMemory(memory, kMemorySize); 47786f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com 47886f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com // ...and then remove it 47986f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com handler.UnregisterAppMemory(memory); 48086f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com 48186f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com ASSERT_TRUE(handler.WriteMinidump()); 48286f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com ASSERT_FALSE(dump_file.empty()); 48386f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com 48486f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com string minidump_filename; 48586f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com ASSERT_TRUE(WindowsStringUtils::safe_wcstombs(dump_file, 48686f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com &minidump_filename)); 48786f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com 48886f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com // Read the minidump. Ensure that the memory region is not present. 48986f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com Minidump minidump(minidump_filename); 49086f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com ASSERT_TRUE(minidump.Read()); 49186f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com 49286f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com MinidumpMemoryList* dump_memory_list = minidump.GetMemoryList(); 49386f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com ASSERT_TRUE(dump_memory_list); 49486f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com const MinidumpMemoryRegion* region = 49586f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com dump_memory_list->GetMemoryRegionForAddress(kMemoryAddress); 49686f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com EXPECT_FALSE(region); 49786f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com 49886f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com delete[] memory; 49986f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com} 50086f79a00ae0829dae0136f758eafbe7c220e0c0dted.mielczarek@gmail.com 5019220e0baf1f59c067e82495d697306cc460c4e8cted.mielczarek} // namespace 502