Repository: microsoft/ptvsd

Issue:
Frame not found while switching to frozen lib frames
Clone the repo using:
```
git clone -b debuggerbug_exception_callstack https://github.com/qubitron/stackoverflow-django
```

This is where it falls over on change of frame:
```
find_frame: frame not found.
    Looking for thread_id:pid_996_id_2077876920104, frame_id:2077914384232
    Current     thread_id:pid_996_id_2077876920104, available frames:
    2077912942600  -  2077884835544  -  2077910162408  -  2077910410088  -  2077912758680
2077912573176  -

    Traceback (most recent call last):
  File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\lib\xml\sax\expatreader.py", line 217, in feed
    self._parser.Parse(data, isFinal)
xml.parsers.expat.ExpatError: syntax error: line 1, column 0

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\GIT\ptvsd\ptvsd\wrapper.py", line 730, in done
    fut.result()
  File "C:\GIT\ptvsd\ptvsd\futures.py", line 44, in result
    reraise(self._exc_info)
  File "C:\GIT\ptvsd\ptvsd\reraise3.py", line 11, in reraise
    raise exc_info[1].with_traceback(exc_info[2])
  File "C:\GIT\ptvsd\ptvsd\futures.py", line 159, in callback
    x = it.send(fut.result())
  File "C:\GIT\ptvsd\ptvsd\wrapper.py", line 1036, in on_variables
    xml = untangle.parse(resp_args).xml
  File "C:\GIT\ptvsd\ptvsd\untangle.py", line 200, in parse
    parser.parse(StringIO(filename))
  File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\lib\xml\sax\expatreader.py", line 111, in parse
    xmlreader.IncrementalParser.parse(self, source)
  File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\lib\xml\sax\xmlreader.py", line 125, in parse
    self.feed(buffer)
  File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\lib\xml\sax\expatreader.py", line 221, in feed
    self._err_handler.fatalError(exc)
  File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\lib\xml\sax\handler.py", line 38, in fatalError
    raise exception
xml.sax._exceptions.SAXParseException: <unknown>:1:0: syntax error
```

PTVS bug: https://github.com/Microsoft/PTVS/issues/3961



Discussion:
This is the stack that is received with the exception when we hit the exception. Switching to any of the frozen frames causes the no frame found issue.

```
  Message=TypeError("frameworksByLanguage() missing 1 required positional argument: 'language'",)
  Source=c:\git\stackoverflow-django\stackoverflow.py
  StackTrace:
  File "c:\git\stackoverflow-django\stackoverflow.py", line 45, in <module>
    frameworksByLanguage()
  File "c:\git\stackoverflow-django\<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "c:\git\stackoverflow-django\<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "c:\git\stackoverflow-django\<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "c:\git\stackoverflow-django\<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "c:\git\stackoverflow-django\<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "c:\git\stackoverflow-django\app\views.py", line 12, in <module>
    import stackoverflow
  File "c:\git\stackoverflow-django\<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "c:\git\stackoverflow-django\<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "c:\git\stackoverflow-django\<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "c:\git\stackoverflow-django\<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "c:\git\stackoverflow-django\<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "c:\git\stackoverflow-django\djangoserver\urls.py", line 10, in <module>
    import app.views
  File "c:\git\stackoverflow-django\<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "c:\git\stackoverflow-django\<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "c:\git\stackoverflow-django\<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "c:\git\stackoverflow-django\<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "c:\git\stackoverflow-django\<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "c:\git\stackoverflow-django\<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "c:\program files (x86)\microsoft visual studio\shared\python36_64\lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "c:\pyenv\py3664\lib\site-packages\django\urls\resolvers.py", line 529, in urlconf_module
    return import_module(self.urlconf_name)
  File "c:\pyenv\py3664\lib\site-packages\django\utils\functional.py", line 36, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "c:\pyenv\py3664\lib\site-packages\django\urls\resolvers.py", line 536, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "c:\pyenv\py3664\lib\site-packages\django\utils\functional.py", line 36, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "c:\pyenv\py3664\lib\site-packages\django\core\checks\urls.py", line 57, in _load_all_namespaces
    url_patterns = getattr(resolver, 'url_patterns', [])
  File "c:\pyenv\py3664\lib\site-packages\django\core\checks\urls.py", line 40, in check_url_namespaces_unique
    all_namespaces = _load_all_namespaces(resolver)
  File "c:\pyenv\py3664\lib\site-packages\django\core\checks\registry.py", line 73, in run_checks
    new_errors = check(app_configs=app_configs)
  File "c:\pyenv\py3664\lib\site-packages\django\core\management\base.py", line 351, in _run_checks
    return checks.run_checks(**kwargs)
  File "c:\pyenv\py3664\lib\site-packages\django\core\management\base.py", line 364, in check
    include_deployment_checks=include_deployment_checks,
  File "c:\pyenv\py3664\lib\site-packages\django\core\management\commands\runserver.py", line 121, in inner_run
    self.check(display_num_errors=True)
  File "c:\pyenv\py3664\lib\site-packages\django\core\management\commands\runserver.py", line 108, in run
    self.inner_run(None, **options)
  File "c:\pyenv\py3664\lib\site-packages\django\core\management\commands\runserver.py", line 99, in handle
    self.run(**options)
  File "c:\pyenv\py3664\lib\site-packages\django\core\management\base.py", line 347, in execute
    translation.activate(saved_locale)
  File "c:\pyenv\py3664\lib\site-packages\django\core\management\commands\runserver.py", line 62, in execute
    super().execute(*args, **options)
  File "c:\pyenv\py3664\lib\site-packages\django\core\management\base.py", line 305, in run_from_argv
    pass
  File "c:\pyenv\py3664\lib\site-packages\django\core\management\__init__.py", line 365, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "c:\pyenv\py3664\lib\site-packages\django\core\management\__init__.py", line 371, in execute_from_command_line
    utility.execute()
  File "c:\git\stackoverflow-django\manage.py", line 17, in <module>
    execute_from_command_line(sys.argv)
  File "c:\git\ptvsd\ptvsd\pydevd\_pydev_imps\_pydev_execfile.py", line 25, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "c:\git\ptvsd\ptvsd\pydevd\pydevd.py", line 1035, in run
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "c:\git\ptvsd\ptvsd\pydevd\pydevd.py", line 1628, in main
    globals = debugger.run(setup['file'], None, None, is_module)
  File "c:\git\ptvsd\ptvsd\debugger.py", line 57, in _run
    raise
  File "c:\git\ptvsd\ptvsd\debugger.py", line 36, in _run_file
    _run(argv)
  File "c:\git\ptvsd\ptvsd\debugger.py", line 24, in debug
    _run_file(address, filename)
  File "c:\users\kanadig\appdata\local\microsoft\visualstudio\15.0_8875dd93exp\extensions\microsoft corporation\python\15.7.0\ptvsd_launcher.py", line 158, in <module>
    vspd.debug(filename, port_num, debug_id, debug_options, run_as)
```
This might be a issue with switching to frozen lib frames. I can switch to any non-frozen lib frame:
![image](https://user-images.githubusercontent.com/3840081/38109215-3ff60d4e-334c-11e8-8c23-ed91cafa1e7f.png)


Resolving patch:
diff --git a/ptvsd/wrapper.py b/ptvsd/wrapper.py
--- a/ptvsd/wrapper.py
+++ b/ptvsd/wrapper.py
@@ -21,6 +21,7 @@
 except Exception:
     import urllib.parse as urllib
 import warnings
+from xml.sax import SAXParseException
 
 import _pydevd_bundle.pydevd_constants as pydevd_constants
 # Disable this, since we aren't packaging the Cython modules at the moment.
@@ -973,6 +974,13 @@ def send_process_event(self, start_method):
         }
         self.send_event('process', **evt)
 
+    def send_error_response(self, request, message=None):
+        self.send_response(
+            request,
+            success=False,
+            message=message
+        )
+
     def is_debugger_internal_thread(self, thread_name):
         if thread_name:
             if thread_name.startswith('pydevd.'):
@@ -986,7 +994,13 @@ def on_threads(self, request, args):
         # TODO: docstring
         cmd = pydevd_comm.CMD_LIST_THREADS
         _, _, resp_args = yield self.pydevd_request(cmd, '')
-        xml = self.parse_xml_response(resp_args)
+
+        try:
+            xml = self.parse_xml_response(resp_args)
+        except SAXParseException as ex:
+            self.send_error_response(request)
+            return
+
         try:
             xthreads = xml.thread
         except AttributeError:
@@ -1121,7 +1135,12 @@ def on_variables(self, request, args):
         with (yield self.using_format(fmt)):
             _, _, resp_args = yield self.pydevd_request(cmd, msg)
 
-        xml = self.parse_xml_response(resp_args)
+        try:
+            xml = self.parse_xml_response(resp_args)
+        except SAXParseException as ex:
+            self.send_error_response(request)
+            return
+
         try:
             xvars = xml.var
         except AttributeError:
@@ -1232,8 +1251,17 @@ def on_setVariable(self, request, args):
                 '\t'.join(cmd_args),
             )
 
-        xml = self.parse_xml_response(resp_args)
-        xvar = xml.var
+        try:
+            xml = self.parse_xml_response(resp_args)
+        except SAXParseException as ex:
+            self.send_error_response(request)
+            return
+
+        try:
+            xvar = xml.var
+        except AttributeError:
+            self.send_response(request, success=False)
+            return
 
         response = {
             'type': unquote(xvar['type']),
@@ -1261,8 +1289,18 @@ def on_evaluate(self, request, args):
             _, _, resp_args = yield self.pydevd_request(
                 pydevd_comm.CMD_EVALUATE_EXPRESSION,
                 msg)
-        xml = self.parse_xml_response(resp_args)
-        xvar = xml.var
+
+        try:
+            xml = self.parse_xml_response(resp_args)
+        except SAXParseException as ex:
+            self.send_error_response(request)
+            return
+
+        try:
+            xvar = xml.var
+        except AttributeError:
+            self.send_response(request, success=False)
+            return
 
         context = args.get('context', '')
         is_eval_error = xvar['isErrorOnEval']
@@ -1538,7 +1576,6 @@ def on_pydevd_thread_create(self, seq, args):
                 self.is_process_created = True
                 self.send_process_event(self.start_reason)
 
-        # TODO: docstring
         xml = self.parse_xml_response(args)
         try:
             name = unquote(xml.thread['name'])


Test patch: