We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Debugging with new_ptvsd is crashing because of TypeError: Struct()
<!-- Please search existing issues to avoid creating duplicates. -->

## Environment data

- VS Code version: 1.40.1
- Extension version (available under the Extensions sidebar): 2019.11.49689
- OS and version: RH7.6
- Python version (& distribution if applicable, e.g. Anaconda): 2.7.5

## Expected behaviour

Debugger works fine

## Actual behaviour

It crashes..
stack:
```
[root@rh01 ~]# /usr/bin/python /root/.vscode-server/extensions/ms-python.python-2019.11.49689/pythonFiles/lib/python/new_ptvsd/no_wheels/ptvsd/launcher /root/helloworld/helloworld.py 
E+00000.020: /handling microsoft/vscode-python#1 request "launch" from Adapter-1/
             Handler 'launch_request' (file u'/root/.vscode-server/extensions/ms-python.python-2019.11.49689/pythonFiles/lib/python/new_ptvsd/no_wheels/ptvsd/launcher/../../ptvsd/launcher/adapter.py', line 35)
             couldn't handle microsoft/vscode-python#1 request "launch" from Adapter-1:
             
             Traceback (most recent call last):
               File "/root/.vscode-server/extensions/ms-python.python-2019.11.49689/pythonFiles/lib/python/new_ptvsd/no_wheels/ptvsd/launcher/../../ptvsd/common/messaging.py", line 763, in _handle
                 result = handler(self)
               File "/root/.vscode-server/extensions/ms-python.python-2019.11.49689/pythonFiles/lib/python/new_ptvsd/no_wheels/ptvsd/launcher/../../ptvsd/launcher/adapter.py", line 147, in launch_request
                 debuggee.spawn(process_name, cmdline, cwd, env, redirect_output)
               File "/root/.vscode-server/extensions/ms-python.python-2019.11.49689/pythonFiles/lib/python/new_ptvsd/no_wheels/ptvsd/launcher/../../ptvsd/launcher/debuggee.py", line 76, in spawn
                 "pointerSize": struct.calcsize("P") * 8,
             TypeError: Struct() argument 1 must be string, not unicode
             
             Stack where logged:
               File "/usr/lib64/python2.7/threading.py", line 785, in __bootstrap
                 self.__bootstrap_inner()
               File "/usr/lib64/python2.7/threading.py", line 812, in __bootstrap_inner
                 self.run()
               File "/usr/lib64/python2.7/threading.py", line 765, in run
                 self.__target(*self.__args, **self.__kwargs)
               File "/root/.vscode-server/extensions/ms-python.python-2019.11.49689/pythonFiles/lib/python/new_ptvsd/no_wheels/ptvsd/launcher/../../ptvsd/common/messaging.py", line 1520, in _run_handlers
                 handler()
               File "/root/.vscode-server/extensions/ms-python.python-2019.11.49689/pythonFiles/lib/python/new_ptvsd/no_wheels/ptvsd/launcher/../../ptvsd/common/messaging.py", line 809, in _handle
                 self.describe(),
```

## Steps to reproduce:

1. Just F5 to debug.
2. Getting this error
3. also getting an error to check launch,json - Launcher[1] disconnected unexpectedly
4. launcher is somehow still listening in the background

ps x | grep ptvsd
```
 9815 pts/3    S      0:00 /usr/bin/python /root/.vscode-server/extensions/ms-python.python-2019.11.49689/pythonFiles/lib/python/new_ptvsd/no_wheels/ptvsd --client --host 127.0.0.1 --port 41995 /root/helloworld/helloworld.py
 9869 pts/3    S      0:00 /usr/bin/python /root/.vscode-server/extensions/ms-python.python-2019.11.49689/pythonFiles/lib/python/new_ptvsd/no_wheels/ptvsd --client --host 127.0.0.1 --port 39855 /root/helloworld/helloworld.py

```
5. **it is verified to be working with the previous release of python extension** which does not make use of ptvsd_new


launch.json contents:
```
{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Current File",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal"
        }
    ]
}
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/ptvsd/launcher/debuggee.py`
Content:
```
1 # Copyright (c) Microsoft Corporation. All rights reserved.
2 # Licensed under the MIT License. See LICENSE in the project root
3 # for license information.
4 
5 from __future__ import absolute_import, division, print_function, unicode_literals
6 
7 import atexit
8 import locale
9 import os
10 import struct
11 import subprocess
12 import sys
13 import threading
14 
15 from ptvsd.common import fmt, log, messaging
16 
17 
18 process = None
19 """subprocess.Popen instance for the debuggee process."""
20 
21 wait_on_exit_predicates = []
22 """List of functions that determine whether to pause after debuggee process exits.
23 
24 Every function is invoked with exit code as the argument. If any of the functions
25 returns True, the launcher pauses and waits for user input before exiting.
26 """
27 
28 
29 def describe():
30     return fmt("debuggee process with PID={0}", process.pid)
31 
32 
33 def spawn(process_name, cmdline, cwd, env, redirect_output):
34     from ptvsd.launcher import adapter, output
35 
36     log.info(
37         "Spawning debuggee process:\n\n"
38         "Current directory: {0!j}\n\n"
39         "Command line: {1!j}\n\n"
40         "Environment variables: {2!j}\n\n",
41         cwd,
42         cmdline,
43         env,
44     )
45 
46     close_fds = set()
47     try:
48         if redirect_output:
49             # subprocess.PIPE behavior can vary substantially depending on Python version
50             # and platform; using our own pipes keeps it simple, predictable, and fast.
51             stdout_r, stdout_w = os.pipe()
52             stderr_r, stderr_w = os.pipe()
53             close_fds |= {stdout_r, stdout_w, stderr_r, stderr_w}
54             kwargs = dict(stdout=stdout_w, stderr=stderr_w)
55         else:
56             kwargs = {}
57 
58         try:
59             global process
60             process = subprocess.Popen(cmdline, cwd=cwd, env=env, bufsize=0, **kwargs)
61         except Exception as exc:
62             raise messaging.Message.cant_handle(
63                 "Couldn't spawn debuggee: {0}\n\nCommand line:{1!r}", exc, cmdline
64             )
65 
66         log.info("Spawned {0}.", describe())
67         atexit.register(kill)
68         adapter.channel.send_event(
69             "process",
70             {
71                 "startMethod": "launch",
72                 "isLocalProcess": True,
73                 "systemProcessId": process.pid,
74                 "name": process_name,
75                 "pointerSize": struct.calcsize("P") * 8,
76             },
77         )
78 
79         if redirect_output:
80             encoding = env.get("PYTHONIOENCODING", locale.getpreferredencoding())
81             for category, fd, tee in [
82                 ("stdout", stdout_r, sys.stdout),
83                 ("stderr", stderr_r, sys.stderr),
84             ]:
85                 output.CaptureOutput(category, fd, tee.fileno(), encoding)
86                 close_fds.remove(fd)
87 
88         wait_thread = threading.Thread(target=wait_for_exit, name="wait_for_exit()")
89         wait_thread.daemon = True
90         wait_thread.start()
91 
92     finally:
93         for fd in close_fds:
94             try:
95                 os.close(fd)
96             except Exception:
97                 log.exception()
98 
99 
100 def kill():
101     if process is None:
102         return
103     try:
104         if process.poll() is None:
105             log.info("Killing {0}", describe())
106             process.kill()
107     except Exception:
108         log.exception("Failed to kill {0}", describe())
109 
110 
111 def wait_for_exit():
112     from ptvsd.launcher import adapter, output
113 
114     try:
115         code = process.wait()
116         if sys.platform != "win32" and code < 0:
117             # On POSIX, if the process was terminated by a signal, Popen will use
118             # a negative returncode to indicate that - but the actual exit code of
119             # the process is always an unsigned number, and can be determined by
120             # taking the lowest 8 bits of that negative returncode.
121             code &= 0xFF
122     except Exception:
123         log.exception("Couldn't determine process exit code:")
124         code = -1
125 
126     log.info("{0} exited with code {1}", describe(), code)
127     output.wait_for_remaining_output()
128     try:
129         adapter.channel.send_event("exited", {"exitCode": code})
130     except Exception:
131         pass
132 
133     if any(pred(code) for pred in wait_on_exit_predicates):
134         _wait_for_user_input()
135 
136     try:
137         adapter.channel.send_event("terminated")
138     except Exception:
139         pass
140 
141 
142 def _wait_for_user_input():
143     if sys.stdout and sys.stdin:
144         from ptvsd.common import log
145 
146         can_getch = sys.stdin.isatty()
147         if can_getch:
148             try:
149                 import msvcrt
150             except ImportError:
151                 can_getch = False
152 
153         if can_getch:
154             log.debug("msvcrt available - waiting for user input via getch()")
155             sys.stdout.write("Press any key to continue . . . ")
156             sys.stdout.flush()
157             msvcrt.getch()
158         else:
159             log.debug("msvcrt not available - waiting for user input via read()")
160             sys.stdout.write("Press Enter to continue . . . ")
161             sys.stdout.flush()
162             sys.stdin.read(1)
163
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/ptvsd/launcher/debuggee.py b/src/ptvsd/launcher/debuggee.py
--- a/src/ptvsd/launcher/debuggee.py
+++ b/src/ptvsd/launcher/debuggee.py
@@ -12,7 +12,7 @@
 import sys
 import threading
 
-from ptvsd.common import fmt, log, messaging
+from ptvsd.common import fmt, log, messaging, compat
 
 
 process = None
@@ -72,7 +72,7 @@
                 "isLocalProcess": True,
                 "systemProcessId": process.pid,
                 "name": process_name,
-                "pointerSize": struct.calcsize("P") * 8,
+                "pointerSize": struct.calcsize(compat.force_str("P")) * 8,
             },
         )

{"golden_diff": "diff --git a/src/ptvsd/launcher/debuggee.py b/src/ptvsd/launcher/debuggee.py\n--- a/src/ptvsd/launcher/debuggee.py\n+++ b/src/ptvsd/launcher/debuggee.py\n@@ -12,7 +12,7 @@\n import sys\n import threading\n \n-from ptvsd.common import fmt, log, messaging\n+from ptvsd.common import fmt, log, messaging, compat\n \n \n process = None\n@@ -72,7 +72,7 @@\n                 \"isLocalProcess\": True,\n                 \"systemProcessId\": process.pid,\n                 \"name\": process_name,\n-                \"pointerSize\": struct.calcsize(\"P\") * 8,\n+                \"pointerSize\": struct.calcsize(compat.force_str(\"P\")) * 8,\n             },\n         )\n", "issue": "Debugging with new_ptvsd is crashing because of TypeError: Struct()\n<!-- Please search existing issues to avoid creating duplicates. -->\r\n\r\n## Environment data\r\n\r\n- VS Code version: 1.40.1\r\n- Extension version (available under the Extensions sidebar): 2019.11.49689\r\n- OS and version: RH7.6\r\n- Python version (& distribution if applicable, e.g. Anaconda): 2.7.5\r\n\r\n## Expected behaviour\r\n\r\nDebugger works fine\r\n\r\n## Actual behaviour\r\n\r\nIt crashes..\r\nstack:\r\n```\r\n[root@rh01 ~]# /usr/bin/python /root/.vscode-server/extensions/ms-python.python-2019.11.49689/pythonFiles/lib/python/new_ptvsd/no_wheels/ptvsd/launcher /root/helloworld/helloworld.py \r\nE+00000.020: /handling microsoft/vscode-python#1 request \"launch\" from Adapter-1/\r\n             Handler 'launch_request' (file u'/root/.vscode-server/extensions/ms-python.python-2019.11.49689/pythonFiles/lib/python/new_ptvsd/no_wheels/ptvsd/launcher/../../ptvsd/launcher/adapter.py', line 35)\r\n             couldn't handle microsoft/vscode-python#1 request \"launch\" from Adapter-1:\r\n             \r\n             Traceback (most recent call last):\r\n               File \"/root/.vscode-server/extensions/ms-python.python-2019.11.49689/pythonFiles/lib/python/new_ptvsd/no_wheels/ptvsd/launcher/../../ptvsd/common/messaging.py\", line 763, in _handle\r\n                 result = handler(self)\r\n               File \"/root/.vscode-server/extensions/ms-python.python-2019.11.49689/pythonFiles/lib/python/new_ptvsd/no_wheels/ptvsd/launcher/../../ptvsd/launcher/adapter.py\", line 147, in launch_request\r\n                 debuggee.spawn(process_name, cmdline, cwd, env, redirect_output)\r\n               File \"/root/.vscode-server/extensions/ms-python.python-2019.11.49689/pythonFiles/lib/python/new_ptvsd/no_wheels/ptvsd/launcher/../../ptvsd/launcher/debuggee.py\", line 76, in spawn\r\n                 \"pointerSize\": struct.calcsize(\"P\") * 8,\r\n             TypeError: Struct() argument 1 must be string, not unicode\r\n             \r\n             Stack where logged:\r\n               File \"/usr/lib64/python2.7/threading.py\", line 785, in __bootstrap\r\n                 self.__bootstrap_inner()\r\n               File \"/usr/lib64/python2.7/threading.py\", line 812, in __bootstrap_inner\r\n                 self.run()\r\n               File \"/usr/lib64/python2.7/threading.py\", line 765, in run\r\n                 self.__target(*self.__args, **self.__kwargs)\r\n               File \"/root/.vscode-server/extensions/ms-python.python-2019.11.49689/pythonFiles/lib/python/new_ptvsd/no_wheels/ptvsd/launcher/../../ptvsd/common/messaging.py\", line 1520, in _run_handlers\r\n                 handler()\r\n               File \"/root/.vscode-server/extensions/ms-python.python-2019.11.49689/pythonFiles/lib/python/new_ptvsd/no_wheels/ptvsd/launcher/../../ptvsd/common/messaging.py\", line 809, in _handle\r\n                 self.describe(),\r\n```\r\n\r\n## Steps to reproduce:\r\n\r\n1. Just F5 to debug.\r\n2. Getting this error\r\n3. also getting an error to check launch,json - Launcher[1] disconnected unexpectedly\r\n4. launcher is somehow still listening in the background\r\n\r\nps x | grep ptvsd\r\n```\r\n 9815 pts/3    S      0:00 /usr/bin/python /root/.vscode-server/extensions/ms-python.python-2019.11.49689/pythonFiles/lib/python/new_ptvsd/no_wheels/ptvsd --client --host 127.0.0.1 --port 41995 /root/helloworld/helloworld.py\r\n 9869 pts/3    S      0:00 /usr/bin/python /root/.vscode-server/extensions/ms-python.python-2019.11.49689/pythonFiles/lib/python/new_ptvsd/no_wheels/ptvsd --client --host 127.0.0.1 --port 39855 /root/helloworld/helloworld.py\r\n\r\n```\r\n5. **it is verified to be working with the previous release of python extension** which does not make use of ptvsd_new\r\n\r\n\r\nlaunch.json contents:\r\n```\r\n{\r\n    // Use IntelliSense to learn about possible attributes.\r\n    // Hover to view descriptions of existing attributes.\r\n    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387\r\n    \"version\": \"0.2.0\",\r\n    \"configurations\": [\r\n        {\r\n            \"name\": \"Python: Current File\",\r\n            \"type\": \"python\",\r\n            \"request\": \"launch\",\r\n            \"program\": \"${file}\",\r\n            \"console\": \"integratedTerminal\"\r\n        }\r\n    ]\r\n}\r\n```\n", "before_files": [{"content": "# Copyright (c) Microsoft Corporation. All rights reserved.\n# Licensed under the MIT License. See LICENSE in the project root\n# for license information.\n\nfrom __future__ import absolute_import, division, print_function, unicode_literals\n\nimport atexit\nimport locale\nimport os\nimport struct\nimport subprocess\nimport sys\nimport threading\n\nfrom ptvsd.common import fmt, log, messaging\n\n\nprocess = None\n\"\"\"subprocess.Popen instance for the debuggee process.\"\"\"\n\nwait_on_exit_predicates = []\n\"\"\"List of functions that determine whether to pause after debuggee process exits.\n\nEvery function is invoked with exit code as the argument. If any of the functions\nreturns True, the launcher pauses and waits for user input before exiting.\n\"\"\"\n\n\ndef describe():\n    return fmt(\"debuggee process with PID={0}\", process.pid)\n\n\ndef spawn(process_name, cmdline, cwd, env, redirect_output):\n    from ptvsd.launcher import adapter, output\n\n    log.info(\n        \"Spawning debuggee process:\\n\\n\"\n        \"Current directory: {0!j}\\n\\n\"\n        \"Command line: {1!j}\\n\\n\"\n        \"Environment variables: {2!j}\\n\\n\",\n        cwd,\n        cmdline,\n        env,\n    )\n\n    close_fds = set()\n    try:\n        if redirect_output:\n            # subprocess.PIPE behavior can vary substantially depending on Python version\n            # and platform; using our own pipes keeps it simple, predictable, and fast.\n            stdout_r, stdout_w = os.pipe()\n            stderr_r, stderr_w = os.pipe()\n            close_fds |= {stdout_r, stdout_w, stderr_r, stderr_w}\n            kwargs = dict(stdout=stdout_w, stderr=stderr_w)\n        else:\n            kwargs = {}\n\n        try:\n            global process\n            process = subprocess.Popen(cmdline, cwd=cwd, env=env, bufsize=0, **kwargs)\n        except Exception as exc:\n            raise messaging.Message.cant_handle(\n                \"Couldn't spawn debuggee: {0}\\n\\nCommand line:{1!r}\", exc, cmdline\n            )\n\n        log.info(\"Spawned {0}.\", describe())\n        atexit.register(kill)\n        adapter.channel.send_event(\n            \"process\",\n            {\n                \"startMethod\": \"launch\",\n                \"isLocalProcess\": True,\n                \"systemProcessId\": process.pid,\n                \"name\": process_name,\n                \"pointerSize\": struct.calcsize(\"P\") * 8,\n            },\n        )\n\n        if redirect_output:\n            encoding = env.get(\"PYTHONIOENCODING\", locale.getpreferredencoding())\n            for category, fd, tee in [\n                (\"stdout\", stdout_r, sys.stdout),\n                (\"stderr\", stderr_r, sys.stderr),\n            ]:\n                output.CaptureOutput(category, fd, tee.fileno(), encoding)\n                close_fds.remove(fd)\n\n        wait_thread = threading.Thread(target=wait_for_exit, name=\"wait_for_exit()\")\n        wait_thread.daemon = True\n        wait_thread.start()\n\n    finally:\n        for fd in close_fds:\n            try:\n                os.close(fd)\n            except Exception:\n                log.exception()\n\n\ndef kill():\n    if process is None:\n        return\n    try:\n        if process.poll() is None:\n            log.info(\"Killing {0}\", describe())\n            process.kill()\n    except Exception:\n        log.exception(\"Failed to kill {0}\", describe())\n\n\ndef wait_for_exit():\n    from ptvsd.launcher import adapter, output\n\n    try:\n        code = process.wait()\n        if sys.platform != \"win32\" and code < 0:\n            # On POSIX, if the process was terminated by a signal, Popen will use\n            # a negative returncode to indicate that - but the actual exit code of\n            # the process is always an unsigned number, and can be determined by\n            # taking the lowest 8 bits of that negative returncode.\n            code &= 0xFF\n    except Exception:\n        log.exception(\"Couldn't determine process exit code:\")\n        code = -1\n\n    log.info(\"{0} exited with code {1}\", describe(), code)\n    output.wait_for_remaining_output()\n    try:\n        adapter.channel.send_event(\"exited\", {\"exitCode\": code})\n    except Exception:\n        pass\n\n    if any(pred(code) for pred in wait_on_exit_predicates):\n        _wait_for_user_input()\n\n    try:\n        adapter.channel.send_event(\"terminated\")\n    except Exception:\n        pass\n\n\ndef _wait_for_user_input():\n    if sys.stdout and sys.stdin:\n        from ptvsd.common import log\n\n        can_getch = sys.stdin.isatty()\n        if can_getch:\n            try:\n                import msvcrt\n            except ImportError:\n                can_getch = False\n\n        if can_getch:\n            log.debug(\"msvcrt available - waiting for user input via getch()\")\n            sys.stdout.write(\"Press any key to continue . . . \")\n            sys.stdout.flush()\n            msvcrt.getch()\n        else:\n            log.debug(\"msvcrt not available - waiting for user input via read()\")\n            sys.stdout.write(\"Press Enter to continue . . . \")\n            sys.stdout.flush()\n            sys.stdin.read(1)\n", "path": "src/ptvsd/launcher/debuggee.py"}], "after_files": [{"content": "# Copyright (c) Microsoft Corporation. All rights reserved.\n# Licensed under the MIT License. See LICENSE in the project root\n# for license information.\n\nfrom __future__ import absolute_import, division, print_function, unicode_literals\n\nimport atexit\nimport locale\nimport os\nimport struct\nimport subprocess\nimport sys\nimport threading\n\nfrom ptvsd.common import fmt, log, messaging, compat\n\n\nprocess = None\n\"\"\"subprocess.Popen instance for the debuggee process.\"\"\"\n\nwait_on_exit_predicates = []\n\"\"\"List of functions that determine whether to pause after debuggee process exits.\n\nEvery function is invoked with exit code as the argument. If any of the functions\nreturns True, the launcher pauses and waits for user input before exiting.\n\"\"\"\n\n\ndef describe():\n    return fmt(\"debuggee process with PID={0}\", process.pid)\n\n\ndef spawn(process_name, cmdline, cwd, env, redirect_output):\n    from ptvsd.launcher import adapter, output\n\n    log.info(\n        \"Spawning debuggee process:\\n\\n\"\n        \"Current directory: {0!j}\\n\\n\"\n        \"Command line: {1!j}\\n\\n\"\n        \"Environment variables: {2!j}\\n\\n\",\n        cwd,\n        cmdline,\n        env,\n    )\n\n    close_fds = set()\n    try:\n        if redirect_output:\n            # subprocess.PIPE behavior can vary substantially depending on Python version\n            # and platform; using our own pipes keeps it simple, predictable, and fast.\n            stdout_r, stdout_w = os.pipe()\n            stderr_r, stderr_w = os.pipe()\n            close_fds |= {stdout_r, stdout_w, stderr_r, stderr_w}\n            kwargs = dict(stdout=stdout_w, stderr=stderr_w)\n        else:\n            kwargs = {}\n\n        try:\n            global process\n            process = subprocess.Popen(cmdline, cwd=cwd, env=env, bufsize=0, **kwargs)\n        except Exception as exc:\n            raise messaging.Message.cant_handle(\n                \"Couldn't spawn debuggee: {0}\\n\\nCommand line:{1!r}\", exc, cmdline\n            )\n\n        log.info(\"Spawned {0}.\", describe())\n        atexit.register(kill)\n        adapter.channel.send_event(\n            \"process\",\n            {\n                \"startMethod\": \"launch\",\n                \"isLocalProcess\": True,\n                \"systemProcessId\": process.pid,\n                \"name\": process_name,\n                \"pointerSize\": struct.calcsize(compat.force_str(\"P\")) * 8,\n            },\n        )\n\n        if redirect_output:\n            encoding = env.get(\"PYTHONIOENCODING\", locale.getpreferredencoding())\n            for category, fd, tee in [\n                (\"stdout\", stdout_r, sys.stdout),\n                (\"stderr\", stderr_r, sys.stderr),\n            ]:\n                output.CaptureOutput(category, fd, tee.fileno(), encoding)\n                close_fds.remove(fd)\n\n        wait_thread = threading.Thread(target=wait_for_exit, name=\"wait_for_exit()\")\n        wait_thread.daemon = True\n        wait_thread.start()\n\n    finally:\n        for fd in close_fds:\n            try:\n                os.close(fd)\n            except Exception:\n                log.exception()\n\n\ndef kill():\n    if process is None:\n        return\n    try:\n        if process.poll() is None:\n            log.info(\"Killing {0}\", describe())\n            process.kill()\n    except Exception:\n        log.exception(\"Failed to kill {0}\", describe())\n\n\ndef wait_for_exit():\n    from ptvsd.launcher import adapter, output\n\n    try:\n        code = process.wait()\n        if sys.platform != \"win32\" and code < 0:\n            # On POSIX, if the process was terminated by a signal, Popen will use\n            # a negative returncode to indicate that - but the actual exit code of\n            # the process is always an unsigned number, and can be determined by\n            # taking the lowest 8 bits of that negative returncode.\n            code &= 0xFF\n    except Exception:\n        log.exception(\"Couldn't determine process exit code:\")\n        code = -1\n\n    log.info(\"{0} exited with code {1}\", describe(), code)\n    output.wait_for_remaining_output()\n    try:\n        adapter.channel.send_event(\"exited\", {\"exitCode\": code})\n    except Exception:\n        pass\n\n    if any(pred(code) for pred in wait_on_exit_predicates):\n        _wait_for_user_input()\n\n    try:\n        adapter.channel.send_event(\"terminated\")\n    except Exception:\n        pass\n\n\ndef _wait_for_user_input():\n    if sys.stdout and sys.stdin:\n        from ptvsd.common import log\n\n        can_getch = sys.stdin.isatty()\n        if can_getch:\n            try:\n                import msvcrt\n            except ImportError:\n                can_getch = False\n\n        if can_getch:\n            log.debug(\"msvcrt available - waiting for user input via getch()\")\n            sys.stdout.write(\"Press any key to continue . . . \")\n            sys.stdout.flush()\n            msvcrt.getch()\n        else:\n            log.debug(\"msvcrt not available - waiting for user input via read()\")\n            sys.stdout.write(\"Press Enter to continue . . . \")\n            sys.stdout.flush()\n            sys.stdin.read(1)\n", "path": "src/ptvsd/launcher/debuggee.py"}]}