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
Tyler Goodlet 2022-02-06 22:14:16 -05:00
parent 1524c94b23
commit 1142b802d3
1 changed files with 53 additions and 19 deletions

View File

@ -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
@ -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")