diff options
-rw-r--r-- | coverage/multiproc.py | 18 | ||||
-rw-r--r-- | tests/test_concurrency.py | 17 |
2 files changed, 30 insertions, 5 deletions
diff --git a/coverage/multiproc.py b/coverage/multiproc.py index bab81475..c466301f 100644 --- a/coverage/multiproc.py +++ b/coverage/multiproc.py @@ -6,6 +6,8 @@ import multiprocessing import multiprocessing.process import os +import sys +import traceback from coverage import env from coverage.misc import contract @@ -27,14 +29,20 @@ class ProcessWithCoverage(OriginalProcess): # pylint: disable=abstract-m def _bootstrap(self, *args, **kwargs): # pylint: disable=arguments-differ """Wrapper around _bootstrap to start coverage.""" - from coverage import Coverage # avoid circular import - cov = Coverage(data_suffix=True) - cov._warn_preimported_source = False - cov.start() - debug = cov._debug try: + from coverage import Coverage # avoid circular import + cov = Coverage(data_suffix=True) + cov._warn_preimported_source = False + cov.start() + debug = cov._debug if debug.should("multiproc"): debug.write("Calling multiprocessing bootstrap") + except Exception: + print("Exception during multiprocessing bootstrap init:") + traceback.print_exc(file=sys.stdout) + sys.stdout.flush() + raise + try: return original_bootstrap(self, *args, **kwargs) finally: if debug.should("multiproc"): diff --git a/tests/test_concurrency.py b/tests/test_concurrency.py index 436df803..3a127499 100644 --- a/tests/test_concurrency.py +++ b/tests/test_concurrency.py @@ -476,6 +476,23 @@ class MultiprocessingTest(CoverageTest): expected_out = "{nprocs} pids, total = {total}".format(nprocs=nprocs, total=total) self.try_multiprocessing_code_with_branching(code, expected_out) + def test_multiprocessing_bootstrap_error_handling(self): + # An exception during bootstrapping will be reported. + self.make_file("multi.py", """\ + import multiprocessing + if __name__ == "__main__": + with multiprocessing.Manager(): + pass + """) + self.make_file(".coveragerc", """\ + [run] + concurrency = multiprocessing + _crash = _bootstrap + """) + out = self.run_command("coverage run multi.py") + self.assertIn("Exception during multiprocessing bootstrap init", out) + self.assertIn("Exception: Crashing because called by _bootstrap", out) + def test_coverage_stop_in_threads(): has_started_coverage = [] |