Bug 1355834 - Report LLVM symbolizer OOMs as errors. r=ahal draft
authorAndrew McCreight <continuation@gmail.com>
Wed, 12 Apr 2017 11:01:24 -0700
changeset 561555 5b47c69fc667fb06131cf0fe5b4be3a5b7b21392
parent 561554 457669d7b6a0de3c5e4c582c27ef71166b1bd4f7
child 562177 87b5ead978b02fc43ae73f8b1620094f2994acc4
push id53776
push userbmo:continuation@gmail.com
push dateWed, 12 Apr 2017 21:06:54 +0000
reviewersahal
bugs1355834
milestone55.0a1
Bug 1355834 - Report LLVM symbolizer OOMs as errors. r=ahal This will make it easier to correctly star these failures, which otherwise simply show up as a false positive leak. MozReview-Commit-ID: 5P6AMRyYmtI
testing/mochitest/leaks.py
--- a/testing/mochitest/leaks.py
+++ b/testing/mochitest/leaks.py
@@ -162,16 +162,17 @@ class LSANLeaks(object):
     Parses the log when running an LSAN build, looking for interesting stack frames
     in allocation stacks, and prints out reports.
     """
 
     def __init__(self, logger):
         self.logger = logger
         self.inReport = False
         self.fatalError = False
+        self.symbolizerError = False
         self.foundFrames = set([])
         self.recordMoreFrames = None
         self.currStack = None
         self.maxNumRecordedFrames = 4
 
         # Don't various allocation-related stack frames, as they do not help much to
         # distinguish different leaks.
         unescapedSkipList = [
@@ -183,29 +184,35 @@ class LSANLeaks(object):
         ]
         self.skipListRegExp = re.compile(
             "^" + "|".join([re.escape(f) for f in unescapedSkipList]) + "$")
 
         self.startRegExp = re.compile(
             "==\d+==ERROR: LeakSanitizer: detected memory leaks")
         self.fatalErrorRegExp = re.compile(
             "==\d+==LeakSanitizer has encountered a fatal error.")
+        self.symbolizerOomRegExp = re.compile(
+            "LLVMSymbolizer: error reading file: Cannot allocate memory")
         self.stackFrameRegExp = re.compile("    #\d+ 0x[0-9a-f]+ in ([^(</]+)")
         self.sysLibStackFrameRegExp = re.compile(
             "    #\d+ 0x[0-9a-f]+ \(([^+]+)\+0x[0-9a-f]+\)")
 
     def log(self, line):
         if re.match(self.startRegExp, line):
             self.inReport = True
             return
 
         if re.match(self.fatalErrorRegExp, line):
             self.fatalError = True
             return
 
+        if re.match(self.symbolizerOomRegExp, line):
+            self.symbolizerError = True
+            return
+
         if not self.inReport:
             return
 
         if line.startswith("Direct leak") or line.startswith("Indirect leak"):
             self._finishStack()
             self.recordMoreFrames = True
             self.currStack = []
             return
@@ -235,16 +242,22 @@ class LSANLeaks(object):
         # If we don't match either of these, just ignore the frame.
         # We'll end up with "unknown stack" if everything is ignored.
 
     def process(self):
         if self.fatalError:
             self.logger.error("TEST-UNEXPECTED-FAIL | LeakSanitizer | LeakSanitizer "
                               "has encountered a fatal error.")
 
+        if self.symbolizerError:
+            self.logger.error("TEST-UNEXPECTED-FAIL | LeakSanitizer | LLVMSymbolizer "
+                              "was unable to allocate memory.")
+            self.logger.info("TEST-INFO | LeakSanitizer | This will cause leaks that "
+                             "should be ignored to instead be reported as an error")
+
         if self.foundFrames:
             self.logger.info("TEST-INFO | LeakSanitizer | To show the "
                              "addresses of leaked objects add report_objects=1 to LSAN_OPTIONS")
             self.logger.info("TEST-INFO | LeakSanitizer | This can be done "
                              "in testing/mozbase/mozrunner/mozrunner/utils.py")
 
         for f in self.foundFrames:
             self.logger.error(