Bug 1378442 - Move Win64 profiler hooks to profiler_start. r=mstange

This commit is contained in:
David Major 2017-07-05 18:45:31 -04:00
parent 2c24b3d088
commit 8f2fab9547
3 changed files with 63 additions and 40 deletions

View File

@ -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<intptr_t>(patched_LdrUnloadDll),
(void**)&stub_LdrUnloadDll);
if (IsWin8OrLater()) { // LdrResolveDelayLoadedAPI was introduced in Win8
NtDllIntercept.AddHook("LdrResolveDelayLoadedAPI",
reinterpret_cast<intptr_t>(patched_LdrResolveDelayLoadedAPI),
(void**)&stub_LdrResolveDelayLoadedAPI);
}
if (!IsWin8OrLater()) {
// The crash that this hook works around is only seen on Win7.
Kernel32Intercept.AddHook("RtlInstallFunctionTableCallback",

View File

@ -32,6 +32,10 @@
#include <mmsystem.h>
#include <process.h>
#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<intptr_t>(patched_LdrUnloadDll),
(void**)&stub_LdrUnloadDll);
if (IsWin8OrLater()) { // LdrResolveDelayLoadedAPI was introduced in Win8
NtDllIntercept.AddHook("LdrResolveDelayLoadedAPI",
reinterpret_cast<intptr_t>(patched_LdrResolveDelayLoadedAPI),
(void**)&stub_LdrResolveDelayLoadedAPI);
}
}
#endif // defined(GP_PLAT_amd64_windows)

View File

@ -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;