summaryrefslogtreecommitdiff
path: root/buildscripts/resmokelib/sighandler.py
diff options
context:
space:
mode:
authorRobert Guo <robert.guo@mongodb.com>2020-07-28 15:48:14 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-07-28 21:18:52 +0000
commit0cbc4ea6a9865906736bae49be34e4359dd3853e (patch)
treec46064f59beec54f3820a41e87d1c1f9be3080b6 /buildscripts/resmokelib/sighandler.py
parent214379825c248f5a5e5f0a01ad9863b900faaf30 (diff)
downloadmongo-0cbc4ea6a9865906736bae49be34e4359dd3853e.tar.gz
SERVER-46687 Run hang-analyzer from resmoke and integrate with archival
This reverts commit 6ac765dd18a96bbe43eb22a30ddaf3a4d42ae2e3.
Diffstat (limited to 'buildscripts/resmokelib/sighandler.py')
-rw-r--r--buildscripts/resmokelib/sighandler.py39
1 files changed, 39 insertions, 0 deletions
diff --git a/buildscripts/resmokelib/sighandler.py b/buildscripts/resmokelib/sighandler.py
index 875b9f4c625..103af35e85f 100644
--- a/buildscripts/resmokelib/sighandler.py
+++ b/buildscripts/resmokelib/sighandler.py
@@ -8,8 +8,13 @@ import threading
import time
import traceback
+import psutil
+
from buildscripts.resmokelib import reportfile
from buildscripts.resmokelib import testing
+from buildscripts.resmokelib import config
+from buildscripts.resmokelib.hang_analyzer import hang_analyzer
+from buildscripts.resmokelib import parser
_IS_WINDOWS = (sys.platform == "win32")
if _IS_WINDOWS:
@@ -59,6 +64,15 @@ def register(logger, suites, start_time):
testing.suite.Suite.log_summaries(logger, suites, time.time() - start_time)
+ if 'is_inner_level' not in config.INTERNAL_PARAMS:
+ # Gather and analyze pids of all subprocesses.
+ # Do nothing for child resmoke process started by another resmoke process
+ # (e.g. backup_restore.js) The child processes of the child resmoke will be
+ # analyzed by the signal handler of the top-level resmoke process.
+ # i.e. the next few lines of code.
+ pids_to_analyze = _get_pids()
+ _analyze_pids(logger, pids_to_analyze)
+
# On Windows spawn a thread to wait on an event object for signal to dump stacks. For Cygwin
# platforms, we use a signal handler since it supports POSIX signals.
if _IS_WINDOWS:
@@ -105,3 +119,28 @@ def _dump_stacks(logger, header_msg):
sb.append("".join(traceback.format_stack(stack)))
logger.info("\n".join(sb))
+
+
+def _get_pids():
+ """Return all PIDs spawned by the current resmoke process and their child PIDs."""
+ pids = [] # Gather fixture PIDs + any PIDs spawned by the fixtures.
+ parent = psutil.Process() # current process
+ for child in parent.children(recursive=True):
+ # Don't signal python threads. They have already been signalled in the evergreen timeout
+ # section.
+ if 'python' not in child.name().lower():
+ pids.append(child.pid)
+
+ return pids
+
+
+def _analyze_pids(logger, pids):
+ """Analyze the PIDs spawned by the current resmoke process."""
+ hang_analyzer_args = [
+ 'hang-analyzer', '-o', 'file', '-o', 'stdout', '-k', '-d', ','.join([str(p) for p in pids])
+ ]
+
+ if not os.getenv('ASAN_OPTIONS'):
+ hang_analyzer_args.append('-c')
+ _hang_analyzer = parser.parse_command_line(hang_analyzer_args, logger=logger)
+ _hang_analyzer.execute()