| // Copyright 2022 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <windows.h> |
| |
| #include <delayimp.h> |
| |
| #include "base/process/memory.h" |
| #include "base/strings/stringprintf.h" |
| #include "base/test/gtest_util.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| // Subtle: In tests, unit_tests.exe is linked with |
| // chrome/common/win/delay_load_failure_hook.cc not |
| // chrome/app/delay_load_failure_hook_win.cc. So, __pfnDliFailureHook2 will |
| // always call DelayLoadFailureHook and not DelayLoadFailureHookEXE despite |
| // existing in an exe file named unit_tests.exe. |
| // |
| // In production chrome.exe, __pfnDliFailureHook2 is instead backed by |
| // DelayLoadFailureHookEXE in chrome/app/delay_load_failure_hook_win.cc, while |
| // in chrome.dll, __pfnDliFailureHook2 is backed by DelayLoadFailureHook from |
| // chrome/common/win/delay_load_failure_hook.cc. |
| |
| // This test verifies that delay load hooks are correctly in place for the |
| // current module, which is unit_tests.exe in the case of this test. |
| TEST(ChromeDelayLoadHookTest, HooksAreSetAtLinkTime) { |
| ASSERT_NE(__pfnDliFailureHook2, nullptr); |
| } |
| |
| // This test verifies DelayLoadFailureHook crashes for a failure. |
| TEST(ChromeDelayLoadHookTest, DllLoadFailureCrashes) { |
| DelayLoadInfo dli = {.szDll = "test.dll"}; |
| EXPECT_NOTREACHED_DEATH({ __pfnDliFailureHook2(dliFailLoadLib, &dli); }); |
| } |
| |
| // This test verifies that DelayLoadFailureHook does not crash for known |
| // DLLs. |
| TEST(ChromeDelayLoadHookTest, DllLoadFailureDoesNotCrash) { |
| { |
| DelayLoadInfo dli = {.szDll = "MF.dll"}; |
| EXPECT_EQ(__pfnDliFailureHook2(dliFailLoadLib, &dli), nullptr); |
| } |
| { |
| DelayLoadInfo dli = {.szDll = "MFPlat.dll"}; |
| EXPECT_EQ(__pfnDliFailureHook2(dliFailLoadLib, &dli), nullptr); |
| } |
| { |
| DelayLoadInfo dli = {.szDll = "MFReadWrite.dll"}; |
| EXPECT_EQ(__pfnDliFailureHook2(dliFailLoadLib, &dli), nullptr); |
| } |
| { |
| DelayLoadInfo dli = {.szDll = "bthprops.cpl"}; |
| EXPECT_EQ(__pfnDliFailureHook2(dliFailLoadLib, &dli), nullptr); |
| } |
| } |
| |
| // This test verifies that if a DLL is failing to load because of lack of |
| // memory, an OOM exception is generated rather than just a CHECK so as to |
| // distinguish them in crash reports. |
| TEST(ChromeDelayLoadHookDeathTest, OomIsHandled) { |
| DelayLoadInfo dli = {.szDll = "test.dll", |
| .dwLastError = ERROR_COMMITMENT_LIMIT}; |
| const auto expected = base::StringPrintf("Received fatal exception 0x%08lx", |
| base::win::kOomExceptionCode); |
| EXPECT_DEATH_IF_SUPPORTED({ __pfnDliFailureHook2(dliFailLoadLib, &dli); }, |
| expected); |
| } |