diff --git a/mozglue/build/WindowsDllBlocklist.cpp b/mozglue/build/WindowsDllBlocklist.cpp index ed8065d0d6e0..d65d5975b67f 100644 --- a/mozglue/build/WindowsDllBlocklist.cpp +++ b/mozglue/build/WindowsDllBlocklist.cpp @@ -779,38 +779,6 @@ continue_loading: return stub_LdrLoadDll(filePath, flags, moduleFileName, handle); } -#ifdef _M_AMD64 -typedef NTSTATUS (NTAPI *LdrUnloadDll_func)(HMODULE module); -static LdrUnloadDll_func stub_LdrUnloadDll; - -static NTSTATUS NTAPI -patched_LdrUnloadDll(HMODULE module) -{ - // Prevent the stack walker from suspending this thread when LdrUnloadDll - // holds the RtlLookupFunctionEntry lock. - AutoSuppressStackWalking suppress; - return stub_LdrUnloadDll(module); -} - -// These pointers are disguised as PVOID to avoid pulling in obscure headers -typedef PVOID (WINAPI *LdrResolveDelayLoadedAPI_func)(PVOID ParentModuleBase, - PVOID DelayloadDescriptor, PVOID FailureDllHook, PVOID FailureSystemHook, - PVOID ThunkAddress, ULONG Flags); -static LdrResolveDelayLoadedAPI_func stub_LdrResolveDelayLoadedAPI; - -static PVOID WINAPI patched_LdrResolveDelayLoadedAPI(PVOID ParentModuleBase, - PVOID DelayloadDescriptor, PVOID FailureDllHook, PVOID FailureSystemHook, - PVOID ThunkAddress, ULONG Flags) -{ - // Prevent the stack walker from suspending this thread when - // LdrResolveDelayLoadAPI holds the RtlLookupFunctionEntry lock. - AutoSuppressStackWalking suppress; - return stub_LdrResolveDelayLoadedAPI(ParentModuleBase, DelayloadDescriptor, - FailureDllHook, FailureSystemHook, - ThunkAddress, Flags); -} -#endif - #ifdef _M_IX86 static bool ShouldBlockThread(void* aStartAddress) @@ -890,14 +858,6 @@ DllBlocklist_Initialize(uint32_t aInitFlags) Kernel32Intercept.Init("kernel32.dll"); #ifdef _M_AMD64 - NtDllIntercept.AddHook("LdrUnloadDll", - reinterpret_cast(patched_LdrUnloadDll), - (void**)&stub_LdrUnloadDll); - if (IsWin8OrLater()) { // LdrResolveDelayLoadedAPI was introduced in Win8 - NtDllIntercept.AddHook("LdrResolveDelayLoadedAPI", - reinterpret_cast(patched_LdrResolveDelayLoadedAPI), - (void**)&stub_LdrResolveDelayLoadedAPI); - } if (!IsWin8OrLater()) { // The crash that this hook works around is only seen on Win7. Kernel32Intercept.AddHook("RtlInstallFunctionTableCallback", diff --git a/tools/profiler/core/platform-win32.cpp b/tools/profiler/core/platform-win32.cpp index ee7edf9eda1b..f1899944f593 100644 --- a/tools/profiler/core/platform-win32.cpp +++ b/tools/profiler/core/platform-win32.cpp @@ -32,6 +32,10 @@ #include #include +#include "nsWindowsDllInterceptor.h" +#include "mozilla/StackWalk_windows.h" +#include "mozilla/WindowsVersion.h" + /* static */ Thread::tid_t Thread::GetCurrentId() { @@ -282,3 +286,58 @@ Registers::SyncPopulate() } #endif +#if defined(GP_PLAT_amd64_windows) +static WindowsDllInterceptor NtDllIntercept; + +typedef NTSTATUS (NTAPI *LdrUnloadDll_func)(HMODULE module); +static LdrUnloadDll_func stub_LdrUnloadDll; + +static NTSTATUS NTAPI +patched_LdrUnloadDll(HMODULE module) +{ + // Prevent the stack walker from suspending this thread when LdrUnloadDll + // holds the RtlLookupFunctionEntry lock. + AutoSuppressStackWalking suppress; + return stub_LdrUnloadDll(module); +} + +// These pointers are disguised as PVOID to avoid pulling in obscure headers +typedef PVOID (WINAPI *LdrResolveDelayLoadedAPI_func)(PVOID ParentModuleBase, + PVOID DelayloadDescriptor, PVOID FailureDllHook, PVOID FailureSystemHook, + PVOID ThunkAddress, ULONG Flags); +static LdrResolveDelayLoadedAPI_func stub_LdrResolveDelayLoadedAPI; + +static PVOID WINAPI +patched_LdrResolveDelayLoadedAPI(PVOID ParentModuleBase, + PVOID DelayloadDescriptor, PVOID FailureDllHook, PVOID FailureSystemHook, + PVOID ThunkAddress, ULONG Flags) +{ + // Prevent the stack walker from suspending this thread when + // LdrResolveDelayLoadAPI holds the RtlLookupFunctionEntry lock. + AutoSuppressStackWalking suppress; + return stub_LdrResolveDelayLoadedAPI(ParentModuleBase, DelayloadDescriptor, + FailureDllHook, FailureSystemHook, + ThunkAddress, Flags); +} + +void +InitializeWin64ProfilerHooks() +{ + static bool initialized = false; + if (initialized) { + return; + } + initialized = true; + + NtDllIntercept.Init("ntdll.dll"); + NtDllIntercept.AddHook("LdrUnloadDll", + reinterpret_cast(patched_LdrUnloadDll), + (void**)&stub_LdrUnloadDll); + if (IsWin8OrLater()) { // LdrResolveDelayLoadedAPI was introduced in Win8 + NtDllIntercept.AddHook("LdrResolveDelayLoadedAPI", + reinterpret_cast(patched_LdrResolveDelayLoadedAPI), + (void**)&stub_LdrResolveDelayLoadedAPI); + } +} +#endif // defined(GP_PLAT_amd64_windows) + diff --git a/tools/profiler/core/platform.cpp b/tools/profiler/core/platform.cpp index 40233fd2d0e0..1266b93d5238 100644 --- a/tools/profiler/core/platform.cpp +++ b/tools/profiler/core/platform.cpp @@ -2423,6 +2423,10 @@ locked_profiler_start(PSLockRef aLock, int aEntries, double aInterval, MOZ_RELEASE_ASSERT(CorePS::Exists() && !ActivePS::Exists(aLock)); +#if defined(GP_PLAT_amd64_windows) + InitializeWin64ProfilerHooks(); +#endif + // Fall back to the default values if the passed-in values are unreasonable. int entries = aEntries > 0 ? aEntries : PROFILER_DEFAULT_ENTRIES; double interval = aInterval > 0 ? aInterval : PROFILER_DEFAULT_INTERVAL;