MCPcopy Create free account
hub / github.com/fabioz/PyDev.Debugger / SuspendThreads

Function SuspendThreads

pydevd_attach_to_process/windows/attach.cpp:203–262  ·  view source on GitHub ↗

Suspends all threads ensuring that they are not currently in a call to Py_AddPendingCall.

Source from the content-addressed store, hash-verified

201
202// Suspends all threads ensuring that they are not currently in a call to Py_AddPendingCall.
203void SuspendThreads(ThreadMap &suspendedThreads, Py_AddPendingCall* addPendingCall, PyEval_ThreadsInitialized* threadsInited) {
204 DWORD curThreadId = GetCurrentThreadId();
205 DWORD curProcess = GetCurrentProcessId();
206 // suspend all the threads in the process so we can do things safely...
207 bool suspended;
208
209 do {
210 suspended = false;
211 HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
212 if (h != INVALID_HANDLE_VALUE) {
213
214 THREADENTRY32 te;
215 te.dwSize = sizeof(te);
216 if (Thread32First(h, &te)) {
217 do {
218 if (te.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(te.th32OwnerProcessID) && te.th32OwnerProcessID == curProcess) {
219
220
221 if (te.th32ThreadID != curThreadId && suspendedThreads.find(te.th32ThreadID) == suspendedThreads.end()) {
222 auto hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, te.th32ThreadID);
223 if (hThread != nullptr) {
224 SuspendThread(hThread);
225
226 bool addingPendingCall = false;
227
228 CONTEXT context;
229 memset(&context, 0x00, sizeof(CONTEXT));
230 context.ContextFlags = CONTEXT_ALL;
231 GetThreadContext(hThread, &context);
232
233#if defined(_X86_)
234 if (context.Eip >= *(reinterpret_cast<DWORD*>(addPendingCall)) && context.Eip <= (*(reinterpret_cast<DWORD*>(addPendingCall))) + 0x100) {
235 addingPendingCall = true;
236 }
237#elif defined(_AMD64_)
238 if (context.Rip >= *(reinterpret_cast<DWORD64*>(addPendingCall)) && context.Rip <= *(reinterpret_cast<DWORD64*>(addPendingCall) + 0x100)) {
239 addingPendingCall = true;
240 }
241#endif
242
243 if (addingPendingCall) {
244 // we appear to be adding a pending call via this thread - wait for this to finish so we can add our own pending call...
245 ResumeThread(hThread);
246 SwitchToThread(); // yield to the resumed thread if it's on our CPU...
247 CloseHandle(hThread);
248 } else {
249 suspendedThreads[te.th32ThreadID] = hThread;
250 }
251 suspended = true;
252 }
253 }
254 }
255
256 te.dwSize = sizeof(te);
257 } while (Thread32Next(h, &te) && !threadsInited());
258 }
259 CloseHandle(h);
260 }

Callers 1

attach.cppFile · 0.85

Calls 12

GetCurrentThreadIdFunction · 0.85
GetCurrentProcessIdFunction · 0.85
CreateToolhelp32SnapshotFunction · 0.85
Thread32FirstFunction · 0.85
OpenThreadFunction · 0.85
SuspendThreadFunction · 0.85
ResumeThreadFunction · 0.85
CloseHandleFunction · 0.85
Thread32NextFunction · 0.85
endMethod · 0.80
GetThreadContextFunction · 0.50
findMethod · 0.45

Tested by

no test coverage detected