Repair/update `stackscope` test

Seems that on 3.13 it's not showing our script code in the output now?
Gotta get an example for @oremanj to see what's up but really it'd be
nice to just custom format stuff above `trio`'s runtime by def..

Anyway, update the `.devx._stackscope`,
- log formatting to be a little more "sclangy" lookin.
- change the per-actor "delimiter" lines style.
- report the `signal.getsignal(SIGINT)` which i needed in the
  `sync_bp.py` with ctl-c causing a hang..
- mask the `_tree_dumped` duplicator log report as well as the "dumped
  fine" one.
- add an example `pkill --signal SIGUSR1` cmdline.

Tweak the test to cope with,
- not showing our script lines now.. which i've commented in the
  `assert_before()` patts..
- to expect the newly formatted delimiter (ascii) lines to separate the
  root vs. hanger sub-actor sections.
py313_support
Tyler Goodlet 2025-03-05 11:34:36 -05:00
parent c9234fbd9c
commit e7bb1edf97
3 changed files with 69 additions and 43 deletions

View File

@ -39,7 +39,6 @@ async def main(
loglevel='devx', loglevel='devx',
) as an, ) as an,
): ):
ptl: tractor.Portal = await an.start_actor( ptl: tractor.Portal = await an.start_actor(
'hanger', 'hanger',
enable_modules=[__name__], enable_modules=[__name__],
@ -54,13 +53,16 @@ async def main(
print( print(
'Yo my child hanging..?\n' 'Yo my child hanging..?\n'
'Sending SIGUSR1 to see a tree-trace!\n' # "i'm a user who wants to see a `stackscope` tree!\n"
) )
# XXX simulate the wrapping test's "user actions" # XXX simulate the wrapping test's "user actions"
# (i.e. if a human didn't run this manually but wants to # (i.e. if a human didn't run this manually but wants to
# know what they should do to reproduce test behaviour) # know what they should do to reproduce test behaviour)
if from_test: if from_test:
print(
f'Sending SIGUSR1 to {cpid!r}!\n'
)
os.kill( os.kill(
cpid, cpid,
signal.SIGUSR1, signal.SIGUSR1,

View File

@ -15,6 +15,7 @@ TODO:
''' '''
import os import os
import signal import signal
import time
from .conftest import ( from .conftest import (
expect, expect,
@ -47,41 +48,39 @@ def test_shield_pause(
] ]
) )
script_pid: int = child.pid
print( print(
'Sending SIGUSR1 to see a tree-trace!', f'Sending SIGUSR1 to {script_pid}\n'
f'(kill -s SIGUSR1 {script_pid})\n'
) )
os.kill( os.kill(
child.pid, script_pid,
signal.SIGUSR1, signal.SIGUSR1,
) )
time.sleep(0.2)
expect( expect(
child, child,
# end-of-tree delimiter # end-of-tree delimiter
"------ \('root', ", "end-of-\('root'",
) )
assert_before( assert_before(
child, child,
[ [
'Trying to dump `stackscope` tree..', # 'Srying to dump `stackscope` tree..',
'Dumping `stackscope` tree for actor', # 'Dumping `stackscope` tree for actor',
"('root'", # uid line "('root'", # uid line
# TODO!? this used to show?
# -[ ] mk reproducable for @oremanj?
#
# parent block point (non-shielded) # parent block point (non-shielded)
'await trio.sleep_forever() # in root', # 'await trio.sleep_forever() # in root',
] ]
) )
# expect(
# child,
# # relay to the sub should be reported
# 'Relaying `SIGUSR1`[10] to sub-actor',
# )
expect( expect(
child, child,
# end-of-tree delimiter # end-of-tree delimiter
"------ \('hanger', ", "end-of-\('hanger'",
) )
assert_before( assert_before(
child, child,
@ -91,11 +90,11 @@ def test_shield_pause(
"('hanger'", # uid line "('hanger'", # uid line
# TODO!? SEE ABOVE
# hanger LOC where it's shield-halted # hanger LOC where it's shield-halted
'await trio.sleep_forever() # in subactor', # 'await trio.sleep_forever() # in subactor',
] ]
) )
# breakpoint()
# simulate the user sending a ctl-c to the hanging program. # simulate the user sending a ctl-c to the hanging program.
# this should result in the terminator kicking in since # this should result in the terminator kicking in since

View File

@ -35,6 +35,7 @@ from signal import (
signal, signal,
getsignal, getsignal,
SIGUSR1, SIGUSR1,
SIGINT,
) )
# import traceback # import traceback
from types import ModuleType from types import ModuleType
@ -48,6 +49,7 @@ from tractor import (
_state, _state,
log as logmod, log as logmod,
) )
from tractor.devx import _debug
log = logmod.get_logger(__name__) log = logmod.get_logger(__name__)
@ -76,22 +78,45 @@ def dump_task_tree() -> None:
) )
actor: Actor = _state.current_actor() actor: Actor = _state.current_actor()
thr: Thread = current_thread() thr: Thread = current_thread()
current_sigint_handler: Callable = getsignal(SIGINT)
if (
current_sigint_handler
is not
_debug.DebugStatus._trio_handler
):
sigint_handler_report: str = (
'The default `trio` SIGINT handler was replaced?!'
)
else:
sigint_handler_report: str = (
'The default `trio` SIGINT handler is in use?!'
)
# sclang symbology
# |_<object>
# |_(Task/Thread/Process/Actor
# |_{Supervisor/Scope
# |_[Storage/Memory/IPC-Stream/Data-Struct
log.devx( log.devx(
f'Dumping `stackscope` tree for actor\n' f'Dumping `stackscope` tree for actor\n'
f'{actor.uid}:\n' f'(>: {actor.uid!r}\n'
f'|_{mp.current_process()}\n' f' |_{mp.current_process()}\n'
f' |_{thr}\n' f' |_{thr}\n'
f' |_{actor}\n\n' f' |_{actor}\n'
# start-of-trace-tree delimiter (mostly for testing)
'------ - ------\n'
'\n'
+
f'{tree_str}\n'
+
# end-of-trace-tree delimiter (mostly for testing)
f'\n' f'\n'
f'------ {actor.uid!r} ------\n' f'{sigint_handler_report}\n'
f'signal.getsignal(SIGINT) -> {current_sigint_handler!r}\n'
# f'\n'
# start-of-trace-tree delimiter (mostly for testing)
# f'------ {actor.uid!r} ------\n'
f'\n'
f'------ start-of-{actor.uid!r} ------\n'
f'|\n'
f'{tree_str}'
# end-of-trace-tree delimiter (mostly for testing)
f'|\n'
f'|_____ end-of-{actor.uid!r} ______\n'
) )
# TODO: can remove this right? # TODO: can remove this right?
# -[ ] was original code from author # -[ ] was original code from author
@ -123,11 +148,11 @@ def dump_tree_on_sig(
) -> None: ) -> None:
global _tree_dumped, _handler_lock global _tree_dumped, _handler_lock
with _handler_lock: with _handler_lock:
if _tree_dumped: # if _tree_dumped:
log.warning( # log.warning(
'Already dumped for this actor...??' # 'Already dumped for this actor...??'
) # )
return # return
_tree_dumped = True _tree_dumped = True
@ -161,9 +186,9 @@ def dump_tree_on_sig(
) )
raise raise
log.devx( # log.devx(
'Supposedly we dumped just fine..?' # 'Supposedly we dumped just fine..?'
) # )
if not relay_to_subs: if not relay_to_subs:
return return
@ -202,11 +227,11 @@ def enable_stack_on_sig(
(https://www.gnu.org/software/bash/manual/bash.html#Command-Substitution) (https://www.gnu.org/software/bash/manual/bash.html#Command-Substitution)
you could use: you could use:
>> kill -SIGUSR1 $(pgrep -f '<cmd>') >> kill -SIGUSR1 $(pgrep -f <part-of-cmd: str>)
Or with with `xonsh` (which has diff capture-from-subproc syntax) OR without a sub-shell,
>> kill -SIGUSR1 @$(pgrep -f '<cmd>') >> pkill --signal SIGUSR1 -f <part-of-cmd: str>
''' '''
try: try: