1# Lint as: python2, python3 2# Copyright Martin J. Bligh, Andy Whitcroft, 2006 3# 4# Shell class for a test, inherited by all individual tests 5# 6# Methods: 7# __init__ initialise 8# initialize run once for each job 9# setup run once for each new version of the test installed 10# run run the test (wrapped by job.run_test()) 11# 12# Data: 13# job backreference to the job this test instance is part of 14# outputdir eg. results/<job>/<testname.tag> 15# resultsdir eg. results/<job>/<testname.tag>/results 16# profdir eg. results/<job>/<testname.tag>/profiling 17# debugdir eg. results/<job>/<testname.tag>/debug 18# bindir eg. tests/<test> 19# src eg. tests/<test>/src 20# tmpdir eg. tmp/<testname.tag> 21 22import os, logging, resource, glob 23 24from autotest_lib.client.common_lib import utils 25from autotest_lib.client.common_lib import test as common_test 26from autotest_lib.client.bin import os_dep 27 28 29class test(common_test.base_test): 30 # Segmentation fault handling is something that is desirable only for 31 # client side tests. 32 def configure_crash_handler(self): 33 """ 34 Configure the crash handler by: 35 * Setting up core size to unlimited 36 * Putting an appropriate crash handler on /proc/sys/kernel/core_pattern 37 * Create files that the crash handler will use to figure which tests 38 are active at a given moment 39 40 The crash handler will pick up the core file and write it to 41 self.debugdir, and perform analysis on it to generate a report. The 42 program also outputs some results to syslog. 43 44 If multiple tests are running, an attempt to verify if we still have 45 the old PID on the system process table to determine whether it is a 46 parent of the current test execution. If we can't determine it, the 47 core file and the report file will be copied to all test debug dirs. 48 """ 49 self.crash_handling_enabled = False 50 51 self.pattern_file = '/proc/sys/kernel/core_pattern' 52 try: 53 # Enable core dumps 54 resource.setrlimit(resource.RLIMIT_CORE, (-1, -1)) 55 # Trying to backup core pattern and register our script 56 self.core_pattern_backup = open(self.pattern_file, 'r').read() 57 pattern_file = open(self.pattern_file, 'w') 58 tools_dir = os.path.join(self.autodir, 'tools') 59 crash_handler_path = os.path.join(tools_dir, 'crash_handler.py') 60 pattern_file.write('|' + crash_handler_path + ' %p %t %u %s %h %e') 61 # Writing the files that the crash handler is going to use 62 self.debugdir_tmp_file = ('/tmp/autotest_results_dir.%s' % 63 os.getpid()) 64 utils.open_write_close(self.debugdir_tmp_file, self.debugdir + "\n") 65 except Exception as e: 66 logging.warning('Crash handling disabled: %s', e) 67 else: 68 self.crash_handling_enabled = True 69 try: 70 os_dep.command('gdb') 71 except ValueError: 72 logging.warning('Could not find GDB installed. Crash handling ' 73 'will operate with limited functionality') 74 logging.debug('Crash handling enabled') 75 76 77 def crash_handler_report(self): 78 """ 79 If core dumps are found on the debugdir after the execution of the 80 test, let the user know. 81 """ 82 if self.crash_handling_enabled: 83 # Remove the debugdir info file 84 os.unlink(self.debugdir_tmp_file) 85 # Restore the core pattern backup 86 try: 87 utils.open_write_close(self.pattern_file, 88 self.core_pattern_backup) 89 except EnvironmentError: 90 pass 91 # Let the user know if core dumps were generated during the test 92 core_dirs = glob.glob('%s/crash.*' % self.debugdir) 93 if core_dirs: 94 logging.warning('Programs crashed during test execution') 95 for dir in core_dirs: 96 logging.warning('Please verify %s for more info', dir) 97 98 99def runtest(job, url, tag, args, dargs): 100 # Leave some autotest bread crumbs in the system logs. 101 utils.system('logger "autotest runtest %s"' % url, ignore_status=True) 102 common_test.runtest(job, url, tag, args, dargs, locals(), globals(), 103 job.sysinfo.log_before_each_test, 104 job.sysinfo.log_after_each_test, 105 job.sysinfo.log_before_each_iteration, 106 job.sysinfo.log_after_each_iteration) 107