-
Notifications
You must be signed in to change notification settings - Fork 12
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
Wen? Multiprocessing-native debugger now! #129
Merged
Merged
Changes from all commits
Commits
Show all changes
61 commits
Select commit
Hold shift + click to select a range
8c97f7b
Create runtime variables
goodboy b11e913
Initial attempt at multi-actor debugging
goodboy b06d4b0
Add support for "debug mode"
goodboy 1d1c881
WIP debugging test script
goodboy e7ee0fe
Pass a copy of the expected exposed modules
goodboy 8eb9a74
Add multi-process debugging support using `pdbpp`
goodboy f7cd2be
Play with re-entrant trace
goodboy efd7095
Add pdbpp as dep
goodboy abaa2f5
Drop uneeded `parent_chan_cs()` cancel call
goodboy 68773d5
Always expose the debug module
goodboy f9ef3fc
Cleanups and more comments
goodboy ebb21b9
Support re-entrant breakpoints
goodboy fd5fb92
Sparsen some lines
goodboy bd157e0
Port to service nursery
goodboy 291ecec
Maybe not sticky by default
goodboy 150179b
Support entering post mortem on crashes in root actor
goodboy 8b6e9f5
Port to new debug api, set `_is_root` state flag on startup
goodboy 09daba4
Explicitly handle `debug_mode` flag correctly
goodboy 9e1d9a8
Add an internal context stack
goodboy f1b242f
Block SIGINT handling while in the debugger
goodboy 363498b
Disable SIGINT handling in child processes
goodboy 25e9392
Add a cancel scope around child debugger requests
goodboy 5dd2d35
Huh, maybe we don't need to block SIGINT
goodboy d7a472c
Update our debugging example to wait on results
goodboy fc2cb61
Make "hard kill" just a `Process.terminate()`
goodboy 29ed065
Ack our inability to hard kill sub-procs
goodboy 0a2a94f
Add initial root actor debugger tests
goodboy 9067bb2
Shorten arbiter contact timeout
goodboy 73a32f7
Add initial subactor debug tests
goodboy a2151cd
Allow re-entrant breakpoints during pdb stepping
goodboy e387e8b
Add a multi-subactor test with nesting
goodboy 83a4511
Add "root mailbox" contact info passing
goodboy 31c1a32
Add re-entrant root breakpoint test; demonstrates a bug..
goodboy d43d367
Facepalm: tty locking from root doesn't require an extra task
goodboy 3710259
Add a multi-subactor test where the root errors
goodboy 2b53c74
Change to relative conftest.py imports
goodboy abf8bb2
Add a deep nested error propagation test
goodboy 0711208
Add mention subactor uid during locking
goodboy acb4cb0
Add test showing issue with child in tty lock when cancelled
goodboy 0e344ee
Add a "cancel arrives during a sync sleep in child" test
goodboy 79c38b0
Report `trio.Cancelled` when exhausting portals..
goodboy a88a6ba
Add pattern matching to test
goodboy c41e5c8
Fix missing await
goodboy 1710b64
Make tests a package (for relative imports)
goodboy c375a2d
mypy fixes
goodboy 0ce6d2b
Add `pexpect` dep for debugger tests
goodboy 573b8fe
Add better actor cancellation tracking
goodboy 08ff989
Add some comments
goodboy 24ef919
Skip sync sleep test on mp backend
goodboy ba52de7
Skip quad ex on local mp tests as well
goodboy e3c2694
Support debug mode only on the trio backend
goodboy 6669660
Revert "Change to relative conftest.py imports"
goodboy a49deb4
Revert "Make tests a package (for relative imports)"
goodboy a934eb0
Factor `repodir()` helper into conftest.py
goodboy fd59f4a
On windows .spawn dne?
goodboy 15edcc6
Skip it on windows too
goodboy 1b6ee2e
Skip sync sleep test on windows
goodboy 0177268
Report on skipped tests
goodboy 1c25f25
Drop travisCI; it's slower and has worse windows support.
goodboy bba47e4
Add gh actions badge
goodboy 61a8df3
Comments tweak
goodboy File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
examples/debugging/multi_nested_subactors_error_up_through_nurseries.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import tractor | ||
|
||
|
||
async def name_error(): | ||
"Raise a ``NameError``" | ||
getattr(doggypants) | ||
|
||
|
||
async def breakpoint_forever(): | ||
"Indefinitely re-enter debugger in child actor." | ||
while True: | ||
await tractor.breakpoint() | ||
|
||
|
||
async def spawn_until(depth=0): | ||
""""A nested nursery that triggers another ``NameError``. | ||
""" | ||
async with tractor.open_nursery() as n: | ||
if depth < 1: | ||
# await n.run_in_actor('breakpoint_forever', breakpoint_forever) | ||
await n.run_in_actor('name_error', name_error) | ||
else: | ||
depth -= 1 | ||
await n.run_in_actor(f'spawn_until_{depth}', spawn_until, depth=depth) | ||
|
||
|
||
async def main(): | ||
"""The main ``tractor`` routine. | ||
|
||
The process tree should look as approximately as follows when the debugger | ||
first engages: | ||
|
||
python examples/debugging/multi_nested_subactors_bp_forever.py | ||
โโ python -m tractor._child --uid ('spawner1', '7eab8462 ...) | ||
โ โโ python -m tractor._child --uid ('spawn_until_3', 'afcba7a8 ...) | ||
โ โโ python -m tractor._child --uid ('spawn_until_2', 'd2433d13 ...) | ||
โ โโ python -m tractor._child --uid ('spawn_until_1', '1df589de ...) | ||
โ โโ python -m tractor._child --uid ('spawn_until_0', '3720602b ...) | ||
โ | ||
โโ python -m tractor._child --uid ('spawner0', '1d42012b ...) | ||
โโ python -m tractor._child --uid ('spawn_until_2', '2877e155 ...) | ||
โโ python -m tractor._child --uid ('spawn_until_1', '0502d786 ...) | ||
โโ python -m tractor._child --uid ('spawn_until_0', 'de918e6d ...) | ||
|
||
""" | ||
async with tractor.open_nursery() as n: | ||
|
||
# spawn both actors | ||
portal = await n.run_in_actor('spawner0', spawn_until, depth=3) | ||
portal1 = await n.run_in_actor('spawner1', spawn_until, depth=4) | ||
|
||
# gah still an issue here. | ||
# await portal.result() | ||
# await portal1.result() | ||
|
||
|
||
if __name__ == '__main__': | ||
tractor.run(main, debug_mode=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import tractor | ||
|
||
|
||
async def name_error(): | ||
"Raise a ``NameError``" | ||
getattr(doggypants) | ||
|
||
|
||
async def spawn_error(): | ||
""""A nested nursery that triggers another ``NameError``. | ||
""" | ||
async with tractor.open_nursery() as n: | ||
portal = await n.run_in_actor('name_error_1', name_error) | ||
return await portal.result() | ||
|
||
|
||
async def main(): | ||
"""The main ``tractor`` routine. | ||
|
||
The process tree should look as approximately as follows: | ||
|
||
python examples/debugging/multi_subactors.py | ||
โโ python -m tractor._child --uid ('name_error', 'a7caf490 ...) | ||
`-python -m tractor._child --uid ('spawn_error', '52ee14a5 ...) | ||
`-python -m tractor._child --uid ('name_error', '3391222c ...) | ||
""" | ||
async with tractor.open_nursery() as n: | ||
|
||
# spawn both actors | ||
portal = await n.run_in_actor('name_error', name_error) | ||
portal1 = await n.run_in_actor('spawn_error', spawn_error) | ||
|
||
# trigger a root actor error | ||
assert 0 | ||
|
||
# attempt to collect results (which raises error in parent) | ||
# still has some issues where the parent seems to get stuck | ||
await portal.result() | ||
await portal1.result() | ||
|
||
|
||
if __name__ == '__main__': | ||
tractor.run(main, debug_mode=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import tractor | ||
import trio | ||
|
||
|
||
async def breakpoint_forever(): | ||
"Indefinitely re-enter debugger in child actor." | ||
while True: | ||
await trio.sleep(0.1) | ||
await tractor.breakpoint() | ||
|
||
|
||
async def name_error(): | ||
"Raise a ``NameError``" | ||
getattr(doggypants) | ||
|
||
|
||
async def spawn_error(): | ||
""""A nested nursery that triggers another ``NameError``. | ||
""" | ||
async with tractor.open_nursery() as n: | ||
portal = await n.run_in_actor('name_error_1', name_error) | ||
return await portal.result() | ||
|
||
|
||
async def main(): | ||
"""The main ``tractor`` routine. | ||
|
||
The process tree should look as approximately as follows: | ||
|
||
-python examples/debugging/multi_subactors.py | ||
|-python -m tractor._child --uid ('name_error', 'a7caf490 ...) | ||
|-python -m tractor._child --uid ('bp_forever', '1f787a7e ...) | ||
`-python -m tractor._child --uid ('spawn_error', '52ee14a5 ...) | ||
`-python -m tractor._child --uid ('name_error', '3391222c ...) | ||
""" | ||
async with tractor.open_nursery() as n: | ||
|
||
# Spawn both actors, don't bother with collecting results | ||
# (would result in a different debugger outcome due to parent's | ||
# cancellation). | ||
await n.run_in_actor('bp_forever', breakpoint_forever) | ||
await n.run_in_actor('name_error', name_error) | ||
await n.run_in_actor('spawn_error', spawn_error) | ||
|
||
|
||
if __name__ == '__main__': | ||
tractor.run(main, debug_mode=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import trio | ||
import tractor | ||
|
||
|
||
async def main(): | ||
|
||
await trio.sleep(0.1) | ||
|
||
await tractor.breakpoint() | ||
|
||
await trio.sleep(0.1) | ||
|
||
|
||
if __name__ == '__main__': | ||
tractor.run(main, debug_mode=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import tractor | ||
|
||
|
||
async def main(): | ||
|
||
while True: | ||
await tractor.breakpoint() | ||
|
||
|
||
if __name__ == '__main__': | ||
tractor.run(main, debug_mode=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import tractor | ||
|
||
|
||
async def main(): | ||
assert 0 | ||
|
||
|
||
if __name__ == '__main__': | ||
tractor.run(main, debug_mode=True) |
48 changes: 48 additions & 0 deletions
48
examples/debugging/root_cancelled_but_child_is_in_tty_lock.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import tractor | ||
|
||
|
||
async def name_error(): | ||
"Raise a ``NameError``" | ||
getattr(doggypants) | ||
|
||
|
||
async def spawn_until(depth=0): | ||
""""A nested nursery that triggers another ``NameError``. | ||
""" | ||
async with tractor.open_nursery() as n: | ||
if depth < 1: | ||
# await n.run_in_actor('breakpoint_forever', breakpoint_forever) | ||
await n.run_in_actor('name_error', name_error) | ||
else: | ||
depth -= 1 | ||
await n.run_in_actor(f'spawn_until_{depth}', spawn_until, depth=depth) | ||
|
||
|
||
async def main(): | ||
"""The main ``tractor`` routine. | ||
|
||
The process tree should look as approximately as follows when the debugger | ||
first engages: | ||
|
||
python examples/debugging/multi_nested_subactors_bp_forever.py | ||
โโ python -m tractor._child --uid ('spawner1', '7eab8462 ...) | ||
โ โโ python -m tractor._child --uid ('spawn_until_0', '3720602b ...) | ||
โ โโ python -m tractor._child --uid ('name_error', '505bf71d ...) | ||
โ | ||
โโ python -m tractor._child --uid ('spawner0', '1d42012b ...) | ||
โโ python -m tractor._child --uid ('name_error', '6c2733b8 ...) | ||
|
||
""" | ||
async with tractor.open_nursery() as n: | ||
|
||
# spawn both actors | ||
portal = await n.run_in_actor('spawner0', spawn_until, depth=0) | ||
portal1 = await n.run_in_actor('spawner1', spawn_until, depth=1) | ||
|
||
# nursery cancellation should be triggered due to propagated error | ||
await portal.result() | ||
await portal1.result() | ||
|
||
|
||
if __name__ == '__main__': | ||
tractor.run(main, debug_mode=True, loglevel='warning') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import trio | ||
import tractor | ||
|
||
|
||
async def breakpoint_forever(): | ||
"""Indefinitely re-enter debugger in child actor. | ||
""" | ||
while True: | ||
await trio.sleep(0.1) | ||
await tractor.breakpoint() | ||
|
||
|
||
async def main(): | ||
|
||
async with tractor.open_nursery() as n: | ||
|
||
portal = await n.run_in_actor( | ||
'breakpoint_forever', | ||
breakpoint_forever, | ||
) | ||
await portal.result() | ||
|
||
|
||
if __name__ == '__main__': | ||
tractor.run(main, debug_mode=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import tractor | ||
|
||
|
||
async def name_error(): | ||
getattr(doggypants) | ||
|
||
|
||
async def main(): | ||
async with tractor.open_nursery() as n: | ||
|
||
portal = await n.run_in_actor('name_error', name_error) | ||
await portal.result() | ||
|
||
|
||
if __name__ == '__main__': | ||
tractor.run(main, debug_mode=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,3 +3,4 @@ pytest-trio | |
pdbpp | ||
mypy | ||
trio_typing | ||
pexpect |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is actually required as a dependency since we needed something where we could hook into the debugger's "tear down" (i.e. where a user releases the debugger and let's code run again using either of the
continue
orquit
commands).The main requirement for this is tty locking in the root actor such that no two subactors can use it simultaneously.