Repository: microsoft/ptvsd

Issue:
Step over a thread join hangs debugger
@dpoole73 commented on [Mon Apr 15 2019](https://github.com/Microsoft/vscode-python/issues/5293)

## Environment data

- VS Code version: 1.33.1
- Extension version (available under the Extensions sidebar): 1029-3-6558
- OS and version: MacOS version 10.14.4
- Python version (& distribution if applicable, e.g. Anaconda): 3.7.3
- Type of virtual environment used (N/A | venv | virtualenv | conda | ...): N/A (reproed with and without venv) 
- Relevant/affected Python packages and their versions: threading, time

## Expected behaviour

F10 (step over) a join operation should move to the next statement or block while threads run

## Actual behaviour

Step-over appears to hang the debugging until you break in and resume the thread showing "PAUSED ON PAUSE" status

## Steps to reproduce:

I have attached a gif with the steps below plus showing that it doesn't repro when continuing rather than stepping over.
![Untitled](https://user-images.githubusercontent.com/10601633/56171057-c36ed880-5f98-11e9-8ab9-ed69c92b655d.gif)

1. create a python file with the code below
```
import threading
import time

class RunThread(threading.Thread):
    kind = 'Thread'
    def __init__(self, name, fn, args = ()):
        threading.Thread.__init__(self)
        self.name = name
        self.fn   = fn
        self.args = args
        self.start()
    def run(self):
        self.fn(*(self.args))

def th1():
    while True:
        print('th1')
        time.sleep(1)

def th2():
    while True:
        print('th2')
        time.sleep(2)

def th3():
    while True:
        print('th3')
        time.sleep(4)

def main():
    threads = []
    threads.append(RunThread("aaa", th1))
    threads.append(RunThread("bbb", th2))
    threads.append(RunThread("ccc", th3))

    for t in threads:
        t.join()

if __name__ == '__main__':
    main()
```
1. Set breakpoint on line 37
1. Debug using the python current file default settings
1. when the breakpoint is hit, hit F10 (or step over).
1. after a few seconds break in by hitting pause, find the "PAUSED ON PAUSE" thread and continue it, execution will continue

The same thing doesn't happen if you continue rather than stepping over the join() call.

This impacts not only this scenario but seemingly anything that uses threads

## Logs
```
Starting Microsoft Python language server.
[Info  - 3:42:41 PM] GetCurrentSearchPaths /usr/local/opt/python/bin/python3.7 
[Info  - 3:42:42 PM] Python search paths:
[Info  - 3:42:42 PM]     /private/var/folders/mm/2w6btf515j36vd2s3_2p6j740000gn/T/sr2eql2k.px2
[Info  - 3:42:42 PM]     /usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7
[Info  - 3:42:42 PM]     /usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload
[Info  - 3:42:42 PM]     /Users/dpoole/Library/Python/3.7/lib/python/site-packages
[Info  - 3:42:42 PM]     /usr/local/lib/python3.7/site-packages
[Info  - 3:42:42 PM] Configuration search paths:
[Info  - 3:42:42 PM]     /usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python37.zip
[Info  - 3:42:42 PM]     /usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7
[Info  - 3:42:42 PM]     /usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload
[Info  - 3:42:42 PM]     /Users/dpoole/Library/Python/3.7/lib/python/site-packages
[Info  - 3:42:42 PM]     /usr/local/lib/python3.7/site-packages
[Info  - 3:42:42 PM]     /usr/local/opt/python/bin
[Info  - 3:42:42 PM] Microsoft Python Language Server version 0.2.47.0
[Info  - 3:42:42 PM] Initializing for /usr/local/opt/python/bin/python3.7
```
# Console

```
dpoole@dpoole-mac:/private/tmp/repro $ cd /private/tmp/repro ; env PYTHONIOENCODING=UTF-8 PYTHONUNBUFFERED=1 /usr/local/opt/python/bin/python3.7 /Users/dpoole/.vscode/extensions/ms-python.python-2019.3.6558/pythonFiles/ptvsd_launcher.py --default --client --host localhost --port 54810 /private/tmp/repro/repro.py 
th3th2
```





Discussion:

Resolving patch:
diff --git a/src/ptvsd/wrapper.py b/src/ptvsd/wrapper.py
--- a/src/ptvsd/wrapper.py
+++ b/src/ptvsd/wrapper.py
@@ -1887,7 +1887,8 @@ def on_pydevd_thread_resume_single_notification(self, seq, args):
         except KeyError:
             pass
         else:
-            self.send_event('continued', threadId=vsc_tid)
+            if os.getenv('PTVSD_USE_CONTINUED'):
+                self.send_event('continued', threadId=vsc_tid)
 
     @pydevd_events.handler(pydevd_comm.CMD_SEND_CURR_EXCEPTION_TRACE)
     def on_pydevd_send_curr_exception_trace(self, seq, args):


Test patch:
diff --git a/tests/func/test_attach.py b/tests/func/test_attach.py
--- a/tests/func/test_attach.py
+++ b/tests/func/test_attach.py
@@ -33,7 +33,6 @@ def test_attach(run_as, wait_for_attach, is_attached, break_into):
         session.initialize(
             target=(run_as, testfile),
             start_method='launch',
-            ignore_unobserved=[Event('continued')],
             env=env,
             use_backchannel=True,
         )
@@ -85,7 +84,6 @@ def code_to_debug():
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
             use_backchannel=True,
             kill_ptvsd=False,
             skip_capture=True,
@@ -128,7 +126,6 @@ def do_something(i):
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
         )
         session.set_breakpoints(code_to_debug, [bp_line])
         session.start_debugging()
diff --git a/tests/func/test_break_into_dbg.py b/tests/func/test_break_into_dbg.py
--- a/tests/func/test_break_into_dbg.py
+++ b/tests/func/test_break_into_dbg.py
@@ -7,7 +7,6 @@
 import pytest
 import sys
 from tests.helpers.session import DebugSession
-from tests.helpers.timeline import Event
 
 
 @pytest.mark.parametrize('run_as', ['file', 'module', 'code'])
@@ -27,7 +26,6 @@ def code_to_debug():
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')]
         )
         session.start_debugging()
         hit = session.wait_for_thread_stopped()
@@ -55,7 +53,6 @@ def code_to_debug():
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')]
         )
         session.start_debugging()
         hit = session.wait_for_thread_stopped()
diff --git a/tests/func/test_breakpoints.py b/tests/func/test_breakpoints.py
--- a/tests/func/test_breakpoints.py
+++ b/tests/func/test_breakpoints.py
@@ -29,7 +29,6 @@ def test_path_with_ampersand(run_as, start_method):
         session.initialize(
             target=(run_as, testfile),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
         )
         session.set_breakpoints(testfile, [bp_line])
         session.start_debugging()
@@ -53,7 +52,6 @@ def test_path_with_unicode(run_as, start_method):
         session.initialize(
             target=(run_as, testfile),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
         )
         session.set_breakpoints(testfile, [bp_line])
         session.start_debugging()
@@ -101,7 +99,6 @@ def code_to_debug():
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
         )
         session.send_request('setBreakpoints', arguments={
             'source': {'path': code_to_debug},
@@ -155,7 +152,6 @@ def script2():
         session.initialize(
             target=(run_as, script2),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
         )
         session.set_breakpoints(script1, lines=[bp_script1_line])
         session.set_breakpoints(script2, lines=[bp_script2_line])
@@ -203,7 +199,6 @@ def do_something_bad():
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
         )
         session.send_request('setBreakpoints', arguments={
             'source': {'path': code_to_debug},
@@ -240,7 +235,6 @@ def code_to_debug():
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
         )
         session.send_request('setBreakpoints', arguments={
             'source': {'path': code_to_debug},
@@ -288,7 +282,6 @@ def code_to_debug():
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
         )
         session.send_request('setBreakpoints', arguments={
             'source': {'path': code_to_debug},
@@ -349,7 +342,6 @@ def test_package_launch():
         session.initialize(
             target=('module', 'pkg1'),
             start_method='launch',
-            ignore_unobserved=[Event('continued')],
             cwd=cwd,
         )
         session.set_breakpoints(testfile, [bp_line])
@@ -378,7 +370,6 @@ def code_to_debug():
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
             use_backchannel=True,
         )
         session.set_breakpoints(code_to_debug, [bp_line])
@@ -431,7 +422,6 @@ def code_to_debug():
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
         )
 
         requested_bps = [
@@ -500,7 +490,6 @@ def deep_stack(level):
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
         )
 
         bp_line = line_numbers['bp']
diff --git a/tests/func/test_completions.py b/tests/func/test_completions.py
--- a/tests/func/test_completions.py
+++ b/tests/func/test_completions.py
@@ -60,7 +60,7 @@ def someFunction(someVar):
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('stopped'), Event('continued')],
+            ignore_unobserved=[Event('stopped')],
         )
 
         line_numbers = get_marked_line_numbers(code_to_debug)
@@ -114,7 +114,6 @@ def code_to_debug():
         session.initialize(
             target=(run_as, bp_file),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
         )
         session.set_breakpoints(bp_file, [bp_line])
         session.start_debugging()
diff --git a/tests/func/test_disconnect.py b/tests/func/test_disconnect.py
--- a/tests/func/test_disconnect.py
+++ b/tests/func/test_disconnect.py
@@ -24,7 +24,7 @@ def code_to_debug():
         session.initialize(
                 target=(run_as, code_to_debug),
                 start_method=start_method,
-                ignore_unobserved=[Event('continued'), Event('exited'), Event('terminated')],
+                ignore_unobserved=[Event('exited'), Event('terminated')],
                 use_backchannel=True,
             )
         session.set_breakpoints(code_to_debug, [bp_line])
@@ -54,7 +54,6 @@ def code_to_debug():
         session.initialize(
                 target=(run_as, code_to_debug),
                 start_method=start_method,
-                ignore_unobserved=[Event('continued')],
                 use_backchannel=True,
                 expected_returncode=ANY.int,
             )
diff --git a/tests/func/test_django.py b/tests/func/test_django.py
--- a/tests/func/test_django.py
+++ b/tests/func/test_django.py
@@ -39,7 +39,6 @@ def test_django_breakpoint_no_multiproc(bp_target, start_method):
             debug_options=['Django'],
             cwd=DJANGO1_ROOT,
             expected_returncode=ANY.int,  # No clean way to kill Django server
-            ignore_unobserved=[Event('continued')],
         )
 
         bp_var_content = 'Django-Django-Test'
@@ -105,7 +104,6 @@ def test_django_template_exception_no_multiproc(start_method):
             debug_options=['Django'],
             cwd=DJANGO1_ROOT,
             expected_returncode=ANY.int,  # No clean way to kill Django server
-            ignore_unobserved=[Event('continued')],
         )
 
         session.send_request('setExceptionBreakpoints', arguments={
@@ -181,7 +179,6 @@ def test_django_exception_no_multiproc(ex_type, start_method):
             debug_options=['Django'],
             cwd=DJANGO1_ROOT,
             expected_returncode=ANY.int,  # No clean way to kill Django server
-            ignore_unobserved=[Event('continued')],
         )
 
         session.send_request('setExceptionBreakpoints', arguments={
@@ -260,7 +257,7 @@ def test_django_breakpoint_multiproc(start_method):
             program_args=['runserver'],
             debug_options=['Django'],
             cwd=DJANGO1_ROOT,
-            ignore_unobserved=[Event('stopped'), Event('continued')],
+            ignore_unobserved=[Event('stopped')],
             expected_returncode=ANY.int,  # No clean way to kill Django server
         )
 
diff --git a/tests/func/test_evaluate.py b/tests/func/test_evaluate.py
--- a/tests/func/test_evaluate.py
+++ b/tests/func/test_evaluate.py
@@ -9,7 +9,6 @@
 from tests.helpers import get_marked_line_numbers, print
 from tests.helpers.pattern import ANY
 from tests.helpers.session import DebugSession
-from tests.helpers.timeline import Event
 
 
 def test_variables_and_evaluate(pyfile, run_as, start_method):
@@ -30,7 +29,6 @@ def code_to_debug():
         session.initialize(
             target=(run_as, bp_file),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
         )
         session.set_breakpoints(bp_file, [bp_line])
         session.start_debugging()
@@ -123,7 +121,6 @@ def code_to_debug():
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
             use_backchannel=True,
         )
         session.start_debugging()
@@ -192,7 +189,6 @@ def code_to_debug():
         session.initialize(
             target=(run_as, bp_file),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
         )
         session.set_breakpoints(bp_file, [bp_line])
         session.start_debugging()
@@ -288,7 +284,7 @@ def my_func():
             target=(run_as, code_to_debug),
             start_method=start_method,
             debug_options=['ShowReturnValue'],
-            ignore_unobserved=[Event('continued')])
+        )
         session.set_breakpoints(code_to_debug, [line_numbers['bp']])
         session.start_debugging()
         hit = session.wait_for_thread_stopped()
@@ -349,7 +345,6 @@ def code_to_debug():
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
         )
         session.start_debugging()
         hit = session.wait_for_thread_stopped()
@@ -391,7 +386,6 @@ def code_to_debug():
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
         )
         session.set_breakpoints(code_to_debug, [line_numbers['bp']])
         session.start_debugging()
diff --git a/tests/func/test_exception.py b/tests/func/test_exception.py
--- a/tests/func/test_exception.py
+++ b/tests/func/test_exception.py
@@ -38,7 +38,6 @@ def raise_with_except():
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
         )
         session.send_request('setExceptionBreakpoints', {
             'filters': filters
@@ -96,7 +95,7 @@ def raise_without_except():
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('continued'), Event('stopped')],
+            ignore_unobserved=[Event('stopped')],
             expected_returncode=ANY.int,
         )
         session.send_request('setExceptionBreakpoints', {
@@ -194,7 +193,6 @@ def code_to_debug():
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
             expected_returncode=ANY.int,
         )
         session.send_request('setExceptionBreakpoints', {
@@ -286,7 +284,7 @@ def code_to_debug():
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('continued'), Event('stopped')],
+            ignore_unobserved=[Event('stopped')],
             expected_returncode=ANY.int,
         )
         path = [
@@ -330,7 +328,6 @@ def code_to_debug():
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
             expected_returncode=exit_code,
         )
         session.send_request('setExceptionBreakpoints', {
@@ -381,7 +378,6 @@ def do_something2(n):
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
             expected_returncode=ANY.int,
             args=args,
         )
diff --git a/tests/func/test_exclude_rules.py b/tests/func/test_exclude_rules.py
--- a/tests/func/test_exclude_rules.py
+++ b/tests/func/test_exclude_rules.py
@@ -6,7 +6,6 @@
 
 from tests.helpers import print, get_marked_line_numbers
 from tests.helpers.session import DebugSession
-from tests.helpers.timeline import Event
 from tests.helpers.pattern import ANY, Path
 from os.path import os
 import pytest
@@ -54,7 +53,6 @@ def code_to_debug():
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
             rules=rules,
         )
         # TODO: The process returncode doesn't match the one returned from the DAP.
@@ -115,7 +113,6 @@ def call_func():
             target=(run_as, code_to_debug),
             start_method=start_method,
             use_backchannel=True,
-            ignore_unobserved=[Event('continued')],
             rules=rules,
         )
         # TODO: The process returncode doesn't match the one returned from the DAP.
diff --git a/tests/func/test_flask.py b/tests/func/test_flask.py
--- a/tests/func/test_flask.py
+++ b/tests/func/test_flask.py
@@ -41,7 +41,7 @@ def _initialize_flask_session_no_multiproc(session, start_method):
         start_method=start_method,
         target=('module', 'flask'),
         program_args=['run', '--no-debugger', '--no-reload', '--with-threads', '--port', str(FLASK_PORT)],
-        ignore_unobserved=[Event('stopped'), Event('continued')],
+        ignore_unobserved=[Event('stopped')],
         debug_options=['Jinja'],
         cwd=FLASK1_ROOT,
         env=env,
@@ -280,7 +280,7 @@ def test_flask_breakpoint_multiproc(start_method):
             target=('module', 'flask'),
             multiprocess=True,
             program_args=['run', '--port', str(FLASK_PORT)],
-            ignore_unobserved=[Event('stopped'), Event('continued')],
+            ignore_unobserved=[Event('stopped')],
             debug_options=['Jinja'],
             cwd=FLASK1_ROOT,
             env=env,
diff --git a/tests/func/test_justmycode.py b/tests/func/test_justmycode.py
--- a/tests/func/test_justmycode.py
+++ b/tests/func/test_justmycode.py
@@ -8,7 +8,6 @@
 
 from tests.helpers import print, get_marked_line_numbers
 from tests.helpers.session import DebugSession
-from tests.helpers.timeline import Event
 from tests.helpers.pattern import ANY, Path
 
 @pytest.mark.parametrize('jmc', ['jmcOn', 'jmcOff'])
@@ -24,7 +23,6 @@ def code_to_debug():
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
             debug_options=[] if jmc == 'jmcOn' else ['DebugStdLib']
         )
 
diff --git a/tests/func/test_multiproc.py b/tests/func/test_multiproc.py
--- a/tests/func/test_multiproc.py
+++ b/tests/func/test_multiproc.py
@@ -277,7 +277,6 @@ def child():
             start_method=start_method,
             program_args=[child],
             use_backchannel=True,
-            ignore_unobserved=[Event('continued')],
         )
 
         session.start_debugging()
diff --git a/tests/func/test_output.py b/tests/func/test_output.py
--- a/tests/func/test_output.py
+++ b/tests/func/test_output.py
@@ -40,7 +40,6 @@ def code_to_debug():
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
         )
 
         session.set_breakpoints(code_to_debug, [line_numbers['bp1']])
diff --git a/tests/func/test_path_mapping.py b/tests/func/test_path_mapping.py
--- a/tests/func/test_path_mapping.py
+++ b/tests/func/test_path_mapping.py
@@ -8,7 +8,6 @@
 from shutil import copyfile
 from tests.helpers.pattern import Path
 from tests.helpers.session import DebugSession
-from tests.helpers.timeline import Event
 from tests.helpers.pathutils import get_test_root
 from tests.helpers import get_marked_line_numbers
 import pytest
@@ -36,7 +35,6 @@ def code_to_debug():
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
             use_backchannel=True,
             path_mappings=[{
                 'localRoot': 'C:\\TEMP\\src',
@@ -84,7 +82,6 @@ def code_to_debug():
         session.initialize(
             target=(run_as, path_remote),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
             use_backchannel=True,
             path_mappings=[{
                 'localRoot': dir_local,
@@ -145,7 +142,6 @@ def call_func():
         session.initialize(
             target=(run_as, path_remote),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
             use_backchannel=True,
             path_mappings=[{
                 'localRoot': dir_local,
diff --git a/tests/func/test_run.py b/tests/func/test_run.py
--- a/tests/func/test_run.py
+++ b/tests/func/test_run.py
@@ -56,7 +56,6 @@ def test_run_submodule():
         session.initialize(
             target=('module', 'pkg1.sub'),
             start_method='launch',
-            ignore_unobserved=[Event('continued')],
             cwd=cwd,
         )
         session.start_debugging()
diff --git a/tests/func/test_set_expression.py b/tests/func/test_set_expression.py
--- a/tests/func/test_set_expression.py
+++ b/tests/func/test_set_expression.py
@@ -2,7 +2,6 @@
 
 from tests.helpers.pattern import ANY
 from tests.helpers.session import DebugSession
-from tests.helpers.timeline import Event
 
 
 def test_set_expression(pyfile, run_as, start_method):
@@ -21,7 +20,6 @@ def code_to_debug():
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
             use_backchannel=True,
         )
         session.start_debugging()
diff --git a/tests/func/test_start_stop.py b/tests/func/test_start_stop.py
--- a/tests/func/test_start_stop.py
+++ b/tests/func/test_start_stop.py
@@ -10,7 +10,6 @@
 
 from tests.helpers.pattern import ANY, Path
 from tests.helpers.session import DebugSession
-from tests.helpers.timeline import Event
 
 
 @pytest.mark.parametrize('start_method', ['launch'])
@@ -28,7 +27,6 @@ def code_to_debug():
             target=(run_as, code_to_debug),
             start_method=start_method,
             debug_options=['StopOnEntry'],
-            ignore_unobserved=[Event('continued')],
             use_backchannel=True,
         )
         session.start_debugging()
@@ -65,7 +63,6 @@ def code_to_debug():
             target=(run_as, code_to_debug),
             start_method=start_method,
             debug_options=['WaitOnNormalExit'],
-            ignore_unobserved=[Event('continued')],
             use_backchannel=True,
         )
         session.start_debugging()
@@ -108,7 +105,6 @@ def code_to_debug():
             target=(run_as, code_to_debug),
             start_method=start_method,
             debug_options=['WaitOnAbnormalExit'],
-            ignore_unobserved=[Event('continued')],
             use_backchannel=True,
         )
         session.start_debugging()
@@ -150,7 +146,6 @@ def code_to_debug():
             target=(run_as, code_to_debug),
             start_method=start_method,
             debug_options=['WaitOnAbnormalExit'],
-            ignore_unobserved=[Event('continued')],
             use_backchannel=True,
         )
         session.start_debugging()
diff --git a/tests/func/test_step.py b/tests/func/test_step.py
--- a/tests/func/test_step.py
+++ b/tests/func/test_step.py
@@ -34,6 +34,7 @@ def func():
             target=(run_as, code_to_debug),
             start_method=start_method,
             ignore_unobserved=[Event('continued')],
+            env={'PTVSD_USE_CONTINUED': '1'},
         )
         session.set_breakpoints(code_to_debug, [line_numbers['inner1']])
         session.start_debugging()
diff --git a/tests/func/test_stop_on_entry.py b/tests/func/test_stop_on_entry.py
--- a/tests/func/test_stop_on_entry.py
+++ b/tests/func/test_stop_on_entry.py
@@ -6,7 +6,6 @@
 
 from tests.helpers.pattern import Path
 from tests.helpers.session import DebugSession
-from tests.helpers.timeline import Event
 import pytest
 
 
@@ -23,7 +22,6 @@ def test_stop_on_entry(run_as, start_method, tmpdir):
         session.initialize(
             target=(run_as, str(testfile)),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
             debug_options=['StopOnEntry'],
         )
 
diff --git a/tests/func/test_threads.py b/tests/func/test_threads.py
--- a/tests/func/test_threads.py
+++ b/tests/func/test_threads.py
@@ -8,7 +8,6 @@
 import pytest
 
 from tests.helpers import get_marked_line_numbers
-from tests.helpers.timeline import Event
 from tests.helpers.session import DebugSession
 
 
@@ -42,7 +41,6 @@ def worker(tid, offset):
             target=(run_as, code_to_debug),
             start_method=start_method,
             program_args=[str(count)],
-            ignore_unobserved=[Event('continued')],
         )
         session.set_breakpoints(code_to_debug, [19])
         session.start_debugging()
@@ -98,7 +96,6 @@ def foo(x):
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('continued')],
         )
         session.set_breakpoints(code_to_debug, [line_numbers['bp']])
         session.start_debugging()
diff --git a/tests/func/test_vs_specific.py b/tests/func/test_vs_specific.py
--- a/tests/func/test_vs_specific.py
+++ b/tests/func/test_vs_specific.py
@@ -31,7 +31,7 @@ def do_something():
         session.initialize(
             target=(run_as, code_to_debug),
             start_method=start_method,
-            ignore_unobserved=[Event('stopped'), Event('continued')],
+            ignore_unobserved=[Event('stopped')],
         )
         session.set_breakpoints(test_module, [bp_line])
         session.start_debugging()
@@ -78,7 +78,7 @@ def test_code():
         session.initialize(
             target=(run_as, test_code),
             start_method=start_method,
-            ignore_unobserved=[Event('stopped'), Event('continued')],
+            ignore_unobserved=[Event('stopped')],
         )
         session.set_breakpoints(module2, [bp_line])
         session.start_debugging()
diff --git a/tests/helpers/session.py b/tests/helpers/session.py
--- a/tests/helpers/session.py
+++ b/tests/helpers/session.py
@@ -315,7 +315,13 @@ def initialize(self, **kwargs):
             print('Spawning %r' % dbg_argv)
 
         spawn_args = usr_argv if self.start_method == 'attach_pid' else dbg_argv
-        self.process = subprocess.Popen(spawn_args, env=self.env, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self.cwd)
+
+        # ensure env is all string, this is needed for python 2.7 on windows
+        temp_env = {}
+        for k, v in self.env.items():
+            temp_env[str(k)] = str(v)
+
+        self.process = subprocess.Popen(spawn_args, env=temp_env, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self.cwd)
         self.pid = self.process.pid
         self.psutil_process = psutil.Process(self.pid)
         self.is_running = True