From: Mikhail Kurinnoi Date: Mon, 18 May 2020 16:19:26 +0000 (+0300) Subject: Fix exception behaviour in implicit function execution during eval. X-Git-Tag: submit/tizen/20200526.162055~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2fc9a543d4b47ff476f0c2a862cdca084b3f1f7c;p=sdk%2Ftools%2Fnetcoredbg.git Fix exception behaviour in implicit function execution during eval. --- diff --git a/src/debug/netcoredbg/manageddebugger.cpp b/src/debug/netcoredbg/manageddebugger.cpp index e100cbe..727ea6a 100644 --- a/src/debug/netcoredbg/manageddebugger.cpp +++ b/src/debug/netcoredbg/manageddebugger.cpp @@ -501,12 +501,44 @@ public: { LogFuncEntry(); + HRESULT Status = S_OK; + // TODO: Need implementation // // This is callback EvalException invoked on evaluation interruption event. // And, evaluated results has inconsistent states. Notify is not enough for this point. m_debugger.m_evaluator.NotifyEvalComplete(pThread, pEval); + + // NOTE + // In case of unhandled exception inside implicit function call (for example, getter), + // ICorDebugManagedCallback::EvalException() is exit point for eval routine, make sure, + // that proper threads states are setted up. + if (m_debugger.m_evaluator.is_empty_eval_queue()) + { + pAppDomain->SetAllThreadsDebugState(THREAD_RUN, nullptr); + } + else + { + DWORD currentThreadId; + pThread->GetID(¤tThreadId); + DWORD evalThreadId = m_debugger.m_evaluator.front_eval_queue(); + if (evalThreadId == currentThreadId) { + m_debugger.m_evaluator.pop_eval_queue(); + + DWORD evalThreadId = m_debugger.m_evaluator.front_eval_queue(); + ToRelease pThreadEval; + IfFailRet(m_debugger.m_pProcess->GetThread(evalThreadId, &pThreadEval)); + IfFailRet(pAppDomain->SetAllThreadsDebugState(THREAD_SUSPEND, nullptr)); + IfFailRet(pThreadEval->SetDebugState(THREAD_RUN)); + + Logger::levelLog(LOG_INFO, "Eval exception, threadid = '%d'", currentThreadId); + } + else { + Logger::levelLog(LOG_ERROR, "Logical error: eval queue '%d' != '%d'", currentThreadId, evalThreadId); + } + } + return S_OK; } @@ -778,6 +810,14 @@ public: { LogFuncEntry(); + // In case we inside evaluation (exception during implicit function execution), make sure we continue process execution. + // This is internal CoreCLR routine, should not be interrupted by debugger. CoreCLR will care about exception in this case + // and provide exception data as evaluation result in case of unhandled exception. + if (m_debugger.m_evaluator.IsEvalRunning() && m_debugger.m_evaluator.FindEvalForThread(pThread)) + { + return pAppDomain->Continue(0); + } + // INFO: Exception event callbacks produce Stop process and managed threads in coreCLR // After emit Stop event from debugger coreclr by command handler send a ExceptionInfo request. // For answer on ExceptionInfo are needed long FuncEval() with asynchronous EvalComplete event.