forked from goodboy/tractor
Try overriding `_GeneratorContextManager.__exit__()`; didn't work..
Using either of `@pdb.hideframe` or `__tracebackhide__` on stdlib methods doesn't seem to work either.. This all seems to have something to do with async generator usage I think ?sigint_ignore_in_pdb_repl
parent
1524c94b23
commit
1142b802d3
|
@ -18,12 +18,15 @@
|
||||||
Multi-core debugging for da peeps!
|
Multi-core debugging for da peeps!
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
import bdb
|
import bdb
|
||||||
import sys
|
import sys
|
||||||
import signal
|
import signal
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from contextlib import asynccontextmanager as acm
|
from contextlib import asynccontextmanager as acm
|
||||||
from contextlib import contextmanager as cm
|
from contextlib import contextmanager as cm
|
||||||
|
from contextlib import _GeneratorContextManager
|
||||||
|
import contextlib
|
||||||
from typing import (
|
from typing import (
|
||||||
Tuple,
|
Tuple,
|
||||||
Optional,
|
Optional,
|
||||||
|
@ -40,7 +43,8 @@ from trio_typing import TaskStatus
|
||||||
from .log import get_logger
|
from .log import get_logger
|
||||||
from ._discovery import get_root
|
from ._discovery import get_root
|
||||||
from ._state import is_root_process, debug_mode
|
from ._state import is_root_process, debug_mode
|
||||||
from ._exceptions import is_multi_cancelled, ContextCancelled
|
from ._exceptions import is_multi_cancelled
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# wtf: only exported when installed in dev mode?
|
# wtf: only exported when installed in dev mode?
|
||||||
|
@ -54,6 +58,19 @@ except ImportError:
|
||||||
log = get_logger(__name__)
|
log = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class noexittbGCM(_GeneratorContextManager):
|
||||||
|
# @pdb.hideframe
|
||||||
|
def __exit__(self, type, value, traceback):
|
||||||
|
__tracebackhide__ = True
|
||||||
|
# try:
|
||||||
|
return super().__exit__(type, value, traceback)
|
||||||
|
# except:
|
||||||
|
# print('EXITED')
|
||||||
|
|
||||||
|
|
||||||
|
contextlib._GeneratorContextManager = noexittbGCM
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['breakpoint', 'post_mortem']
|
__all__ = ['breakpoint', 'post_mortem']
|
||||||
|
|
||||||
|
|
||||||
|
@ -98,17 +115,19 @@ class PdbwTeardown(pdbpp.Pdb):
|
||||||
try:
|
try:
|
||||||
super().set_continue()
|
super().set_continue()
|
||||||
finally:
|
finally:
|
||||||
global _local_task_in_debug
|
global _local_task_in_debug, _pdb_release_hook
|
||||||
_local_task_in_debug = None
|
_local_task_in_debug = None
|
||||||
_pdb_release_hook()
|
if _pdb_release_hook:
|
||||||
|
_pdb_release_hook()
|
||||||
|
|
||||||
def set_quit(self):
|
def set_quit(self):
|
||||||
try:
|
try:
|
||||||
super().set_quit()
|
super().set_quit()
|
||||||
finally:
|
finally:
|
||||||
global _local_task_in_debug
|
global _local_task_in_debug, _pdb_release_hook
|
||||||
_local_task_in_debug = None
|
_local_task_in_debug = None
|
||||||
_pdb_release_hook()
|
if _pdb_release_hook:
|
||||||
|
_pdb_release_hook()
|
||||||
|
|
||||||
|
|
||||||
# TODO: will be needed whenever we get to true remote debugging.
|
# TODO: will be needed whenever we get to true remote debugging.
|
||||||
|
@ -252,7 +271,7 @@ async def _hijack_stdin_for_child(
|
||||||
|
|
||||||
with (
|
with (
|
||||||
trio.CancelScope(shield=True),
|
trio.CancelScope(shield=True),
|
||||||
disable_sigint(),
|
# disable_sigint(),
|
||||||
):
|
):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -270,10 +289,12 @@ async def _hijack_stdin_for_child(
|
||||||
except (
|
except (
|
||||||
# BaseException,
|
# BaseException,
|
||||||
trio.MultiError,
|
trio.MultiError,
|
||||||
trio.BrokenResourceError,
|
Exception,
|
||||||
trio.Cancelled, # by local cancellation
|
# trio.BrokenResourceError,
|
||||||
trio.ClosedResourceError, # by self._rx_chan
|
# trio.Cancelled, # by local cancellation
|
||||||
ContextCancelled,
|
# trio.ClosedResourceError, # by self._rx_chan
|
||||||
|
# ContextCancelled,
|
||||||
|
# ConnectionResetError,
|
||||||
) as err:
|
) as err:
|
||||||
|
|
||||||
# XXX: there may be a race with the portal teardown
|
# XXX: there may be a race with the portal teardown
|
||||||
|
@ -485,6 +506,7 @@ async def _breakpoint(
|
||||||
|
|
||||||
|
|
||||||
@cm
|
@cm
|
||||||
|
@pdb.hideframe
|
||||||
def _open_pdb() -> Iterator[PdbwTeardown]:
|
def _open_pdb() -> Iterator[PdbwTeardown]:
|
||||||
|
|
||||||
# XXX: setting these flags on the pdb instance are absolutely
|
# XXX: setting these flags on the pdb instance are absolutely
|
||||||
|
@ -492,6 +514,7 @@ def _open_pdb() -> Iterator[PdbwTeardown]:
|
||||||
# stdlib's pdb supports entering the current sync frame on a SIGINT,
|
# stdlib's pdb supports entering the current sync frame on a SIGINT,
|
||||||
# with ``trio`` we pretty much never want this and if we did we can
|
# with ``trio`` we pretty much never want this and if we did we can
|
||||||
# handle it in the ``tractor`` task runtime.
|
# handle it in the ``tractor`` task runtime.
|
||||||
|
__tracebackhide__ = True
|
||||||
|
|
||||||
pdb = PdbwTeardown()
|
pdb = PdbwTeardown()
|
||||||
pdb.allow_kbdint = True
|
pdb.allow_kbdint = True
|
||||||
|
@ -564,7 +587,7 @@ def shield_sigint(
|
||||||
else:
|
else:
|
||||||
# If we haven't tried to cancel the runtime then do that instead
|
# If we haven't tried to cancel the runtime then do that instead
|
||||||
# of raising a KBI (which may non-gracefully destroy
|
# of raising a KBI (which may non-gracefully destroy
|
||||||
# a ``trio.run()``).
|
# a ``trio.run()``).
|
||||||
if not actor._cancel_called:
|
if not actor._cancel_called:
|
||||||
actor.cancel_soon()
|
actor.cancel_soon()
|
||||||
|
|
||||||
|
@ -591,6 +614,7 @@ def shield_sigint(
|
||||||
print(pdb.prompt, end='', flush=True)
|
print(pdb.prompt, end='', flush=True)
|
||||||
|
|
||||||
|
|
||||||
|
@pdb.hideframe
|
||||||
@cm
|
@cm
|
||||||
def disable_sigint(
|
def disable_sigint(
|
||||||
pdb: Optional[PdbwTeardown] = None
|
pdb: Optional[PdbwTeardown] = None
|
||||||
|
@ -601,10 +625,10 @@ def disable_sigint(
|
||||||
|
|
||||||
# ensure the ``contextlib.contextmanager`` frame inside the wrapping
|
# ensure the ``contextlib.contextmanager`` frame inside the wrapping
|
||||||
# ``.__exit__()`` method isn't shown either.
|
# ``.__exit__()`` method isn't shown either.
|
||||||
frame = sys._getframe()
|
# frame = sys._getframe()
|
||||||
last_f = frame.f_back
|
# last_f = frame.f_back
|
||||||
if last_f:
|
# last_f.f_globals['__tracebackhide__'] = True
|
||||||
last_f.f_globals['__tracebackhide__'] = True
|
|
||||||
# NOTE: this seems like a form of cpython bug wherein
|
# NOTE: this seems like a form of cpython bug wherein
|
||||||
# it's likely that ``functools.WRAPPER_ASSIGNMENTS`` should
|
# it's likely that ``functools.WRAPPER_ASSIGNMENTS`` should
|
||||||
# probably contain this attr name?
|
# probably contain this attr name?
|
||||||
|
@ -625,8 +649,13 @@ def disable_sigint(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _set_trace(actor=None):
|
@pdb.hideframe
|
||||||
|
def _set_trace(
|
||||||
|
actor: Optional[tractor.Actor] = None
|
||||||
|
):
|
||||||
__tracebackhide__ = True
|
__tracebackhide__ = True
|
||||||
|
actor = actor or tractor.current_actor()
|
||||||
|
|
||||||
with (
|
with (
|
||||||
_open_pdb() as pdb,
|
_open_pdb() as pdb,
|
||||||
disable_sigint(pdb=pdb),
|
disable_sigint(pdb=pdb),
|
||||||
|
@ -640,7 +669,8 @@ def _set_trace(actor=None):
|
||||||
)
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# we entered the global ``breakpoint()`` built-in from sync code
|
# we entered the global ``breakpoint()`` built-in from sync code?
|
||||||
|
assert 0, 'Woa this path finally triggered?'
|
||||||
global _local_task_in_debug, _pdb_release_hook
|
global _local_task_in_debug, _pdb_release_hook
|
||||||
_local_task_in_debug = 'sync'
|
_local_task_in_debug = 'sync'
|
||||||
|
|
||||||
|
@ -651,7 +681,7 @@ def _set_trace(actor=None):
|
||||||
|
|
||||||
pdb.set_trace(
|
pdb.set_trace(
|
||||||
# start 2 levels up in user code
|
# start 2 levels up in user code
|
||||||
frame=sys._getframe().f_back,
|
frame=sys._getframe().f_back.f_back,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -661,11 +691,15 @@ breakpoint = partial(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pdb.hideframe
|
||||||
def _post_mortem(actor):
|
def _post_mortem(actor):
|
||||||
|
|
||||||
__tracebackhide__ = True
|
__tracebackhide__ = True
|
||||||
|
|
||||||
with (
|
with (
|
||||||
|
# noop()
|
||||||
_open_pdb() as pdb,
|
_open_pdb() as pdb,
|
||||||
disable_sigint(pdb=pdb),
|
# disable_sigint(pdb=pdb),
|
||||||
):
|
):
|
||||||
log.pdb(f"\nAttaching to pdb in crashed actor: {actor.uid}\n")
|
log.pdb(f"\nAttaching to pdb in crashed actor: {actor.uid}\n")
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue