mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 806209 - Prevent the Windows implementation of NS_StackWalk from accessing the stdio APIs in order to avoid deadlocks when profiling on Windows; r=BenWa
--HG-- extra : rebase_source : cb945d9d3cb162a1177029a6aa097af33f7c917b
This commit is contained in:
parent
37f89578d7
commit
c6c8d4cb2c
@ -306,7 +306,7 @@ WalkStackMain64(struct WalkStackData* data)
|
||||
// Get a context for the specified thread.
|
||||
memset(&context, 0, sizeof(CONTEXT));
|
||||
context.ContextFlags = CONTEXT_FULL;
|
||||
if (!GetThreadContext(myThread, &context)) {
|
||||
if (!GetThreadContext(myThread, &context) && data->walkCallingThread) {
|
||||
PrintError("GetThreadContext");
|
||||
return;
|
||||
}
|
||||
@ -365,7 +365,9 @@ WalkStackMain64(struct WalkStackData* data)
|
||||
} else {
|
||||
addr = 0;
|
||||
spaddr = 0;
|
||||
PrintError("WalkStack64");
|
||||
if (data->walkCallingThread) {
|
||||
PrintError("WalkStack64");
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok || (addr == 0)) {
|
||||
@ -473,6 +475,10 @@ NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
targetThread = threadToWalk;
|
||||
}
|
||||
|
||||
// We need to avoid calling fprintf and friends if we're walking the stack of
|
||||
// another thread, in order to avoid deadlocks.
|
||||
const bool shouldBeThreadSafe = !!aThread;
|
||||
|
||||
// Have to duplicate handle to get a real handle.
|
||||
if (!myProcess) {
|
||||
if (!::DuplicateHandle(::GetCurrentProcess(),
|
||||
@ -480,7 +486,9 @@ NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
::GetCurrentProcess(),
|
||||
&myProcess,
|
||||
PROCESS_ALL_ACCESS, FALSE, 0)) {
|
||||
PrintError("DuplicateHandle (process)");
|
||||
if (!shouldBeThreadSafe) {
|
||||
PrintError("DuplicateHandle (process)");
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
@ -489,7 +497,9 @@ NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
::GetCurrentProcess(),
|
||||
&myThread,
|
||||
THREAD_ALL_ACCESS, FALSE, 0)) {
|
||||
PrintError("DuplicateHandle (thread)");
|
||||
if (!shouldBeThreadSafe) {
|
||||
PrintError("DuplicateHandle (thread)");
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -529,7 +539,7 @@ NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
|
||||
walkerReturn = ::SignalObjectAndWait(data.eventStart,
|
||||
data.eventEnd, INFINITE, FALSE);
|
||||
if (walkerReturn != WAIT_OBJECT_0)
|
||||
if (walkerReturn != WAIT_OBJECT_0 && !shouldBeThreadSafe)
|
||||
PrintError("SignalObjectAndWait (1)");
|
||||
if (data.pc_count > data.pc_size) {
|
||||
data.pcs = (void**) _alloca(data.pc_count * sizeof(void*));
|
||||
@ -541,7 +551,7 @@ NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
::PostThreadMessage(gStackWalkThread, WM_USER, 0, (LPARAM)&data);
|
||||
walkerReturn = ::SignalObjectAndWait(data.eventStart,
|
||||
data.eventEnd, INFINITE, FALSE);
|
||||
if (walkerReturn != WAIT_OBJECT_0)
|
||||
if (walkerReturn != WAIT_OBJECT_0 && !shouldBeThreadSafe)
|
||||
PrintError("SignalObjectAndWait (2)");
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user