Bug 1349444: Take the stack walk workaround lock in LdrUnloadDll. r=mstange

This will prevent the profiler from suspending a target thread while that thread holds the RtlLookupFunctionEntry lock, which the profiler itself also wants to use.
This commit is contained in:
David Major 2017-04-25 16:10:14 -04:00
parent 88d5807434
commit 5be9ebe23b
2 changed files with 29 additions and 0 deletions

View File

@ -190,6 +190,7 @@ StackWalkInitCriticalAddress()
#include <malloc.h>
#include "mozilla/ArrayUtils.h"
#include "mozilla/StackWalk_windows.h"
#include "nsWindowsDllInterceptor.h"
#include <imagehlp.h>
// We need a way to know if we are building for WXP (or later), as if we are, we
@ -225,6 +226,20 @@ CRITICAL_SECTION gDbgHelpCS;
#ifdef _M_AMD64
static uint8_t* sJitCodeRegionStart;
static size_t sJitCodeRegionSize;
static WindowsDllInterceptor NtDllInterceptor;
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.
AcquireStackWalkWorkaroundLock();
NTSTATUS ret = stub_LdrUnloadDll(module);
ReleaseStackWalkWorkaroundLock();
return ret;
}
#endif
// Routine to print an error message to standard error.
@ -300,6 +315,12 @@ EnsureWalkThreadReady()
stackWalkThread = nullptr;
readyEvent = nullptr;
#ifdef _M_AMD64
NtDllInterceptor.Init("ntdll.dll");
NtDllInterceptor.AddHook("LdrUnloadDll",
reinterpret_cast<intptr_t>(patched_LdrUnloadDll),
(void**)&stub_LdrUnloadDll);
#endif
::InitializeCriticalSection(&gDbgHelpCS);

View File

@ -236,6 +236,13 @@ bool TestNtQueryFullAttributesFile(void* aFunc)
return patchedNtQueryFullAttributesFile(0, 0) != 0;
}
bool TestLdrUnloadDll(void* aFunc)
{
typedef NTSTATUS (NTAPI *LdrUnloadDllType)(HMODULE);
auto patchedLdrUnloadDll = reinterpret_cast<LdrUnloadDllType>(aFunc);
return patchedLdrUnloadDll(0) != 0;
}
bool TestSetUnhandledExceptionFilter(void* aFunc)
{
auto patchedSetUnhandledExceptionFilter =
@ -463,6 +470,7 @@ int main()
TestHook(TestGetOpenFileNameW, "comdlg32.dll", "GetOpenFileNameW") &&
#ifdef _M_X64
TestHook(TestGetKeyState, "user32.dll", "GetKeyState") && // see Bug 1316415
TestHook(TestLdrUnloadDll, "ntdll.dll", "LdrUnloadDll") &&
#endif
MaybeTestHook(ShouldTestTipTsf(), TestProcessCaretEvents, "tiptsf.dll", "ProcessCaretEvents") &&
#ifdef _M_IX86