diff --git a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/add_code_to_python_process.py b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/add_code_to_python_process.py index 2e328f617..a1a852a02 100644 --- a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/add_code_to_python_process.py +++ b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/add_code_to_python_process.py @@ -308,7 +308,7 @@ def run_python_code_windows(pid, python_code, connect_debugger_tracing=False, sh args = [target_executable, str(pid), target_dll_run_on_dllmain] subprocess.check_call(args) - if not event.wait_for_event_set(15): + if not event.wait_for_event_set(30): print("Timeout error: the attach may not have completed.") sys.stdout.flush() print("--- Finished dll injection ---\n") diff --git a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_amd64.dll b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_amd64.dll index 6f804e79f..c37fa3360 100644 Binary files a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_amd64.dll and b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_amd64.dll differ diff --git a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_amd64.pdb b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_amd64.pdb index db2eb3219..ddd7b302f 100644 Binary files a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_amd64.pdb and b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_amd64.pdb differ diff --git a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_linux_amd64.so b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_linux_amd64.so index 4203c0ae4..efcd65851 100755 Binary files a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_linux_amd64.so and b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_linux_amd64.so differ diff --git a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_linux_x86.so b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_linux_x86.so index 862b81e1c..4865512e4 100755 Binary files a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_linux_x86.so and b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_linux_x86.so differ diff --git a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_x86.dll b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_x86.dll index 9b3167269..01a300a2d 100644 Binary files a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_x86.dll and b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_x86.dll differ diff --git a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_x86.pdb b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_x86.pdb index 211572527..8d53b7294 100644 Binary files a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_x86.pdb and b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_x86.pdb differ diff --git a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_x86_64.dylib b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_x86_64.dylib index beef83e8e..581ac88a5 100644 Binary files a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_x86_64.dylib and b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_x86_64.dylib differ diff --git a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/common/py_utils.hpp b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/common/py_utils.hpp index 97163a4e2..132a07107 100644 --- a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/common/py_utils.hpp +++ b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/common/py_utils.hpp @@ -11,6 +11,7 @@ typedef PyThreadState* (PyInterpreterState_ThreadHead)(PyInterpreterState* inter typedef PyThreadState* (PyThreadState_Next)(PyThreadState *tstate); typedef PyThreadState* (PyThreadState_Swap)(PyThreadState *tstate); typedef PyThreadState* (_PyThreadState_UncheckedGet)(); +typedef PyThreadState* (_PyThreadState_GetCurrent)(); typedef PyObject* (PyObject_CallFunctionObjArgs)(PyObject *callable, ...); // call w/ varargs, last arg should be nullptr typedef PyObject* (PyInt_FromLong)(long); typedef PyObject* (PyErr_Occurred)(); diff --git a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/common/py_version.hpp b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/common/py_version.hpp index be736929f..712684cf3 100644 --- a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/common/py_version.hpp +++ b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/common/py_version.hpp @@ -21,7 +21,9 @@ enum PythonVersion { PythonVersion_38 = 0x0308, PythonVersion_39 = 0x0309, PythonVersion_310 = 0x030A, - PythonVersion_311 = 0x030B + PythonVersion_311 = 0x030B, + PythonVersion_312 = 0x030C, + PythonVersion_313 = 0x030D, }; @@ -70,6 +72,12 @@ static PythonVersion GetPythonVersion(void *module) { if(version[3] == '1'){ return PythonVersion_311; } + if(version[3] == '2'){ + return PythonVersion_312; + } + if(version[3] == '3'){ + return PythonVersion_313; + } } return PythonVersion_Unknown; // we don't care about 3.1 anymore... diff --git a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/inject_dll_amd64.exe b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/inject_dll_amd64.exe index 6211dcea6..6e8000f39 100644 Binary files a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/inject_dll_amd64.exe and b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/inject_dll_amd64.exe differ diff --git a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/inject_dll_amd64.pdb b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/inject_dll_amd64.pdb index a5892f1aa..6ee04b647 100644 Binary files a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/inject_dll_amd64.pdb and b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/inject_dll_amd64.pdb differ diff --git a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/inject_dll_x86.exe b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/inject_dll_x86.exe index b0c0275a9..48529e8dd 100644 Binary files a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/inject_dll_x86.exe and b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/inject_dll_x86.exe differ diff --git a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/inject_dll_x86.pdb b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/inject_dll_x86.pdb index bb4b0279e..37d8ed2a3 100644 Binary files a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/inject_dll_x86.pdb and b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/inject_dll_x86.pdb differ diff --git a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/run_code_on_dllmain_amd64.dll b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/run_code_on_dllmain_amd64.dll index 639eedbbc..b4f3886be 100644 Binary files a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/run_code_on_dllmain_amd64.dll and b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/run_code_on_dllmain_amd64.dll differ diff --git a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/run_code_on_dllmain_amd64.pdb b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/run_code_on_dllmain_amd64.pdb index b40bd07e6..d2d46c2f8 100644 Binary files a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/run_code_on_dllmain_amd64.pdb and b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/run_code_on_dllmain_amd64.pdb differ diff --git a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/run_code_on_dllmain_x86.dll b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/run_code_on_dllmain_x86.dll index d91c00c66..5f84608dc 100644 Binary files a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/run_code_on_dllmain_x86.dll and b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/run_code_on_dllmain_x86.dll differ diff --git a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/run_code_on_dllmain_x86.pdb b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/run_code_on_dllmain_x86.pdb index c63e18788..7890b9d09 100644 Binary files a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/run_code_on_dllmain_x86.pdb and b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/run_code_on_dllmain_x86.pdb differ diff --git a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/windows/attach.cpp b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/windows/attach.cpp index e44c6e147..6ce81c173 100644 --- a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/windows/attach.cpp +++ b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/windows/attach.cpp @@ -41,7 +41,6 @@ // Access to std::cout and std::endl #include -#include // DECLDIR will perform an export for us #define DLL_EXPORT @@ -108,9 +107,9 @@ struct InitializeThreadingInfo { PyImport_ImportModule* pyImportMod; PyEval_Lock* initThreads; - std::mutex mutex; - HANDLE initedEvent; // Note: only access with mutex locked (and check if not already nullptr). - bool completed; // Note: only access with mutex locked + CRITICAL_SECTION cs; + HANDLE initedEvent; // Note: only access with cs locked (and check if not already nullptr). + bool completed; // Note: only access with cs locked }; @@ -122,12 +121,12 @@ int AttachCallback(void *voidInitializeThreadingInfo) { initializeThreadingInfo->initThreads(); // Note: calling multiple times is ok. initializeThreadingInfo->pyImportMod("threading"); - initializeThreadingInfo->mutex.lock(); + EnterCriticalSection(&initializeThreadingInfo->cs); + initializeThreadingInfo->completed = true; if(initializeThreadingInfo->initedEvent != nullptr) { SetEvent(initializeThreadingInfo->initedEvent); } - initializeThreadingInfo->completed = true; - initializeThreadingInfo->mutex.unlock(); + LeaveCriticalSection(&initializeThreadingInfo->cs); return 0; } @@ -311,6 +310,11 @@ extern "C" // Either _PyThreadState_Current or _PyThreadState_UncheckedGet are required DEFINE_PROC_NO_CHECK(curPythonThread, PyThreadState**, "_PyThreadState_Current", -220); // optional DEFINE_PROC_NO_CHECK(getPythonThread, _PyThreadState_UncheckedGet*, "_PyThreadState_UncheckedGet", -230); // optional + DEFINE_PROC_NO_CHECK(getPythonThread13, _PyThreadState_GetCurrent*, "_PyThreadState_GetCurrent", -231); // optional + if (getPythonThread == nullptr && getPythonThread13 != nullptr) { + std::cout << "Using Python 3.13 or later, using _PyThreadState_GetCurrent" << std::endl << std::flush; + getPythonThread = getPythonThread13; + } if (curPythonThread == nullptr && getPythonThread == nullptr) { // we're missing some APIs, we cannot attach. @@ -318,6 +322,7 @@ extern "C" return -240; } + // Either _Py_CheckInterval or _PyEval_[GS]etSwitchInterval are useful, but not required DEFINE_PROC_NO_CHECK(intervalCheck, int*, "_Py_CheckInterval", -250); // optional DEFINE_PROC_NO_CHECK(getSwitchInterval, _PyEval_GetSwitchInterval*, "_PyEval_GetSwitchInterval", -260); // optional @@ -368,6 +373,8 @@ extern "C" initializeThreadingInfo->pyImportMod = pyImportMod; initializeThreadingInfo->initThreads = initThreads; initializeThreadingInfo->initedEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr); + InitializeCriticalSection(&initializeThreadingInfo->cs); + // Add the call to initialize threading. addPendingCall(&AttachCallback, initializeThreadingInfo); @@ -375,15 +382,16 @@ extern "C" ::WaitForSingleObject(initializeThreadingInfo->initedEvent, 5000); // Whether this completed or not, release the event handle as we won't use it anymore. - initializeThreadingInfo->mutex.lock(); + EnterCriticalSection(&initializeThreadingInfo->cs); CloseHandle(initializeThreadingInfo->initedEvent); bool completed = initializeThreadingInfo->completed; initializeThreadingInfo->initedEvent = nullptr; - initializeThreadingInfo->mutex.unlock(); + LeaveCriticalSection(&initializeThreadingInfo->cs); if(completed) { // Note that this structure will leak if addPendingCall did not complete in the timeout // (we can't release now because it's possible that it'll still be called). + DeleteCriticalSection(&initializeThreadingInfo->cs); delete initializeThreadingInfo; if (showDebugInfo) { std::cout << "addPendingCall to initialize threads/import threading completed. " << std::endl << std::flush; diff --git a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/windows/compile_windows.bat b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/windows/compile_windows.bat index a7e12471b..605ec9693 100644 --- a/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/windows/compile_windows.bat +++ b/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/windows/compile_windows.bat @@ -7,7 +7,7 @@ setlocal @set VSWHERE=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe @echo Using vswhere at %VSWHERE% -@for /f "usebackq tokens=*" %%i in (`"%VSWHERE%" -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do set VSDIR=%%i +@for /f "usebackq tokens=*" %%i in (`"%VSWHERE%" -prerelease -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do set VSDIR=%%i @echo Using Visual C++ at %VSDIR% call "%VSDIR%\VC\Auxiliary\Build\vcvarsall.bat" x86 -vcvars_spectre_libs=spectre diff --git a/tests/debugpy/test_attach.py b/tests/debugpy/test_attach.py index afabc1acf..017d7f595 100644 --- a/tests/debugpy/test_attach.py +++ b/tests/debugpy/test_attach.py @@ -12,7 +12,7 @@ @pytest.mark.parametrize("stop_method", ["breakpoint", "pause"]) @pytest.mark.parametrize("is_client_connected", ["is_client_connected", ""]) -@pytest.mark.parametrize("wait_for_client", ["wait_for_client", ""]) +@pytest.mark.parametrize("wait_for_client", ["wait_for_client", pytest.param("", marks=pytest.mark.skipif(sys.platform.startswith("darwin"), reason="Flakey test on Mac"))]) def test_attach_api(pyfile, wait_for_client, is_client_connected, stop_method): @pyfile def code_to_debug():