// Copyright 2022 The Crashpad Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "client/crashpad_client.h" #include "base/files/file_path.h" #include "gtest/gtest.h" #include "test/test_paths.h" #include "util/win/registration_protocol_win.h" #include #include namespace crashpad { namespace test { namespace { base::FilePath ModulePath() { auto dir = TestPaths::Executable().DirName(); return dir.Append(FILE_PATH_LITERAL("crashpad_wer.dll")); } // Quick sanity check of the module, can't really test dumping etc. outside of // WerFault.exe loading it. TEST(CrashpadWerModule, Basic) { HRESULT res = 0; // Module loads. HMODULE hMod = LoadLibraryW(ModulePath().value().c_str()); ASSERT_TRUE(hMod); // Required functions exist. auto wref = reinterpret_cast( GetProcAddress(hMod, WER_RUNTIME_EXCEPTION_EVENT_FUNCTION)); ASSERT_TRUE(wref); auto wrees = reinterpret_cast( GetProcAddress(hMod, WER_RUNTIME_EXCEPTION_EVENT_SIGNATURE_FUNCTION)); ASSERT_TRUE(wrees); auto wredl = reinterpret_cast( GetProcAddress(hMod, WER_RUNTIME_EXCEPTION_DEBUGGER_LAUNCH)); ASSERT_TRUE(wredl); // Not-implemented functions return E_FAIL as expected. res = wrees(nullptr, nullptr, 0, nullptr, nullptr, nullptr, nullptr); ASSERT_EQ(res, E_FAIL); res = wredl(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); ASSERT_EQ(res, E_FAIL); // Dummy args for OutOfProcessExceptionEventCallback. WER_RUNTIME_EXCEPTION_INFORMATION wer_ex; wer_ex.dwSize = sizeof(WER_RUNTIME_EXCEPTION_INFORMATION); BOOL bClaimed = FALSE; // No context => skip. res = wref(nullptr, &wer_ex, &bClaimed, nullptr, nullptr, nullptr); ASSERT_EQ(res, S_OK); ASSERT_EQ(bClaimed, FALSE); // Following tests only make sense if building on SDK >= 19041 as // bIsFatalField only exists after that. #if defined(NTDDI_WIN10_VB) && (WDK_NTDDI_VERSION >= NTDDI_WIN10_VB) crashpad::WerRegistration registration; // Non-fatal exceptions are skipped. wer_ex.bIsFatal = FALSE; res = wref(®istration, &wer_ex, &bClaimed, nullptr, nullptr, nullptr); ASSERT_EQ(res, S_OK); ASSERT_EQ(bClaimed, FALSE); // Fatal exception with unhandled code is skipped. wer_ex.bIsFatal = TRUE; wer_ex.exceptionRecord.ExceptionCode = 0xc0000005; res = wref(®istration, &wer_ex, &bClaimed, nullptr, nullptr, nullptr); ASSERT_EQ(res, S_OK); ASSERT_EQ(bClaimed, FALSE); #endif // defined(NTDDI_WIN10_VB) && WDK_NTDDI_VERSION >= NTDDI_WIN10_VB FreeLibrary(hMod); } } // namespace } // namespace test } // namespace crashpad