-
Notifications
You must be signed in to change notification settings - Fork 68
If threading is not imported in main thread, attach to pid does not work properly. #1542
Comments
As a note, I've also reported this to CPython: https://bugs.python.org/issue37416 |
I remember now that we had to deal with that exact problem in PyDebugAttach, and also in the old ptvsd. So the way those two worked in conjunction is that PyDebugAttach made sure that threads are initialized without importing The crucial part there was that at no point |
Well, we actually do use that code in the attach to pid (so, we initialize the low-level threading facilities the same way), the difference is that ptvsd really delays loading Still, I think lazy-loading threading is not really a good solution, the main reasons being: I think that if the user does not use the Also, there's still the case where even lazy-loading And to finish, I remember that delaying the load of I was thinking a bit about this and I think we should be able to just fix the threading module to have the proper info if we detect that we were the first to initialize it and the main thread is not the correct thread (i.e.: I think we can get the needed info from the CPython API and fix |
Or maybe a different approach would be just initializing Instead of simply doing the |
I tried to go through the Now, this got me thinking a bit more about the actual problem... the real reason we don't attach properly is because we're now using threading.enumerate() to get the ids of the threads to trace, but it should be possible to get all the thread ids through Then, in the case where |
Looking at the implementation of |
We need to initialize threading on the main thread as well. But doesn't it already do so via |
In practice, what I see is that the threads are not initialized through the On Python 2.7 In Python 3.7 the initial check for So, in practice it seems that all that code to use I'm not actually sure why in Python 3.7 it's already initialized before (I haven't actually made a debug version to check, but it seems that just getting the gil could do it: https://github.com/python/cpython/blob/36456df13843c5b8a1fb5a6022ab9ed1fe2a11c5/Python/pystate.c#L1275) -- and that's probably good because otherwise we woudn't be able to connect on cases where the main thread is not actually running because our callback to |
I think that going that way can be an option, but I don't think we should tackle that right now (as you said, it can be a bit on the flaky side and each Python version is probably different). |
Maybe the right approach is trying to use the |
On 3.7+, the threads are always initialized because |
I was doing some manual testing for the attach to pid and in this situation, if the user never imported
threading
, we don't currently set the tracing properly.The main reason for this is that
threading
seems to expect that it's imported from the actual main thread and not from another thread (because presumably one would importthreading
to create a thread in the first place) and it creates the initial_MainThread
with the current thread (even if that's not the actual main thread).Now, in the attach to pid, what happens is that we create a thread on the target process and then call the
settrace
in that thread... and ifthreading
was never imported it'll consider that dummy thread as the main thread because we importthreading
in the dummy thread and the actual main thread will not be visible tothreading.enumerate()
.I still don't know the best way to overcome this...
Additional notes:
threading
not insys.modules
during the attach.threading
and we happen to stop in the wrong thread, then we'd importthreading
in the wrong thread).The text was updated successfully, but these errors were encountered: