# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. import re class LSANLeaks(object): """ Parses the log when running an LSAN build, looking for interesting stack frames in allocation stacks """ def __init__( self, logger, scope=None, allowed=None, maxNumRecordedFrames=None, allowAll=False, ): self.logger = logger self.inReport = False self.fatalError = False self.symbolizerError = False self.foundFrames = set() self.recordMoreFrames = None self.currStack = None self.maxNumRecordedFrames = maxNumRecordedFrames if maxNumRecordedFrames else 4 self.summaryData = None self.scope = scope self.allowedMatch = None self.allowAll = allowAll self.sawError = False # Don't various allocation-related stack frames, as they do not help much to # distinguish different leaks. unescapedSkipList = [ "malloc", "js_malloc", "malloc_", "__interceptor_malloc", "moz_xmalloc", "calloc", "js_calloc", "calloc_", "__interceptor_calloc", "moz_xcalloc", "realloc", "js_realloc", "realloc_", "__interceptor_realloc", "moz_xrealloc", "new", "js::MallocProvider", ] self.skipListRegExp = re.compile( "^" + "|".join([re.escape(f) for f in unescapedSkipList]) + "$" ) self.startRegExp = re.compile( r"==\d+==ERROR: LeakSanitizer: detected memory leaks" ) self.fatalErrorRegExp = re.compile( r"==\d+==LeakSanitizer has encountered a fatal error." ) self.symbolizerOomRegExp = re.compile( "LLVMSymbolizer: error reading file: Cannot allocate memory" ) self.stackFrameRegExp = re.compile(r" #\d+ 0x[0-9a-f]+ in ([^(= self.maxNumRecordedFrames: self.recordMoreFrames = False def _cleanFrame(self, frame): # Rust frames aren't properly demangled and in particular can contain # some trailing junk of the form ::h[a-f0-9]{16} that changes with # compiler versions; see bug 1507350. return self.rustRegexp.sub("", frame)