"""
Tests basic UndefinedBehaviorSanitizer support (detecting an alignment error).
"""

import os
import lldb
from lldbsuite.test.lldbtest import *
from lldbsuite.test.decorators import *
import lldbsuite.test.lldbutil as lldbutil
import json


class UbsanBasicTestCase(TestBase):
    @skipUnlessUndefinedBehaviorSanitizer
    @no_debug_info_test
    def test(self):
        self.build()
        self.ubsan_tests()

    def setUp(self):
        # Call super's setUp().
        TestBase.setUp(self)
        self.line_align = line_number("main.c", "// align line")

    def ubsan_tests(self):
        # Load the test
        exe = self.getBuildArtifact("a.out")
        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)
        self.registerSanitizerLibrariesWithTarget(target)

        self.runCmd("run")

        process = self.dbg.GetSelectedTarget().process
        thread = process.GetSelectedThread()
        frame = thread.GetSelectedFrame()

        # the stop reason of the thread should be breakpoint.
        self.expect(
            "thread list",
            "A ubsan issue should be detected",
            substrs=["stopped", "stop reason ="],
        )

        stop_reason = thread.GetStopReason()
        self.assertStopReason(stop_reason, lldb.eStopReasonInstrumentation)

        # test that the UBSan dylib is present
        self.expect(
            "image lookup -n __ubsan_on_report",
            "__ubsan_on_report should be present",
            substrs=["1 match found"],
        )

        # FIXME: Check on non macOS platform we land don't
        # stop on __ubsan_on_report instead we stop on main.
        if self.platformIsDarwin():
            # We should not be stopped in the sanitizer library.
            self.assertIn("main", frame.GetFunctionName())

        # The stopped thread backtrace should contain either 'align line'
        found = False
        for i in range(thread.GetNumFrames()):
            frame = thread.GetFrameAtIndex(i)
            if frame.GetLineEntry().GetFileSpec().GetFilename() == "main.c":
                if frame.GetLineEntry().GetLine() == self.line_align:
                    found = True
        self.assertTrue(found)

        backtraces = thread.GetStopReasonExtendedBacktraces(
            lldb.eInstrumentationRuntimeTypeUndefinedBehaviorSanitizer
        )
        self.assertEqual(backtraces.GetSize(), 1)

        self.expect(
            "thread info -s",
            "The extended stop info should contain the UBSan provided fields",
            substrs=[
                "col",
                "description",
                "filename",
                "instrumentation_class",
                "line",
                "memory_address",
            ],
        )

        output_lines = self.res.GetOutput().split("\n")
        json_line = "\n".join(output_lines[2:])
        data = json.loads(json_line)

        self.assertEqual(data["instrumentation_class"], "UndefinedBehaviorSanitizer")
        self.assertEqual(data["description"], "misaligned-pointer-use")
        self.assertEqual(os.path.basename(data["filename"]), "main.c")
        self.assertEqual(data["line"], self.line_align)

        for count in range(0, 8):
            process.Continue()
            stop_reason = thread.GetStopReason()
            self.assertEqual(
                stop_reason,
                lldb.eStopReasonInstrumentation,
                "Round {0} wasn't instrumentation".format(count),
            )
