Skip to content

Add --sigterm flag - #65

Merged
jaltmayerpizzorno merged 4 commits into
plasma-umass:mainfrom
liammcinroy:main
Aug 6, 2026
Merged

Add --sigterm flag#65
jaltmayerpizzorno merged 4 commits into
plasma-umass:mainfrom
liammcinroy:main

Conversation

@liammcinroy

@liammcinroy liammcinroy commented May 6, 2025

Copy link
Copy Markdown
Contributor

Adds a --sigterm flag (matching coverage.py's sigterm flag) to still write the coverage output if a SIGTERM signal is sent.

Helpful for using slipcover in e.g. docker containers.

Tested with a simple while True: ... script and then a kill -SIGTERM. I'm not too familiar with what sort of cleanup may be necessary for more complex cases, so I'd welcome any suggestions on how to truly gracefully exit.

Also, this currently ignores --fail-under, since it exits immediately instead. I'm happy to update it to e.g. raise an exception that is caught by a context manager surrounding the runpy / exec calls, so that the normal flow in __main__ afterwards is maintained. I chose not to for now, since the atexit isn't currently doing that either.

Thanks for creating/maintaining this project!


Update: fixed two bugs in the original handler: it called sci_atexit() manually and then sys.exit(0), which re-triggered the same already-registered atexit handler a second time, double-writing the report; and a forked child inheriting the handler went through that same top-level path instead of the already-shimmed os._exit(), racing the real parent for --out and silently dropping the child's coverage on merge. Added two integration tests exercising real --sigterm + real signal delivery (including a real forked child) end to end. The --fail-under caveat above is still accurate and unaddressed.

liammcinroy and others added 4 commits May 6, 2025 16:34
# Conflicts:
#	src/slipcover/__main__.py
The handler called sci_atexit() manually and then sys.exit(0), which
re-triggers the same already atexit.register()'d sci_atexit() a second
time during normal interpreter shutdown -- removing the redundant
manual call fixes this; atexit already runs it exactly once. A forked
child inheriting the handler also went through this same top-level
path instead of the already-shimmed os._exit() (which correctly writes
the child's own coverage to a tempfile for the parent to merge),
racing the real parent for the same --out file and silently dropping
the child's coverage on merge.

Adds --sigterm to config.py's _BOOL_KEYS (caught immediately by the
drift-detecting oracle test), and two integration tests exercising the
real --sigterm flag and real signal delivery end to end (no internal
functions called directly): one confirms the report is written exactly
once on a top-level SIGTERM, the other has the target script fork for
real and SIGTERMs the child specifically, confirming its partial
coverage survives the merge instead of being lost.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@jaltmayerpizzorno

Copy link
Copy Markdown
Collaborator

CI has been stuck due to GitHub's Actions incident.

@jaltmayerpizzorno
jaltmayerpizzorno merged commit 9f0f7a6 into plasma-umass:main Aug 6, 2026
41 of 55 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants