Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Debugging class with modified __getattribute__ freezes debugpy #1832

Closed
fireattack opened this issue Feb 12, 2025 · 2 comments
Closed

Debugging class with modified __getattribute__ freezes debugpy #1832

fireattack opened this issue Feb 12, 2025 · 2 comments
Assignees
Labels
Fixed in next release This issue has been fixed, but won't be available to customers until the next release. needs repro Issue has not been reproduced yet

Comments

@fireattack
Copy link

fireattack commented Feb 12, 2025

Before creating a new issue, please check the FAQ to see if your question is answered there.

Environment data

  • debugpy version: the one bundled with VS Code extension ms-python.debugpy-2025.0.0-win32-x64
  • OS and version: Windows 10
  • Python version (& distribution if applicable, e.g. Anaconda): Python 3.11
  • Using VS Code or Visual Studio: VS Code

Actual behavior

debugpy throws an error

Expected behavior

It should not raise an error in debugpy or cause VS Code debugging to freeze.

Steps to reproduce:

  1. Create a file with the following content:
class KillDebugpy():
    def __getattribute__(self, _):
        return self

a = KillDebugpy()
print('Done')
  1. Add a breakpoint in front of print()
  2. Start debugging the file in VS Code.
  3. Observe the following error in terminal, and it freezes VS Code debugging interface (you cannot stop it in UI.)
> cmd /C "c:\Users\{masked}\AppData\Local\Programs\Python\Python311\python.exe c:\Users\{masked}\.vscode\extensions\ms-python.debugpy-2025.0.0-win32-x64\bundled\libs\debugpy\launcher 11138 -- D:\sync\code\python\trysail\_test4.py "
0.77s - Error processing internal command.
Traceback (most recent call last):
  File "c:\Users\{masked}\.vscode\extensions\ms-python.debugpy-2025.0.0-win32-x64\bundled\libs\debugpy\_vendored\pydevd\pydevd.py", line 2245, in _do_wait_suspend
    internal_cmd.do_it(self)
  File "c:\Users\{masked}\.vscode\extensions\ms-python.debugpy-2025.0.0-win32-x64\bundled\libs\debugpy\_vendored\pydevd\_pydevd_bundle\pydevd_comm.py", line 565, in do_it
    self.method(dbg, *self.args, **self.kwargs)
  File "c:\Users\{masked}\.vscode\extensions\ms-python.debugpy-2025.0.0-win32-x64\bundled\libs\debugpy\_vendored\pydevd\_pydevd_bundle\pydevd_constants.py", line 531, in new_func
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "c:\Users\{masked}\.vscode\extensions\ms-python.debugpy-2025.0.0-win32-x64\bundled\libs\debugpy\_vendored\pydevd\_pydevd_bundle\pydevd_comm.py", line 813, in internal_get_variable_json
    py_db.writer.add_command(NetCommand(CMD_RETURN, 0, variables_response, is_json=True))
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\Users\{masked}\.vscode\extensions\ms-python.debugpy-2025.0.0-win32-x64\bundled\libs\debugpy\_vendored\pydevd\_pydevd_bundle\pydevd_net_command.py", line 80, in __init__
    text = json.dumps(as_dict)
           ^^^^^^^^^^^^^^^^^^^
  File "c:\Users\{masked}\AppData\Local\Programs\Python\Python311\Lib\json\__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\Users\{masked}\AppData\Local\Programs\Python\Python311\Lib\json\encoder.py", line 200, in encode
    chunks = self.iterencode(o, _one_shot=True)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\Users\{masked}\AppData\Local\Programs\Python\Python311\Lib\json\encoder.py", line 258, in iterencode
    return _iterencode(o, 0)
           ^^^^^^^^^^^^^^^^^
  File "c:\Users\{masked}\AppData\Local\Programs\Python\Python311\Lib\json\encoder.py", line 180, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type <__main__.KillDebugpy object at 0x00000179EC1F9E50> is not JSON serializable

This bug was first observed in real-world code (see: mikf/gallery-dl#6582 (comment)), and I then created a minimal reproducible example based on it.

@rchiodo
Copy link
Contributor

rchiodo commented Feb 12, 2025

Thanks, we could probably handle infinite __getattribute__ better.

I think this would do it (in pydevd_pydevd_bundle\pydevd_net_command.py)

            try:
                text = json.dumps(as_dict)
            except TypeError:
                text = json.dumps(as_dict, default=lambda o: str(o))

rchiodo added a commit that referenced this issue Feb 12, 2025
rchiodo added a commit that referenced this issue Feb 12, 2025
* Handle invalid `__getattribute__` functions

Addresses #1832

* Update src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_net_command.py

Co-authored-by: Mike Fährmann <mike_faehrmann@web.de>

---------

Co-authored-by: Mike Fährmann <mike_faehrmann@web.de>
@rchiodo rchiodo added the Fixed in next release This issue has been fixed, but won't be available to customers until the next release. label Feb 12, 2025
@rchiodo
Copy link
Contributor

rchiodo commented Mar 5, 2025

This issue should be fixed in the latest build of debugpy. It should ship with VS code in a future version of the Python Debugger Extension or you can install your own debugpy from pypi

@rchiodo rchiodo closed this as completed Mar 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Fixed in next release This issue has been fixed, but won't be available to customers until the next release. needs repro Issue has not been reproduced yet
Projects
None yet
Development

No branches or pull requests

3 participants