Only re-enable fauthandler during unconfigure if it was enabled before

This commit is contained in:
Bruno Oliveira 2021-01-25 12:28:00 -03:00
parent adc0f29b8f
commit 33861098d9
2 changed files with 33 additions and 13 deletions

View File

@ -12,6 +12,7 @@ from _pytest.store import StoreKey
fault_handler_stderr_key = StoreKey[TextIO]() fault_handler_stderr_key = StoreKey[TextIO]()
fault_handler_originally_enabled_key = StoreKey[bool]()
def pytest_addoption(parser: Parser) -> None: def pytest_addoption(parser: Parser) -> None:
@ -27,6 +28,7 @@ def pytest_configure(config: Config) -> None:
stderr_fd_copy = os.dup(get_stderr_fileno()) stderr_fd_copy = os.dup(get_stderr_fileno())
config._store[fault_handler_stderr_key] = open(stderr_fd_copy, "w") config._store[fault_handler_stderr_key] = open(stderr_fd_copy, "w")
config._store[fault_handler_originally_enabled_key] = faulthandler.is_enabled()
faulthandler.enable(file=config._store[fault_handler_stderr_key]) faulthandler.enable(file=config._store[fault_handler_stderr_key])
@ -38,9 +40,8 @@ def pytest_unconfigure(config: Config) -> None:
if fault_handler_stderr_key in config._store: if fault_handler_stderr_key in config._store:
config._store[fault_handler_stderr_key].close() config._store[fault_handler_stderr_key].close()
del config._store[fault_handler_stderr_key] del config._store[fault_handler_stderr_key]
# Re-enable the faulthandler, attaching it to the default sys.stderr if config._store.get(fault_handler_originally_enabled_key, False):
# so we can see crashes after pytest has finished, usually during # Re-enable the faulthandler if it was originally enabled.
# garbage collection during interpreter shutdown.
faulthandler.enable(file=get_stderr_fileno()) faulthandler.enable(file=get_stderr_fileno())

View File

@ -19,9 +19,7 @@ def test_enabled(pytester: Pytester) -> None:
assert result.ret != 0 assert result.ret != 0
def test_crash_near_exit(pytester: Pytester) -> None: def setup_crashing_test(pytester: Pytester) -> None:
"""Test that fault handler displays crashes that happen even after
pytest is exiting (for example, when the interpreter is shutting down)."""
pytester.makepyfile( pytester.makepyfile(
""" """
import faulthandler import faulthandler
@ -30,11 +28,32 @@ def test_crash_near_exit(pytester: Pytester) -> None:
atexit.register(faulthandler._sigabrt) atexit.register(faulthandler._sigabrt)
""" """
) )
result = pytester.runpytest_subprocess()
def test_crash_during_shutdown_captured(pytester: Pytester) -> None:
"""
Re-enable faulthandler if pytest encountered it enabled during configure.
We should be able to then see crashes during interpreter shutdown.
"""
setup_crashing_test(pytester)
args = (sys.executable, "-Xfaulthandler", "-mpytest")
result = pytester.run(*args)
result.stderr.fnmatch_lines(["*Fatal Python error*"]) result.stderr.fnmatch_lines(["*Fatal Python error*"])
assert result.ret != 0 assert result.ret != 0
def test_crash_during_shutdown_not_captured(pytester: Pytester) -> None:
"""
Check that pytest leaves faulthandler disabled if it was not enabled during configure.
This prevents us from seeing crashes during interpreter shutdown (see #8260).
"""
setup_crashing_test(pytester)
args = (sys.executable, "-mpytest")
result = pytester.run(*args)
result.stderr.no_fnmatch_line("*Fatal Python error*")
assert result.ret != 0
def test_disabled(pytester: Pytester) -> None: def test_disabled(pytester: Pytester) -> None:
"""Test option to disable fault handler in the command line.""" """Test option to disable fault handler in the command line."""
pytester.makepyfile( pytester.makepyfile(