diff options
author | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2016-11-04 12:18:02 -0400 |
---|---|---|
committer | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2016-11-04 12:18:02 -0400 |
commit | cc32f2cf5990bfefafaf9cab08eabe944f4ade34 (patch) | |
tree | c2a3c8a5a6c5fc6f19e6b4f9d8eb50520d2251ca /buildscripts | |
parent | d60a852dad66cb40c2ba737c04685028767ee1c7 (diff) | |
download | mongo-cc32f2cf5990bfefafaf9cab08eabe944f4ade34.tar.gz |
SERVER-26842 dump the go stack traces on hung tools in the hang analyzer
Diffstat (limited to 'buildscripts')
-rwxr-xr-x | buildscripts/hang_analyzer.py | 33 |
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())) |