Commit e5511cf2 authored by Jan Kiene's avatar Jan Kiene
Browse files

add msan (untested yet) + sorting

parent c1d0be92
Loading
Loading
Loading
Loading
+56 −17
Original line number Diff line number Diff line
@@ -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": "",
@@ -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
@@ -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)