зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset 1c19d2a03d90 (bug 827446) for packaging bustage on a CLOSED TREE.
This commit is contained in:
Родитель
1c0574fd33
Коммит
35ddb95cc4
|
@ -91,6 +91,7 @@ TARGET_DEPTH = ..
|
|||
include $(srcdir)/automation-build.mk
|
||||
|
||||
_LEAKTEST_DIR = $(DEPTH)/_leaktest
|
||||
GARBAGE_DIRS += $(_LEAKTEST_DIR)
|
||||
|
||||
_LEAKTEST_FILES = \
|
||||
automation.py \
|
||||
|
|
|
@ -24,24 +24,6 @@ SCRIPT_DIR = os.path.abspath(os.path.realpath(os.path.dirname(sys.argv[0])))
|
|||
sys.path.insert(0, SCRIPT_DIR)
|
||||
import automationutils
|
||||
|
||||
# --------------------------------------------------------------
|
||||
# TODO: this is a hack for mozbase without virtualenv, remove with bug 849900
|
||||
#
|
||||
here = os.path.dirname(__file__)
|
||||
mozbase = os.path.realpath(os.path.join(os.path.dirname(here), 'mozbase'))
|
||||
|
||||
try:
|
||||
import mozcrash
|
||||
except:
|
||||
deps = ['mozcrash',
|
||||
'mozlog']
|
||||
for dep in deps:
|
||||
module = os.path.join(mozbase, dep)
|
||||
if module not in sys.path:
|
||||
sys.path.append(module)
|
||||
import mozcrash
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
_DEFAULT_WEB_SERVER = "127.0.0.1"
|
||||
_DEFAULT_HTTP_PORT = 8888
|
||||
_DEFAULT_SSL_PORT = 4443
|
||||
|
@ -1149,7 +1131,7 @@ user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless t
|
|||
return foundZombie
|
||||
|
||||
def checkForCrashes(self, profileDir, symbolsPath):
|
||||
return mozcrash.check_for_crashes(os.path.join(profileDir, "minidumps"), symbolsPath, test_name=self.lastTestSeen)
|
||||
return automationutils.checkForCrashes(os.path.join(profileDir, "minidumps"), symbolsPath, self.lastTestSeen)
|
||||
|
||||
def runApp(self, testURL, env, app, profileDir, extraArgs,
|
||||
runSSLTunnel = False, utilityPath = None,
|
||||
|
|
|
@ -11,6 +11,7 @@ from urlparse import urlparse
|
|||
__all__ = [
|
||||
"ZipFileReader",
|
||||
"addCommonOptions",
|
||||
"checkForCrashes",
|
||||
"dumpLeakLog",
|
||||
"isURL",
|
||||
"processLeakLog",
|
||||
|
@ -131,6 +132,95 @@ def addCommonOptions(parser, defaults={}):
|
|||
help = "prevents the test harness from redirecting "
|
||||
"stdout and stderr for interactive debuggers")
|
||||
|
||||
def checkForCrashes(dumpDir, symbolsPath, testName=None):
|
||||
stackwalkPath = os.environ.get('MINIDUMP_STACKWALK', None)
|
||||
# try to get the caller's filename if no test name is given
|
||||
if testName is None:
|
||||
try:
|
||||
testName = os.path.basename(sys._getframe(1).f_code.co_filename)
|
||||
except:
|
||||
testName = "unknown"
|
||||
|
||||
# Check preconditions
|
||||
dumps = glob.glob(os.path.join(dumpDir, '*.dmp'))
|
||||
if len(dumps) == 0:
|
||||
return False
|
||||
|
||||
try:
|
||||
removeSymbolsPath = False
|
||||
|
||||
# If our symbols are at a remote URL, download them now
|
||||
if symbolsPath and isURL(symbolsPath):
|
||||
print "Downloading symbols from: " + symbolsPath
|
||||
removeSymbolsPath = True
|
||||
# Get the symbols and write them to a temporary zipfile
|
||||
data = urllib2.urlopen(symbolsPath)
|
||||
symbolsFile = tempfile.TemporaryFile()
|
||||
symbolsFile.write(data.read())
|
||||
# extract symbols to a temporary directory (which we'll delete after
|
||||
# processing all crashes)
|
||||
symbolsPath = tempfile.mkdtemp()
|
||||
zfile = ZipFileReader(symbolsFile)
|
||||
zfile.extractall(symbolsPath)
|
||||
|
||||
for d in dumps:
|
||||
stackwalkOutput = []
|
||||
stackwalkOutput.append("Crash dump filename: " + d)
|
||||
topFrame = None
|
||||
if symbolsPath and stackwalkPath and os.path.exists(stackwalkPath):
|
||||
# run minidump stackwalk
|
||||
p = subprocess.Popen([stackwalkPath, d, symbolsPath],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
(out, err) = p.communicate()
|
||||
if len(out) > 3:
|
||||
# minidump_stackwalk is chatty, so ignore stderr when it succeeds.
|
||||
stackwalkOutput.append(out)
|
||||
# The top frame of the crash is always the line after "Thread N (crashed)"
|
||||
# Examples:
|
||||
# 0 libc.so + 0xa888
|
||||
# 0 libnss3.so!nssCertificate_Destroy [certificate.c : 102 + 0x0]
|
||||
# 0 mozjs.dll!js::GlobalObject::getDebuggers() [GlobalObject.cpp:89df18f9b6da : 580 + 0x0]
|
||||
# 0 libxul.so!void js::gc::MarkInternal<JSObject>(JSTracer*, JSObject**) [Marking.cpp : 92 + 0x28]
|
||||
lines = out.splitlines()
|
||||
for i, line in enumerate(lines):
|
||||
if "(crashed)" in line:
|
||||
match = re.search(r"^ 0 (?:.*!)?(?:void )?([^\[]+)", lines[i+1])
|
||||
if match:
|
||||
topFrame = "@ %s" % match.group(1).strip()
|
||||
break
|
||||
else:
|
||||
stackwalkOutput.append("stderr from minidump_stackwalk:")
|
||||
stackwalkOutput.append(err)
|
||||
if p.returncode != 0:
|
||||
stackwalkOutput.append("minidump_stackwalk exited with return code %d" % p.returncode)
|
||||
else:
|
||||
if not symbolsPath:
|
||||
stackwalkOutput.append("No symbols path given, can't process dump.")
|
||||
if not stackwalkPath:
|
||||
stackwalkOutput.append("MINIDUMP_STACKWALK not set, can't process dump.")
|
||||
elif stackwalkPath and not os.path.exists(stackwalkPath):
|
||||
stackwalkOutput.append("MINIDUMP_STACKWALK binary not found: %s" % stackwalkPath)
|
||||
if not topFrame:
|
||||
topFrame = "Unknown top frame"
|
||||
log.info("PROCESS-CRASH | %s | application crashed [%s]", testName, topFrame)
|
||||
print '\n'.join(stackwalkOutput)
|
||||
dumpSavePath = os.environ.get('MINIDUMP_SAVE_PATH', None)
|
||||
if dumpSavePath:
|
||||
shutil.move(d, dumpSavePath)
|
||||
print "Saved dump as %s" % os.path.join(dumpSavePath,
|
||||
os.path.basename(d))
|
||||
else:
|
||||
os.remove(d)
|
||||
extra = os.path.splitext(d)[0] + ".extra"
|
||||
if os.path.exists(extra):
|
||||
os.remove(extra)
|
||||
finally:
|
||||
if removeSymbolsPath:
|
||||
shutil.rmtree(symbolsPath)
|
||||
|
||||
return True
|
||||
|
||||
def getFullPath(directory, path):
|
||||
"Get an absolute path relative to 'directory'."
|
||||
return os.path.normpath(os.path.join(directory, os.path.expanduser(path)))
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
import time
|
||||
import re
|
||||
import os
|
||||
import automationutils
|
||||
import tempfile
|
||||
import shutil
|
||||
import subprocess
|
||||
|
@ -132,8 +133,8 @@ class RemoteAutomation(Automation):
|
|||
# Whilst no crash was found, the run should still display as a failure
|
||||
return True
|
||||
self._devicemanager.getDirectory(remoteCrashDir, dumpDir)
|
||||
crashed = Automation.checkForCrashes(self, dumpDir, symbolsPath)
|
||||
|
||||
crashed = automationutils.checkForCrashes(dumpDir, symbolsPath,
|
||||
self.lastTestSeen)
|
||||
finally:
|
||||
try:
|
||||
shutil.rmtree(dumpDir)
|
||||
|
|
|
@ -18,7 +18,6 @@ include $(topsrcdir)/config/rules.mk
|
|||
# Packages later in the list can depend only on packages earlier in the list.
|
||||
MOZBASE_PACKAGES = \
|
||||
manifestdestiny \
|
||||
mozcrash \
|
||||
mozfile \
|
||||
mozhttpd \
|
||||
mozinfo \
|
||||
|
|
|
@ -18,24 +18,6 @@ import time
|
|||
|
||||
from automationutils import *
|
||||
|
||||
# --------------------------------------------------------------
|
||||
# TODO: this is a hack for mozbase without virtualenv, remove with bug 849900
|
||||
#
|
||||
here = os.path.dirname(__file__)
|
||||
mozbase = os.path.realpath(os.path.join(os.path.dirname(here), 'mozbase'))
|
||||
|
||||
try:
|
||||
import mozcrash
|
||||
except:
|
||||
deps = ['mozcrash',
|
||||
'mozlog']
|
||||
for dep in deps:
|
||||
module = os.path.join(mozbase, dep)
|
||||
if module not in sys.path:
|
||||
sys.path.append(module)
|
||||
import mozcrash
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
#TODO: replace this with json.loads when Python 2.6 is required.
|
||||
def parse_json(j):
|
||||
"""
|
||||
|
@ -912,7 +894,7 @@ class XPCShellTests(object):
|
|||
self.todoCount += 1
|
||||
xunitResult["todo"] = True
|
||||
|
||||
if mozcrash.check_for_crashes(testdir, self.symbolsPath, test_name=name):
|
||||
if checkForCrashes(testdir, self.symbolsPath, testName=name):
|
||||
message = "PROCESS-CRASH | %s | application crashed" % name
|
||||
self.failCount += 1
|
||||
xunitResult["passed"] = False
|
||||
|
|
Загрузка…
Ссылка в новой задаче