-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
python: Ignore SIGINT while running wrapped program from zip #20256
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,7 @@ import sys | |
del sys.path[0] | ||
|
||
import os | ||
import signal | ||
import subprocess | ||
|
||
def IsRunningFromZip(): | ||
|
@@ -354,11 +355,21 @@ def ExecuteFile(python_program, main_filename, args, env, module_space, | |
ret_code = _RunForCoverage(python_program, main_filename, args, env, | ||
coverage_entrypoint, workspace) | ||
else: | ||
ret_code = subprocess.call( | ||
[python_program, main_filename] + args, | ||
env=env, | ||
cwd=workspace | ||
) | ||
# Temporarily ignoring SIGINT to not interfere with python_program's own | ||
# interrupt handling. SIGINT does not need to be forwarded to python_program. | ||
# It will receive the signal automatically as part of the same process group. | ||
def noop(sig, frame): | ||
pass | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't it necessary to forward the SIGINT to the wrapped process? Or does this happen automatically somehow? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My understanding is that Please correct me if I'm wrong, or missing a significant edge case. This can be observed with this program: Click to expand
import os
import signal
import subprocess as sp
import sys
import time
pid = os.getpid()
pgid = os.getpgid(pid)
is_parent_process = len(sys.argv) == 1
print("parent" if is_parent_process else "child")
print(f" {pid=}")
print(f" {pgid=}")
def noop(sig, frame):
pass
try:
if is_parent_process:
# signal.signal(signal.SIGINT, noop)
sp.call(
[sys.executable, __file__, "child"],
# start_new_session=True,
)
else:
print("press CTRL+C now")
time.sleep(1000)
except:
exc_type = sys.exc_info()[0]
print("Exception caught", pid, "of type:", exc_type) If you run it, you'll see two processes spawned:
and if you interrupt it, you will see that both of them receive
Now if you uncomment
If you uncomment
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great, I didn't know that. Thanks for the detailed example! It could be worth adding a comment with a short explanation so that future readers of this part of the code don't see the same bug that isn't there. |
||
signal.signal(signal.SIGINT, noop) | ||
|
||
try: | ||
ret_code = subprocess.call( | ||
[python_program, main_filename] + args, | ||
env=env, | ||
cwd=workspace | ||
) | ||
finally: | ||
signal.signal(signal.SIGINT, signal.SIG_DFL) | ||
|
||
if delete_module_space: | ||
# NOTE: dirname() is called because CreateModuleSpace() creates a | ||
|
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.
Assuming this is right, perhaps the same should be applied to internals of
_RunForCoverage
. I'm not sure yet.Any feedback appreciated.