Bug 1625888 - In Talos, check_for_crashes even when exception raised after browser run; r=perftest-reviewers,AlexandruIonescu

In some cases, a browser crash may subsequently cause an exception in the harness before
check_for_crashes is called, effectively bypassing crash reporting. This patch catches
the exception to ensure that check_for_crashes is called regardless of such exceptions.
It also fixes the check for non-unicode file names and adds more diagnostic logging.

Differential Revision: https://phabricator.services.mozilla.com/D68901

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Geoff Brown 2020-04-03 13:09:05 +00:00
parent 84bf0fdb08
commit d0dc11cfdb
2 changed files with 78 additions and 67 deletions

View File

@ -492,6 +492,7 @@ if mozinfo.isWin:
FILE_ATTRIBUTE_NORMAL = 0x80
INVALID_HANDLE_VALUE = -1
log = get_logger()
file_name = os.path.join(dump_directory,
str(uuid.uuid4()) + ".dmp")
@ -501,7 +502,6 @@ if mozinfo.isWin:
# python process was compiled for a different architecture than
# firefox, so we invoke the minidumpwriter utility program.
log = get_logger()
minidumpwriter = os.path.normpath(os.path.join(utility_path,
"minidumpwriter.exe"))
log.info(u"Using {} to write a dump to {} for [{}]".format(
@ -519,12 +519,16 @@ if mozinfo.isWin:
log.error("minidumpwriter exited with status: %d" % status)
return
log.info(u"Writing a dump to {} for [{}]".format(file_name, pid))
proc_handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
0, pid)
if not proc_handle:
err = kernel32.GetLastError()
log.warning("unable to get handle for pid %d: %d" % (pid, err))
return
if not isinstance(file_name, string_types):
if not isinstance(file_name, text_type):
# Convert to unicode explicitly so our path will be valid as input
# to CreateFileW
file_name = text_type(file_name, sys.getfilesystemencoding())
@ -537,18 +541,23 @@ if mozinfo.isWin:
FILE_ATTRIBUTE_NORMAL,
None)
if file_handle != INVALID_HANDLE_VALUE:
ctypes.windll.dbghelp.MiniDumpWriteDump(proc_handle,
pid,
file_handle,
# Dump type - MiniDumpNormal
0,
# Exception parameter
None,
# User stream parameter
None,
# Callback parameter
None)
if not ctypes.windll.dbghelp.MiniDumpWriteDump(proc_handle,
pid,
file_handle,
# Dump type - MiniDumpNormal
0,
# Exception parameter
None,
# User stream parameter
None,
# Callback parameter
None):
err = kernel32.GetLastError()
log.warning("unable to dump minidump file for pid %d: %d" % (pid, err))
CloseHandle(file_handle)
else:
err = kernel32.GetLastError()
log.warning("unable to create minidump file for pid %d: %d" % (pid, err))
CloseHandle(proc_handle)
def kill_pid(pid):

View File

@ -223,67 +223,69 @@ class TTest(object):
if counter_management:
counter_management.stop()
if test_config['mainthread']:
rawlog = os.path.join(here, 'mainthread_io.log')
if os.path.exists(rawlog):
processedlog = \
os.path.join(here, 'mainthread_io.json')
xre_path = \
os.path.dirname(browser_config['browser_path'])
mtio_py = os.path.join(here, 'mainthreadio.py')
command = ['python', mtio_py, rawlog,
processedlog, xre_path]
mtio = subprocess.Popen(command,
env=os.environ.copy(),
stdout=subprocess.PIPE)
output, stderr = mtio.communicate()
for line in output.split('\n'):
if line.strip() == '':
continue
try:
if test_config['mainthread']:
rawlog = os.path.join(here, 'mainthread_io.log')
if os.path.exists(rawlog):
processedlog = \
os.path.join(here, 'mainthread_io.json')
xre_path = \
os.path.dirname(browser_config['browser_path'])
mtio_py = os.path.join(here, 'mainthreadio.py')
command = ['python', mtio_py, rawlog,
processedlog, xre_path]
mtio = subprocess.Popen(command,
env=os.environ.copy(),
stdout=subprocess.PIPE)
output, stderr = mtio.communicate()
for line in output.split('\n'):
if line.strip() == '':
continue
print(line)
mainthread_error_count += 1
mozfile.remove(rawlog)
print(line)
mainthread_error_count += 1
mozfile.remove(rawlog)
if test_config['cleanup']:
# HACK: add the pid to support xperf where we require
# the pid in post processing
talosconfig.generateTalosConfig(command_args,
browser_config,
test_config,
pid=pcontext.pid)
subprocess.call(
[sys.executable] + test_config['cleanup'].split()
)
if test_config['cleanup']:
# HACK: add the pid to support xperf where we require
# the pid in post processing
talosconfig.generateTalosConfig(command_args,
browser_config,
test_config,
pid=pcontext.pid)
subprocess.call(
[sys.executable] + test_config['cleanup'].split()
)
# For startup tests, we launch the browser multiple times
# with the same profile
for fname in ('sessionstore.js', '.parentlock',
'sessionstore.bak'):
mozfile.remove(os.path.join(setup.profile_dir, fname))
# For startup tests, we launch the browser multiple times
# with the same profile
for fname in ('sessionstore.js', '.parentlock',
'sessionstore.bak'):
mozfile.remove(os.path.join(setup.profile_dir, fname))
# check for xperf errors
if os.path.exists(browser_config['error_filename']) or \
mainthread_error_count > 0:
raise TalosRegression(
'Talos has found a regression, if you have questions'
' ask for help in irc on #perf'
)
# check for xperf errors
if os.path.exists(browser_config['error_filename']) or \
mainthread_error_count > 0:
raise TalosRegression(
'Talos has found a regression, if you have questions'
' ask for help in irc on #perf'
)
# add the results from the browser output
if not run_in_debug_mode(browser_config):
test_results.add(
'\n'.join(pcontext.output),
counter_results=(counter_management.results()
if counter_management
else None)
)
# add the results from the browser output
if not run_in_debug_mode(browser_config):
test_results.add(
'\n'.join(pcontext.output),
counter_results=(counter_management.results()
if counter_management
else None)
)
if setup.gecko_profile:
setup.gecko_profile.symbolicate(i)
if setup.gecko_profile:
setup.gecko_profile.symbolicate(i)
self.check_for_crashes(browser_config, minidump_dir,
test_config['name'])
finally:
self.check_for_crashes(browser_config, minidump_dir,
test_config['name'])
# include global (cross-cycle) counters
test_results.all_counter_results.extend(