// See the LICENSE file in the project root for more information.\r
\r
#include "debugger/evalwaiter.h"\r
-#include "debugger/threads.h"\r
\r
namespace netcoredbg\r
{\r
IfFailRet(pThread->GetProcess(&iCorProcess));\r
if (!iCorProcess)\r
return E_FAIL;\r
- std::vector<ThreadId> userThreadIds;\r
- IfFailRet(m_sharedThreads->GetThreadIds(userThreadIds));\r
- ThreadId threadId(getThreadId(pThread));\r
- if (!threadId)\r
- return E_FAIL;\r
+ DWORD evalThreadId = 0;\r
+ IfFailRet(pThread->GetID(&evalThreadId));\r
\r
- // Note, we need suspend during eval only user's threads, that not used for eval.\r
+ // Note, we need suspend during eval all managed threads, that not used for eval (delegates, reverse pinvokes, managed threads).\r
auto ChangeThreadsState = [&](CorDebugThreadState state)\r
{\r
- for (const auto &userThreadId : userThreadIds)\r
+ ToRelease<ICorDebugThreadEnum> iCorThreadEnum;\r
+ iCorProcess->EnumerateThreads(&iCorThreadEnum);\r
+ ULONG fetched = 0;\r
+ ToRelease<ICorDebugThread> iCorThread;\r
+ while (SUCCEEDED(iCorThreadEnum->Next(1, &iCorThread, &fetched)) && fetched == 1)\r
{\r
- if (threadId == userThreadId)\r
- continue;\r
-\r
- ToRelease<ICorDebugThread> iCorThread;\r
- if (FAILED(iCorProcess->GetThread(int(userThreadId), &iCorThread)) ||\r
- FAILED(iCorThread->SetDebugState(state)))\r
+ DWORD tid = 0;\r
+ if (SUCCEEDED(iCorThread->GetID(&tid)) && evalThreadId != tid)\r
{\r
- if (state == THREAD_SUSPEND)\r
- LOGW("%s %s", "SetDebugState(THREAD_SUSPEND) during eval setup failed.",\r
- "This may change the state of the process and any breakpoints and exceptions encountered will be skipped.");\r
- else\r
- LOGW("SetDebugState(THREAD_RUN) during eval failed. Process state was not restored.");\r
+ if (FAILED(iCorThread->SetDebugState(state)))\r
+ {\r
+ if (state == THREAD_SUSPEND)\r
+ LOGW("%s %s", "SetDebugState(THREAD_SUSPEND) during eval setup failed.",\r
+ "This may change the state of the process and any breakpoints and exceptions encountered will be skipped.");\r
+ else\r
+ LOGW("SetDebugState(THREAD_RUN) during eval failed. Process state was not restored.");\r
+ }\r
}\r
+ iCorThread.Free();\r
}\r
};\r
\r
// All CoreCLR releases at least till version 3.1.3, don't have proper x86 implementation for ICorDebugEval::Abort().\r
// This issue looks like CoreCLR terminate managed process execution instead of abort evaluation.\r
\r
- // In this case we have same behaviour as MS vsdbg and MSVS C# debugger - run all user threads and try to abort eval by any cost.\r
+ // In this case we have same behaviour as MS vsdbg and MSVS C# debugger - run all managed threads and try to abort eval by any cost.\r
// Ignore errors here, this our last chance prevent debugger hangs.\r
iCorProcess->Stop(0);\r
ChangeThreadsState(THREAD_RUN);\r
m_isConfigurationDone(false),
m_sharedThreads(new Threads),
m_sharedModules(new Modules),
- m_sharedEvalWaiter(new EvalWaiter(m_sharedThreads)),
+ m_sharedEvalWaiter(new EvalWaiter),
m_sharedEvalHelpers(new EvalHelpers(m_sharedModules, m_sharedEvalWaiter)),
m_sharedEvalStackMachine(new EvalStackMachine),
m_sharedEvaluator(new Evaluator(m_sharedModules, m_sharedEvalHelpers, m_sharedEvalStackMachine)),