Ptvs: Multi threaded program is not debuggable properly

Created on 8 Apr 2019  Â·  4Comments  Â·  Source: microsoft/PTVS

I was trying to debug the attached script. This script is written for practicing multi-threading. To view each & every details of how threading is being worked I wrote this script and started debugging. But the debugger is not been able to start all the thread. Before starting all the threads it starts executing the 1st thread's target function which it should not supposed to do

To reproduce the problem please re-run the following python script and put debugger as per the screenshot provided

Please note that PyCharm Community Edition is doing this debugging properly.

Program Details: Microsoft Visual Studio Community Edition 2019
Version 16.0.0
Python 16.0.19074.1
Python Base Version 3.7.2

==========================================================

import threading
import time

thread_lock = threading.Lock()
COUNT = 20
global_variable = 0


def inc_by_1():
    global global_variable
    with thread_lock:
        for i in range(COUNT):
            global_variable += 1


def inc_by_4():
    global global_variable
    with thread_lock:
        for i in range(COUNT):
            global_variable += 4


def dec_by_1():
    global global_variable
    with thread_lock:
        for i in range(COUNT):
            global_variable -= 1


def dec_by_2():
    global global_variable
    with thread_lock:
        for i in range(COUNT):
            global_variable -= 2


def dec_by_2_again():
    global global_variable
    with thread_lock:
        for i in range(COUNT):
            global_variable -= 2


t1 = threading.Thread(target=inc_by_1)
t2 = threading.Thread(target=inc_by_4)
t3 = threading.Thread(target=dec_by_1)
t4 = threading.Thread(target=dec_by_2)
t5 = threading.Thread(target=dec_by_2_again)

t1.start()
t2.start()
t3.start()
t4.start()
t5.start()

print("Calling from main thread::\nCurrent value of global_variable is::: {0}".
      format(global_variable))

=======================ooooooooo============================

I'm sorry for writing code in this way as default code integrator was not working for my code.

image

Debugger (VSC) bug

All 4 comments

Hi Sajeeb

Thank you for the detailed report! It helped a lot.

In short, everything works as expected. Here's a couple things I want to mention:

  1. This program has race conditions because the threads are never joining, so they could still be running when the print statement is executed. You can resolve this by adding "t1.join() t2.join()…" before the print statement to ensure that all the threads have finished executing before the print statement is executed.

  2. Since this is multithreaded debugging, it can get a bit confusing. The debugger is trying to sequentially debug a process where multiple lines of code are executed simultaneously. When a multithreaded process is executed, the OS decides the thread switching schedule and allocates a specific amount of time (usually in milliseconds or less) to each thread. Due to differences in VS and PyCharm debugger, the thread switching schedule is altered which is why you see different results. Since PyCharm directly talks to the debugger (PyDev), it's usually able to execute more python lines of code than VS in the same amount of time, as specified in the thread switching schedule. VS uses PyDev as well, but it provides additional features that slows down debugging which usually leads to less python code executed in same amount of time.

The behavior you saw in PyCharm is that it quickly executed the main thread (before scheduled time was over) and then proceeded to execute the child threads. In VS, the main thread was executed until "t1.Start()" and then main thread ran out of thread time so it switched threads and started debugging "inc_by_1". These two cases are extremely vulnerable to race conditions so the ordering is not guaranteed. You can end up in a situation where the PyCharm debugger behaves like the VS debugger and the VS debugger behaves like the PyCharm debugger. Or you could end up in a case where "dec_by_2_again" starts debugging before "inc_by_1". It's very hard to predict this behavior.

This essentially boils down to the fact that PyCharm and VS are providing the same underlying debugging functionality, but the race conditions show different behavior. Both are equally valid and work as expected.

In VS, You can view which thread is currently being debugged by going to "Debug->Windows->Threads"

image

I'm extremely sorry for replying late.
Thank you very much for your kind attention. I understood your point of view. But I think I was unable to express my problem to the point. I think I should try again to express my problem.

The main problem is in VS2019 I have no control over the child threads. What I mean by that is suppose all the child threads t1,t2,... are in stack. Now I will select a child thread from thread queue and the target function listening to that thread will start executing. But here the problem started. The debugger freeze here and stop responding. To make is responsive again I need to pause the debugging and then resume that.

Where PyCharm does not freezes. When I select a thread function listening to that thread start executing while it was in the middle of execution of another function.

Is it happening due to differences in VS and PyCharm debugger?

Ah, okay. I see what you mean. This is indeed a bug.

Whenever the thread that is being debugged hits a case such as "thread_lock" and unable to proceed, VS will pause debugging on that thread. A user should be able to switch threads and continue debugging, but PTVS is not allowing the user to switch threads.

The current workaround is to press the pause button which resumes debugging the previous thread.

Thanks for reporting it!

You are most welcome. Again thanks for your support.

Was this page helpful?
0 / 5 - 0 ratings