// Return Value:
// None
//
-inline void LogCallstackForLogWorker(bool isStackOverflow = false)
+inline void LogCallstackForLogWorker(Thread* pThread)
{
WRAPPER_NO_CONTRACT;
- Thread* pThread = GetThread();
- _ASSERTE (pThread);
-
SmallStackSString WordAt;
- if (isStackOverflow || !WordAt.LoadResource(CCompRC::Optional, IDS_ER_WORDAT))
+ if (!WordAt.LoadResource(CCompRC::Optional, IDS_ER_WORDAT))
{
WordAt.Set(W(" at"));
}
CallStackLogger logger;
- pThread->StackWalkFrames(&CallStackLogger::LogCallstackForLogCallback, &logger, QUICKUNWIND | FUNCTIONSONLY);
+ pThread->StackWalkFrames(&CallStackLogger::LogCallstackForLogCallback, &logger, QUICKUNWIND | FUNCTIONSONLY | ALLOW_ASYNC_STACK_WALK);
logger.PrintStackTrace(WordAt.GetUnicode());
if (pThread && errorSource == NULL)
{
- LogCallstackForLogWorker();
+ LogCallstackForLogWorker(GetThread());
if (argExceptionString != NULL) {
PrintToStdErrW(argExceptionString);
PrintToStdErrA("Stack overflow.\n");
}
+DWORD LogStackOverflowStackTraceThread(void* arg)
+{
+ LogCallstackForLogWorker((Thread*)arg);
+
+ return 0;
+}
+
void DECLSPEC_NORETURN EEPolicy::HandleFatalStackOverflow(EXCEPTION_POINTERS *pExceptionInfo, BOOL fSkipDebugger)
{
// This is fatal error. We do not care about SO mode any more.
if (InterlockedCompareExchange(&g_stackOverflowCallStackLogged, 1, 0) == 0)
{
DisplayStackOverflowException();
- LogCallstackForLogWorker(true /* isStackOverflow */);
+
+ HandleHolder stackDumpThreadHandle = Thread::CreateUtilityThread(Thread::StackSize_Small, LogStackOverflowStackTraceThread, GetThread(), W(".NET Stack overflow trace logger"));
+ if (stackDumpThreadHandle != INVALID_HANDLE_VALUE)
+ {
+ // Wait for the stack trace logging completion
+ DWORD res = WaitForSingleObject(stackDumpThreadHandle, INFINITE);
+ _ASSERTE(res == WAIT_OBJECT_0);
+ }
+
g_stackOverflowCallStackLogged = 2;
}
else
// -additionally, we need to provide some region to hosts to allow for lock acquisition in a hosted scenario
//
EXTRA_PAGES = 3;
- INDEBUG(EXTRA_PAGES += 3);
+ INDEBUG(EXTRA_PAGES += 1);
int ThreadGuardPages = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_ThreadGuardPages);
if (ThreadGuardPages == 0)
#else // HOST_64BIT
#ifdef _DEBUG
- uGuardSize += (3 * GetOsPageSize()); // three extra pages for debug infrastructure
+ uGuardSize += (1 * GetOsPageSize()); // one extra page for debug infrastructure
#endif // _DEBUG
#endif // HOST_64BIT