Loading scripts/parse_usan_errors_from_xml_report.py +56 −17 Original line number Diff line number Diff line Loading @@ -6,30 +6,57 @@ from typing import List import re class UsanError: def __init__(self, err: str, commandlines: dict): self.err = err class SanitizerError: def __init__(self, traceback: str, commandlines: dict) -> None: self.traceback = traceback self.commandlines = commandlines err_lines = err.split("\n") self.err_location = err_lines[0].strip().split(": runtime error:")[0] self.location = "" self.type = "" def __hash__(self): return hash(self.err_location) return hash(self.location) def __eq__(self, other): return self.err_location == other.err_location return self.location == other.location def __repr__(self): return f"<USAN err: {self.err_location}>" return f"<{self.__class__} at {self.location}>" def __lt__(self, other): return self.location < other.location def to_dict(self) -> dict: return { "location": self.err_location, "traceback": "\n".join(self.err.split("\n")[1:]), "location": self.location, "type": self.type, "traceback": self.traceback, **self.commandlines, } class UsanError(SanitizerError): def __init__(self, traceback: str, commandlines: dict): super().__init__(traceback, commandlines) err_lines = traceback.split("\n") self.location = err_lines[0].strip().split(": runtime error:")[0] self.type = "undefined-behaviour" class MsanError(SanitizerError): def __init__(self, traceback: str, commandlines: dict) -> None: super().__init__(traceback, commandlines) err_lines = traceback.split("\n") last_line = err_lines[-1].strip() assert last_line.startswith("SUMMARY: MemorySanitizer: ") m = re.search( r"^SUMMARY: MemorySanitizer: ([a-z-]*) .*\/(.*\.[ch]:\d+:\d+) in .+$", traceback, ) assert m is not None self.type, self.location = m.groups() def parse_commandlines_from_sysout(sysout: str) -> dict: commandlines = { "IVAS_cod": "", Loading Loading @@ -57,23 +84,34 @@ def parse_errors_from_sysout(sysout: str) -> List[UsanError]: OUT = 0 IN = 1 pattern = re.compile(r"(lib_.+|apps)\/(.*\.[ch]):(\d+):(\d+): runtime error:") pattern_usan = re.compile(r"(lib_.+|apps)\/(.*\.[ch]):(\d+):(\d+): runtime error:") pattern_msan = re.compile(r" MemorySanitizer: ") state = ParserState.OUT accu = [] for line in sysout.splitlines(): m = re.match(pattern, line.strip()) if m is not None: err_cls = None for l in sysout.splitlines(): line = l.strip() m_usan = re.match(pattern_usan, line) m_msan = re.match(pattern_msan, line) assert m_msan != m_usan or (m_usan is None and m_msan is None) match_found = m_usan is not None or m_msan is not None if match_found: assert state == ParserState.OUT state = ParserState.IN accu = [] err_cls = UsanError if m_usan is not None else MsanError if state == ParserState.IN: accu.append(line.strip()) accu.append(line) if line.strip().startswith("SUMMARY:"): assert state == ParserState.IN errors.append(UsanError("\n".join(accu), commandlines)) errors.append(err_cls("\n".join(accu), commandlines)) state = ParserState.OUT return errors Loading @@ -88,7 +126,8 @@ def main(args): for sysout in tc.findall("system-out"): errors.extend(parse_errors_from_sysout(sysout.text)) unique_errors = list(set(errors)) unique_errors = list(sorted(set(errors))) print(f"Found {len(unique_errors)} unique errors") df = pd.DataFrame([e.to_dict() for e in unique_errors]) df.to_csv(args.outfile, index=False) Loading Loading
scripts/parse_usan_errors_from_xml_report.py +56 −17 Original line number Diff line number Diff line Loading @@ -6,30 +6,57 @@ from typing import List import re class UsanError: def __init__(self, err: str, commandlines: dict): self.err = err class SanitizerError: def __init__(self, traceback: str, commandlines: dict) -> None: self.traceback = traceback self.commandlines = commandlines err_lines = err.split("\n") self.err_location = err_lines[0].strip().split(": runtime error:")[0] self.location = "" self.type = "" def __hash__(self): return hash(self.err_location) return hash(self.location) def __eq__(self, other): return self.err_location == other.err_location return self.location == other.location def __repr__(self): return f"<USAN err: {self.err_location}>" return f"<{self.__class__} at {self.location}>" def __lt__(self, other): return self.location < other.location def to_dict(self) -> dict: return { "location": self.err_location, "traceback": "\n".join(self.err.split("\n")[1:]), "location": self.location, "type": self.type, "traceback": self.traceback, **self.commandlines, } class UsanError(SanitizerError): def __init__(self, traceback: str, commandlines: dict): super().__init__(traceback, commandlines) err_lines = traceback.split("\n") self.location = err_lines[0].strip().split(": runtime error:")[0] self.type = "undefined-behaviour" class MsanError(SanitizerError): def __init__(self, traceback: str, commandlines: dict) -> None: super().__init__(traceback, commandlines) err_lines = traceback.split("\n") last_line = err_lines[-1].strip() assert last_line.startswith("SUMMARY: MemorySanitizer: ") m = re.search( r"^SUMMARY: MemorySanitizer: ([a-z-]*) .*\/(.*\.[ch]:\d+:\d+) in .+$", traceback, ) assert m is not None self.type, self.location = m.groups() def parse_commandlines_from_sysout(sysout: str) -> dict: commandlines = { "IVAS_cod": "", Loading Loading @@ -57,23 +84,34 @@ def parse_errors_from_sysout(sysout: str) -> List[UsanError]: OUT = 0 IN = 1 pattern = re.compile(r"(lib_.+|apps)\/(.*\.[ch]):(\d+):(\d+): runtime error:") pattern_usan = re.compile(r"(lib_.+|apps)\/(.*\.[ch]):(\d+):(\d+): runtime error:") pattern_msan = re.compile(r" MemorySanitizer: ") state = ParserState.OUT accu = [] for line in sysout.splitlines(): m = re.match(pattern, line.strip()) if m is not None: err_cls = None for l in sysout.splitlines(): line = l.strip() m_usan = re.match(pattern_usan, line) m_msan = re.match(pattern_msan, line) assert m_msan != m_usan or (m_usan is None and m_msan is None) match_found = m_usan is not None or m_msan is not None if match_found: assert state == ParserState.OUT state = ParserState.IN accu = [] err_cls = UsanError if m_usan is not None else MsanError if state == ParserState.IN: accu.append(line.strip()) accu.append(line) if line.strip().startswith("SUMMARY:"): assert state == ParserState.IN errors.append(UsanError("\n".join(accu), commandlines)) errors.append(err_cls("\n".join(accu), commandlines)) state = ParserState.OUT return errors Loading @@ -88,7 +126,8 @@ def main(args): for sysout in tc.findall("system-out"): errors.extend(parse_errors_from_sysout(sysout.text)) unique_errors = list(set(errors)) unique_errors = list(sorted(set(errors))) print(f"Found {len(unique_errors)} unique errors") df = pd.DataFrame([e.to_dict() for e in unique_errors]) df.to_csv(args.outfile, index=False) Loading