Bug 481732 - Check for crash minidumps in unit tests and dump them, if the MINIDUMP_STACKWALK path is set in the environment, r=ted

This commit is contained in:
Benjamin Smedberg 2009-03-10 13:36:14 -04:00
parent eda03c34c6
commit 3305b96ed7
5 changed files with 50 additions and 9 deletions

View File

@ -190,18 +190,19 @@ SYMBOL_INDEX_NAME = \
buildsymbols:
ifdef MOZ_CRASHREPORTER
echo building symbol store
mkdir -p $(DIST)/crashreporter-symbols/$(BUILDID)
$(RM) -rf $(DIST)/crashreporter-symbols
$(NSINSTALL) -D $(DIST)/crashreporter-symbols
$(PYTHON) $(topsrcdir)/toolkit/crashreporter/tools/symbolstore.py \
$(MAKE_SYM_STORE_ARGS) \
$(foreach dir,$(SYM_STORE_SOURCE_DIRS),-s $(dir)) \
$(DUMP_SYMS_BIN) \
$(DIST)/crashreporter-symbols/$(BUILDID) \
$(DIST)/crashreporter-symbols \
$(MAKE_SYM_STORE_PATH) > \
$(DIST)/crashreporter-symbols/$(BUILDID)/$(SYMBOL_INDEX_NAME)
$(DIST)/crashreporter-symbols/$(SYMBOL_INDEX_NAME)
echo packing symbols
mkdir -p $(topsrcdir)/../$(BUILDID)
cd $(DIST)/crashreporter-symbols/$(BUILDID) && \
zip -r9D ../../$(SYMBOL_ARCHIVE_BASENAME).zip .
cd $(DIST)/crashreporter-symbols && \
zip -r9D ../$(SYMBOL_ARCHIVE_BASENAME).zip .
endif # MOZ_CRASHREPORTER
uploadsymbols:

View File

@ -22,6 +22,7 @@ endif
endif
_PROFILE_DIR = $(TARGET_DEPTH)/_profile/pgo
_SYMBOLS_PATH = $(TARGET_DIST)/crashreporter-symbols
ifneq (,$(filter /%,$(topsrcdir)))
# $(topsrcdir) is already an absolute pathname.
@ -38,6 +39,7 @@ AUTOMATION_PPARGS = \
-DBIN_SUFFIX=\"$(BIN_SUFFIX)\" \
-DPROFILE_DIR=\"$(_PROFILE_DIR)\" \
-DCERTS_SRC_DIR=\"$(_CERTS_SRC_DIR)\" \
-DSYMBOLS_PATH=\"$(_SYMBOLS_PATH)\" \
$(NULL)
ifeq ($(OS_ARCH),Darwin)
@ -68,6 +70,6 @@ else
AUTOMATION_PPARGS += -DIS_DEBUG_BUILD=0
endif
automation.py: $(topsrcdir)/build/automation.py.in
automation.py: $(topsrcdir)/build/automation.py.in $(topsrcdir)/build/automation-build.mk
$(PYTHON) $(topsrcdir)/config/Preprocessor.py \
$(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $< > $@

View File

@ -48,6 +48,7 @@ import signal
import subprocess
import sys
import threading
import glob
"""
Runs the browser from a script, and provides useful utilities
@ -87,6 +88,7 @@ UNIXISH = not IS_WIN32 and not IS_MAC
#expand CERTS_SRC_DIR = __CERTS_SRC_DIR__
#expand IS_TEST_BUILD = __IS_TEST_BUILD__
#expand IS_DEBUG_BUILD = __IS_DEBUG_BUILD__
#expand SYMBOLS_PATH = __SYMBOLS_PATH__
###########
# LOGGING #
@ -401,8 +403,27 @@ def environment(env = None, xrePath = DIST_BIN):
elif IS_WIN32:
env["PATH"] = env["PATH"] + ";" + ldLibraryPath
env['MOZ_CRASHREPORTER_NO_REPORT'] = '1'
env['MOZ_CRASHREPORTER'] = '1'
return env
def checkForCrashes(profileDir, symbolsPath):
stackwalkPath = os.environ.get('MINIDUMP_STACKWALK', None)
foundCrash = False
dumps = glob.glob(os.path.join(profileDir, 'minidumps', '*.dmp'))
for d in dumps:
log.info("TEST-UNEXPECTED-FAIL | (automation.py) | Browser crashed (minidump found)")
if symbolsPath and stackwalkPath:
nullfd = open(os.devnull, 'w')
# eat minidump_stackwalk errors
subprocess.call([stackwalkPath, d, symbolsPath], stderr=nullfd)
nullfd.close()
os.remove(d)
foundCrash = True
return foundCrash
###############
# RUN THE APP #
###############
@ -480,7 +501,10 @@ def processLeakLog(leakLogFile, leakThreshold):
log.info("TEST-UNEXPECTED-FAIL | runtests-leaks | missing output line for total leaks!")
leaks.close()
def runApp(testURL, env, app, profileDir, extraArgs, runSSLTunnel = False, utilityPath = DIST_BIN, xrePath = DIST_BIN, certPath = CERTS_SRC_DIR, debuggerInfo = None):
def runApp(testURL, env, app, profileDir, extraArgs,
runSSLTunnel = False, utilityPath = DIST_BIN,
xrePath = DIST_BIN, certPath = CERTS_SRC_DIR,
debuggerInfo = None, symbolsPath = SYMBOLS_PATH):
"Run the app, log the duration it took to execute, return the status code."
if IS_TEST_BUILD and runSSLTunnel:
@ -548,6 +572,9 @@ def runApp(testURL, env, app, profileDir, extraArgs, runSSLTunnel = False, utili
log.info("TEST-UNEXPECTED-FAIL | (automation.py) | Exited with code %d during test run", status)
log.info("INFO | (automation.py) | Application ran for: %s", str(datetime.now() - startTime))
if checkForCrashes(profileDir, symbolsPath):
status = -1
if IS_TEST_BUILD and runSSLTunnel:
ssltunnelProcess.kill()

View File

@ -84,6 +84,10 @@ def main():
action = "append", dest = "extraProfileFiles",
default = [],
help = "copy specified files/dirs to testing profile")
parser.add_option("--symbols-path",
action = "store", type = "string", dest = "symbolsPath",
default = automation.SYMBOLS_PATH,
help = "absolute path to directory containing breakpad symbols")
options, args = parser.parse_args()
if len(args) != 1:
@ -136,7 +140,8 @@ Are you executing $objdir/_tests/reftest/runreftest.py?""" \
# and then exit the app
log.info("REFTEST INFO | runreftest.py | Performing extension manager registration: start.\n")
status = automation.runApp(None, browserEnv, options.app, profileDir,
extraArgs = ["-silent"])
extraArgs = ["-silent"],
symbolsPath=options.symbolsPath)
# We don't care to call |processLeakLog()| for this step.
log.info("\nREFTEST INFO | runreftest.py | Performing extension manager registration: end.")

View File

@ -136,6 +136,11 @@ class MochitestOptions(optparse.OptionParser):
help = "absolute path to directory containing utility programs (xpcshell, ssltunnel, certutil)")
defaults["utilityPath"] = automation.DIST_BIN
self.add_option("--symbols-path",
action = "store", type = "string", dest = "symbolsPath",
help = "absolute path to directory containing breakpad symbols")
defaults["symbolsPath"] = automation.SYMBOLS_PATH
self.add_option("--certificate-path",
action = "store", type = "string", dest = "certPath",
help = "absolute path to directory containing certificate store to use testing profile")
@ -472,7 +477,8 @@ Are you executing $objdir/_tests/testing/mochitest/runtests.py?"""
utilityPath = options.utilityPath,
xrePath = options.xrePath,
certPath=options.certPath,
debuggerInfo=debuggerInfo)
debuggerInfo=debuggerInfo,
symbolsPath=options.symbolsPath)
# Server's no longer needed, and perhaps more importantly, anything it might
# spew to console shouldn't disrupt the leak information table we print next.