-
-
Notifications
You must be signed in to change notification settings - Fork 346
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
Stack spew when quitting via the debugger #1155
Comments
Ick, that's certainly an unpleasant pile of junk. It looks like what's happening is:
What do we want to happen here? I guess ideally, pdb would be smart enough to work at the "Trio level", treating the Trio internals as opaque and treating tasks as first-class objects, and injecting I don't think we can do a clean unwind like we would for a user exception or A simple change would be to special-case The other sources of spew I see are:
My first thought was that maybe we could do something to manually tear down all these tasks before the GC has a chance to do it, so that it still happens in Trio context. (This is similar to what we need to do for async generators – see #265 and especially #265 (comment).) However, I don't think this will work. The main thing that's failing is calls to be to try to manipulate other data structures that are also in inconsistent states. (Like what happens to the nursery cleanup code.) Maybe we could add some specific hacks to
|
@njsmith so here's another fun one: If you enter a
Here's some example code with demonstrates this failure: import pdb
import trio
async def trace():
breakpoint()
while True:
await trio.sleep(0.1)
async def spawn_debuggers():
async with trio.open_nursery() as n:
n.start_soon(trace)
n.start_soon(trio.sleep_forever)
trio.run(spawn_debuggers) After running the @smurfix using ProposalFor the KBI borking problem mentioned, I propose we just write our own I guess you could argue the "halting sync code wherever it is currently running" can sometimes be useful, but I'm just not sure that's so compatible with I personally found the whole situation extremely difficult to grok once you involve a foreign host loop in guest mode and your code gets stuck blocking forever in that loop after having used the debugger 🤯 |
Oh wow wait ma bad @smurfix, just realized I almost always have With the stdlib's debugger it's what you posted: 3.9) >>> python trio_pdb.py
> /home/goodboy/repos/tractor/trio_pdb.py(10)trace()
-> await trio.sleep(0.1)
(Pdb) c
^C
Program interrupted. (Use 'cont' to resume).
--Return--
> /home/goodboy/repos/trio/trio/_core/_io_epoll.py(229)get_events()->[(6, 1)]
-> return self._epoll.poll(timeout, max_events)
(Pdb) q
Traceback (most recent call last):
File "/home/goodboy/repos/tractor/trio_pdb.py", line 19, in <module>
trio.run(spawn_debuggers)
File "/home/goodboy/repos/trio/trio/_core/_run.py", line 1931, in run
next_send = runner.io_manager.get_events(timeout)
File "/home/goodboy/repos/trio/trio/_core/_io_epoll.py", line 229, in get_events
return self._epoll.poll(timeout, max_events)
File "/usr/lib/python3.9/bdb.py", line 92, in trace_dispatch
return self.dispatch_return(frame, arg)
File "/usr/lib/python3.9/bdb.py", line 154, in dispatch_return
if self.quitting: raise BdbQuit
bdb.BdbQuit
/home/goodboy/repos/trio/trio/_core/_run.py:2226: RuntimeWarning: Trio guest run got abandoned without properly finishing... weird stuff might happen
warnings.warn(
Exception ignored in: <coroutine object Runner.init at 0x7f342f0ba9c0>
Traceback (most recent call last):
File "/home/goodboy/repos/trio/trio/_core/_run.py", line 1608, in init
File "/home/goodboy/repos/trio/trio/_core/_run.py", line 802, in __aexit__
File "/home/goodboy/repos/trio/trio/_core/_run.py", line 914, in _nested_child_finished
File "/home/goodboy/repos/trio/trio/_core/_run.py", line 896, in _add_exc
File "/home/goodboy/repos/trio/trio/_core/_ki.py", line 159, in wrapper
File "/home/goodboy/repos/trio/trio/_core/_run.py", line 681, in cancel
File "/home/goodboy/repos/trio/trio/_core/_run.py", line 357, in recalculate
File "/home/goodboy/repos/trio/trio/_core/_run.py", line 1169, in _attempt_delivery_of_any_pending_cancel
File "/home/goodboy/repos/trio/trio/_core/_run.py", line 1151, in _attempt_abort
File "/home/goodboy/repos/trio/trio/_core/_io_epoll.py", line 292, in abort
File "/home/goodboy/repos/trio/trio/_core/_io_epoll.py", line 261, in _update_registrations
ValueError: I/O operation on closed epoll object
Exception ignored in: <function Nursery.__del__ at 0x7f342f67e4c0>
Traceback (most recent call last):
File "/home/goodboy/repos/trio/trio/_core/_run.py", line 1050, in __del__
AssertionError:
Exception ignored in: <function Nursery.__del__ at 0x7f342f67e4c0>
Traceback (most recent call last):
File "/home/goodboy/repos/trio/trio/_core/_run.py", line 1050, in __del__
AssertionError:
Exception ignored in: <function Nursery.__del__ at 0x7f342f67e4c0>
Traceback (most recent call last):
File "/home/goodboy/repos/trio/trio/_core/_run.py", line 1050, in __del__
AssertionError:
Exception ignored in: <coroutine object trace at 0x7f342f0bac40>
Traceback (most recent call last):
File "/home/goodboy/repos/tractor/trio_pdb.py", line 10, in trace
File "/home/goodboy/repos/trio/trio/_timeouts.py", line 75, in sleep
File "/home/goodboy/repos/trio/trio/_timeouts.py", line 56, in sleep_until
File "/home/goodboy/repos/trio/trio/_core/_ki.py", line 159, in wrapper
File "/home/goodboy/repos/trio/trio/_core/_run.py", line 539, in __exit__
File "/home/goodboy/repos/trio/trio/_core/_run.py", line 476, in _close
File "/home/goodboy/repos/trio/trio/_core/_run.py", line 2276, in current_task
RuntimeError: must be called from async context Heh, I guess also we get a new error msg since guest mode was introduced. If you just enter > /home/goodboy/repos/tractor/trio_pdb.py(10)trace()
-> await trio.sleep(0.1)
(Pdb) q
Traceback (most recent call last):
File "/home/goodboy/repos/tractor/trio_pdb.py", line 19, in <module>
trio.run(spawn_debuggers)
File "/home/goodboy/repos/trio/trio/_core/_run.py", line 1928, in run
timeout = gen.send(next_send)
File "/home/goodboy/repos/tractor/trio_pdb.py", line 16, in spawn_debuggers
n.start_soon(trio.sleep_forever)
File "/home/goodboy/repos/trio/trio/_core/_run.py", line 815, in __aexit__
raise combined_error_from_nursery
File "/home/goodboy/repos/tractor/trio_pdb.py", line 10, in trace
await trio.sleep(0.1)
File "/home/goodboy/repos/tractor/trio_pdb.py", line 10, in trace
await trio.sleep(0.1)
File "/usr/lib/python3.9/bdb.py", line 88, in trace_dispatch
return self.dispatch_line(frame)
File "/usr/lib/python3.9/bdb.py", line 113, in dispatch_line
if self.quitting: raise BdbQuit
bdb.BdbQuit So I think we might get a few birds here by changing these flags. |
Oh, and just so that I'm not talking lots of air, I did fix this in |
Turns out this is a lower level issue in terms of the stdlib's default `pdb.Pdb` settings and how they conflict with `trio`s cancellation and KBI handling. The details are hashed out more thoroughly in python-trio/trio#1155. Maybe we can get a fix in trio so things are solved under our feet :)
Chiming in per chat request:
True to its word, once you continue execution from the debugger, hitting CTRL-C causes an exit with a completely normal |
@mikeengland perfect, yes this is the default behavior I would expect. I think this adds fuel for this change I've got in mind. |
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Override `breakpoint()` for sync code making it work properly with `trio` as per: python-trio/trio#1155 (comment) Relates to #193
Can we do better than this?
The text was updated successfully, but these errors were encountered: