summaryrefslogtreecommitdiff
path: root/buildscripts
diff options
context:
space:
mode:
authorMark Benvenuto <mark.benvenuto@mongodb.com>2016-11-04 12:18:02 -0400
committerMark Benvenuto <mark.benvenuto@mongodb.com>2016-11-04 12:18:02 -0400
commitcc32f2cf5990bfefafaf9cab08eabe944f4ade34 (patch)
treec2a3c8a5a6c5fc6f19e6b4f9d8eb50520d2251ca /buildscripts
parentd60a852dad66cb40c2ba737c04685028767ee1c7 (diff)
downloadmongo-cc32f2cf5990bfefafaf9cab08eabe944f4ade34.tar.gz
SERVER-26842 dump the go stack traces on hung tools in the hang analyzer
Diffstat (limited to 'buildscripts')
-rwxr-xr-xbuildscripts/hang_analyzer.py33
1 files changed, 24 insertions, 9 deletions
diff --git a/buildscripts/hang_analyzer.py b/buildscripts/hang_analyzer.py
index 8fdf40bc274..50d0f3a86ef 100755
--- a/buildscripts/hang_analyzer.py
+++ b/buildscripts/hang_analyzer.py
@@ -439,18 +439,18 @@ def check_dump_quota(quota, ext):
return (size_sum <= quota)
-def signal_process(pid):
- """Signal python process with SIGUSR1, N/A on Windows"""
+def signal_process(pid, signalnum):
+ """Signal process with signal, N/A on Windows"""
try:
- os.kill(pid, signal.SIGUSR1)
+ os.kill(pid, signalnum)
- print "Waiting for python process to report"
+ print "Waiting for process to report"
time.sleep(5)
except OSError,e:
- print "Hit OS error trying to signal python process: " + str(e)
+ print "Hit OS error trying to signal process: " + str(e)
except AttributeError:
- print "Cannot send signal to python on Windows"
+ print "Cannot send signal to a process on Windows"
def timeout_protector():
@@ -489,9 +489,11 @@ def main():
print "Cannot determine Unix Current Login, not supported on Windows"
interesting_processes = ["mongo", "mongod", "mongos", "_test", "dbtest", "python", "java"]
+ go_processes = []
parser = OptionParser(description=__doc__)
parser.add_option('-p', '--process_names', dest='process_names', help='List of process names to analyze')
+ parser.add_option('-g', '--go_process_names', dest='go_process_names', help='List of go process names to analyze')
parser.add_option('-s', '--max_core_dumps_size', dest='max_core_dumps_size', default=10000, help='Maximum total size of core dumps to keep in megabytes')
(options, args) = parser.parse_args()
@@ -499,6 +501,10 @@ def main():
if options.process_names is not None:
interesting_processes = options.process_names.split(',')
+ if options.go_process_names is not None:
+ go_processes = options.go_process_names.split(',')
+ interesting_processes += go_processes
+
[ps, dbg, jstack] = get_hang_analyzers()
if( ps == None or (dbg == None and jstack == None)):
@@ -511,7 +517,7 @@ def main():
processes_orig = ps.dump_processes()
- # Find all running interesting processes.
+ # Find all running interesting processes by doing a substring match.
processes = [a for a in processes_orig
if any([a[1].find(ip) >= 0 for ip in interesting_processes]) and a[0] != os.getpid()]
@@ -523,7 +529,7 @@ def main():
for process in processes_orig:
sys.stdout.write("Ignoring process %d of %s\n" % (process[0], process[1]))
else:
- # Dump all other processes, except python & java.
+ # Dump all other processes including go programs, except python & java.
for process in [a for a in processes if not re.match("^(java|python)", a[1])]:
sys.stdout.write("Dumping process %d of %s\n" % (process[0], process[1]))
dbg.dump_info(process[0], process[1], sys.stdout, check_dump_quota(max_dump_size_bytes, dbg.get_dump_ext()))
@@ -533,9 +539,18 @@ def main():
sys.stdout.write("Dumping process %d of %s\n" % (process[0], process[1]))
jstack.dump_info(process[0], process[1], sys.stdout)
+ # Signal go processes to ensure they print out stack traces, and die on POSIX OSes.
+ # On Windows, this will simply kill the process since python emulates SIGABRT as
+ # TerminateProcess.
+ # Note: The stacktrace output may be captured elsewhere (i.e. resmoke).
+ for process in [a for a in processes if a[1] in go_processes]:
+ sys.stdout.write("Sending signal SIGABRT to go process %d of %s\n" % (process[0], process[1]))
+ signal_process(process[0], signal.SIGABRT)
+
# Dump python processes after signalling them.
for process in [a for a in processes if a[1].startswith("python")]:
- signal_process(process[0])
+ sys.stdout.write("Sending signal SIGUSR1 to python process %d of %s\n" % (process[0], process[1]))
+ signal_process(process[0], signal.SIGUSR1)
dbg.dump_info(process[0], process[1], sys.stdout, check_dump_quota(max_dump_size_bytes, dbg.get_dump_ext()))