xref: /llvm-project/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py (revision ceeb08b9e0a51a4d2e0804baeb579fe8a6485885)
101263c6cSJonas Devlieghereimport os
201263c6cSJonas Devlieghereimport time
301263c6cSJonas Devlieghere
401263c6cSJonas Devlieghereimport dap_server
501263c6cSJonas Devliegherefrom lldbsuite.test.lldbtest import *
6a52be0ccSSanthosh Kumar Ellendulafrom lldbsuite.test import lldbplatformutil
7a52be0ccSSanthosh Kumar Ellendulaimport lldbgdbserverutils
801263c6cSJonas Devlieghere
901263c6cSJonas Devlieghere
1001263c6cSJonas Devlieghereclass DAPTestCaseBase(TestBase):
1182c1bfc4SShubham Sandeep Rastogi    # set timeout based on whether ASAN was enabled or not. Increase
1282c1bfc4SShubham Sandeep Rastogi    # timeout by a factor of 10 if ASAN is enabled.
1382c1bfc4SShubham Sandeep Rastogi    timeoutval = 10 * (10 if ('ASAN_OPTIONS' in os.environ) else 1)
1401263c6cSJonas Devlieghere    NO_DEBUG_INFO_TESTCASE = True
1501263c6cSJonas Devlieghere
1601263c6cSJonas Devlieghere    def create_debug_adaptor(self, lldbDAPEnv=None):
1701263c6cSJonas Devlieghere        """Create the Visual Studio Code debug adaptor"""
1801263c6cSJonas Devlieghere        self.assertTrue(
1901263c6cSJonas Devlieghere            is_exe(self.lldbDAPExec), "lldb-dap must exist and be executable"
2001263c6cSJonas Devlieghere        )
2101263c6cSJonas Devlieghere        log_file_path = self.getBuildArtifact("dap.txt")
2201263c6cSJonas Devlieghere        self.dap_server = dap_server.DebugAdaptorServer(
2301263c6cSJonas Devlieghere            executable=self.lldbDAPExec,
2401263c6cSJonas Devlieghere            init_commands=self.setUpCommands(),
2501263c6cSJonas Devlieghere            log_file=log_file_path,
2601263c6cSJonas Devlieghere            env=lldbDAPEnv,
2701263c6cSJonas Devlieghere        )
2801263c6cSJonas Devlieghere
2901263c6cSJonas Devlieghere    def build_and_create_debug_adaptor(self, lldbDAPEnv=None):
3001263c6cSJonas Devlieghere        self.build()
3101263c6cSJonas Devlieghere        self.create_debug_adaptor(lldbDAPEnv)
3201263c6cSJonas Devlieghere
3301263c6cSJonas Devlieghere    def set_source_breakpoints(self, source_path, lines, data=None):
3401263c6cSJonas Devlieghere        """Sets source breakpoints and returns an array of strings containing
3501263c6cSJonas Devlieghere        the breakpoint IDs ("1", "2") for each breakpoint that was set.
3601263c6cSJonas Devlieghere        Parameter data is array of data objects for breakpoints.
3701263c6cSJonas Devlieghere        Each object in data is 1:1 mapping with the entry in lines.
3801263c6cSJonas Devlieghere        It contains optional location/hitCondition/logMessage parameters.
3901263c6cSJonas Devlieghere        """
4001263c6cSJonas Devlieghere        response = self.dap_server.request_setBreakpoints(source_path, lines, data)
4101263c6cSJonas Devlieghere        if response is None:
4201263c6cSJonas Devlieghere            return []
4301263c6cSJonas Devlieghere        breakpoints = response["body"]["breakpoints"]
4401263c6cSJonas Devlieghere        breakpoint_ids = []
4501263c6cSJonas Devlieghere        for breakpoint in breakpoints:
4601263c6cSJonas Devlieghere            breakpoint_ids.append("%i" % (breakpoint["id"]))
4701263c6cSJonas Devlieghere        return breakpoint_ids
4801263c6cSJonas Devlieghere
4901263c6cSJonas Devlieghere    def set_function_breakpoints(self, functions, condition=None, hitCondition=None):
5001263c6cSJonas Devlieghere        """Sets breakpoints by function name given an array of function names
5101263c6cSJonas Devlieghere        and returns an array of strings containing the breakpoint IDs
5201263c6cSJonas Devlieghere        ("1", "2") for each breakpoint that was set.
5301263c6cSJonas Devlieghere        """
5401263c6cSJonas Devlieghere        response = self.dap_server.request_setFunctionBreakpoints(
5501263c6cSJonas Devlieghere            functions, condition=condition, hitCondition=hitCondition
5601263c6cSJonas Devlieghere        )
5701263c6cSJonas Devlieghere        if response is None:
5801263c6cSJonas Devlieghere            return []
5901263c6cSJonas Devlieghere        breakpoints = response["body"]["breakpoints"]
6001263c6cSJonas Devlieghere        breakpoint_ids = []
6101263c6cSJonas Devlieghere        for breakpoint in breakpoints:
6201263c6cSJonas Devlieghere            breakpoint_ids.append("%i" % (breakpoint["id"]))
6301263c6cSJonas Devlieghere        return breakpoint_ids
6401263c6cSJonas Devlieghere
6501263c6cSJonas Devlieghere    def waitUntil(self, condition_callback):
6601263c6cSJonas Devlieghere        for _ in range(20):
6701263c6cSJonas Devlieghere            if condition_callback():
6801263c6cSJonas Devlieghere                return True
6901263c6cSJonas Devlieghere            time.sleep(0.5)
7001263c6cSJonas Devlieghere        return False
7101263c6cSJonas Devlieghere
7201263c6cSJonas Devlieghere    def verify_breakpoint_hit(self, breakpoint_ids):
7301263c6cSJonas Devlieghere        """Wait for the process we are debugging to stop, and verify we hit
7401263c6cSJonas Devlieghere        any breakpoint location in the "breakpoint_ids" array.
7501263c6cSJonas Devlieghere        "breakpoint_ids" should be a list of breakpoint ID strings
7601263c6cSJonas Devlieghere        (["1", "2"]). The return value from self.set_source_breakpoints()
7701263c6cSJonas Devlieghere        or self.set_function_breakpoints() can be passed to this function"""
7801263c6cSJonas Devlieghere        stopped_events = self.dap_server.wait_for_stopped()
7901263c6cSJonas Devlieghere        for stopped_event in stopped_events:
8001263c6cSJonas Devlieghere            if "body" in stopped_event:
8101263c6cSJonas Devlieghere                body = stopped_event["body"]
8201263c6cSJonas Devlieghere                if "reason" not in body:
8301263c6cSJonas Devlieghere                    continue
8489c27d6bSSanthosh Kumar Ellendula                if (
8589c27d6bSSanthosh Kumar Ellendula                    body["reason"] != "breakpoint"
8689c27d6bSSanthosh Kumar Ellendula                    and body["reason"] != "instruction breakpoint"
8789c27d6bSSanthosh Kumar Ellendula                ):
8801263c6cSJonas Devlieghere                    continue
8901263c6cSJonas Devlieghere                if "description" not in body:
9001263c6cSJonas Devlieghere                    continue
9101263c6cSJonas Devlieghere                # Descriptions for breakpoints will be in the form
9201263c6cSJonas Devlieghere                # "breakpoint 1.1", so look for any description that matches
9301263c6cSJonas Devlieghere                # ("breakpoint 1.") in the description field as verification
9401263c6cSJonas Devlieghere                # that one of the breakpoint locations was hit. DAP doesn't
9501263c6cSJonas Devlieghere                # allow breakpoints to have multiple locations, but LLDB does.
9601263c6cSJonas Devlieghere                # So when looking at the description we just want to make sure
9701263c6cSJonas Devlieghere                # the right breakpoint matches and not worry about the actual
9801263c6cSJonas Devlieghere                # location.
9901263c6cSJonas Devlieghere                description = body["description"]
10001263c6cSJonas Devlieghere                for breakpoint_id in breakpoint_ids:
10101263c6cSJonas Devlieghere                    match_desc = "breakpoint %s." % (breakpoint_id)
10201263c6cSJonas Devlieghere                    if match_desc in description:
10301263c6cSJonas Devlieghere                        return
10401263c6cSJonas Devlieghere        self.assertTrue(False, "breakpoint not hit")
10501263c6cSJonas Devlieghere
1065b4100ccSJohn Harrison    def verify_stop_exception_info(self, expected_description, timeout=timeoutval):
10701263c6cSJonas Devlieghere        """Wait for the process we are debugging to stop, and verify the stop
10801263c6cSJonas Devlieghere        reason is 'exception' and that the description matches
10901263c6cSJonas Devlieghere        'expected_description'
11001263c6cSJonas Devlieghere        """
1115b4100ccSJohn Harrison        stopped_events = self.dap_server.wait_for_stopped(timeout=timeout)
11201263c6cSJonas Devlieghere        for stopped_event in stopped_events:
1135b4100ccSJohn Harrison            print("stopped_event", stopped_event)
11401263c6cSJonas Devlieghere            if "body" in stopped_event:
11501263c6cSJonas Devlieghere                body = stopped_event["body"]
11601263c6cSJonas Devlieghere                if "reason" not in body:
11701263c6cSJonas Devlieghere                    continue
11801263c6cSJonas Devlieghere                if body["reason"] != "exception":
11901263c6cSJonas Devlieghere                    continue
12001263c6cSJonas Devlieghere                if "description" not in body:
12101263c6cSJonas Devlieghere                    continue
12201263c6cSJonas Devlieghere                description = body["description"]
12301263c6cSJonas Devlieghere                if expected_description == description:
12401263c6cSJonas Devlieghere                    return True
12501263c6cSJonas Devlieghere        return False
12601263c6cSJonas Devlieghere
12701263c6cSJonas Devlieghere    def verify_commands(self, flavor, output, commands):
12801263c6cSJonas Devlieghere        self.assertTrue(output and len(output) > 0, "expect console output")
12901263c6cSJonas Devlieghere        lines = output.splitlines()
13001263c6cSJonas Devlieghere        prefix = "(lldb) "
13101263c6cSJonas Devlieghere        for cmd in commands:
13201263c6cSJonas Devlieghere            found = False
13301263c6cSJonas Devlieghere            for line in lines:
134ae8facc1SJohn Harrison                if len(cmd) > 0 and (cmd[0] == "!" or cmd[0] == "?"):
135ae8facc1SJohn Harrison                    cmd = cmd[1:]
13601263c6cSJonas Devlieghere                if line.startswith(prefix) and cmd in line:
13701263c6cSJonas Devlieghere                    found = True
13801263c6cSJonas Devlieghere                    break
13901263c6cSJonas Devlieghere            self.assertTrue(
14001263c6cSJonas Devlieghere                found, "verify '%s' found in console output for '%s'" % (cmd, flavor)
14101263c6cSJonas Devlieghere            )
14201263c6cSJonas Devlieghere
14301263c6cSJonas Devlieghere    def get_dict_value(self, d, key_path):
14401263c6cSJonas Devlieghere        """Verify each key in the key_path array is in contained in each
14501263c6cSJonas Devlieghere        dictionary within "d". Assert if any key isn't in the
14601263c6cSJonas Devlieghere        corresponding dictionary. This is handy for grabbing values from VS
14701263c6cSJonas Devlieghere        Code response dictionary like getting
14801263c6cSJonas Devlieghere        response['body']['stackFrames']
14901263c6cSJonas Devlieghere        """
15001263c6cSJonas Devlieghere        value = d
15101263c6cSJonas Devlieghere        for key in key_path:
15201263c6cSJonas Devlieghere            if key in value:
15301263c6cSJonas Devlieghere                value = value[key]
15401263c6cSJonas Devlieghere            else:
15501263c6cSJonas Devlieghere                self.assertTrue(
15601263c6cSJonas Devlieghere                    key in value,
15701263c6cSJonas Devlieghere                    'key "%s" from key_path "%s" not in "%s"' % (key, key_path, d),
15801263c6cSJonas Devlieghere                )
15901263c6cSJonas Devlieghere        return value
16001263c6cSJonas Devlieghere
16101263c6cSJonas Devlieghere    def get_stackFrames_and_totalFramesCount(
16201263c6cSJonas Devlieghere        self, threadId=None, startFrame=None, levels=None, dump=False
16301263c6cSJonas Devlieghere    ):
16401263c6cSJonas Devlieghere        response = self.dap_server.request_stackTrace(
16501263c6cSJonas Devlieghere            threadId=threadId, startFrame=startFrame, levels=levels, dump=dump
16601263c6cSJonas Devlieghere        )
16701263c6cSJonas Devlieghere        if response:
16801263c6cSJonas Devlieghere            stackFrames = self.get_dict_value(response, ["body", "stackFrames"])
16901263c6cSJonas Devlieghere            totalFrames = self.get_dict_value(response, ["body", "totalFrames"])
17001263c6cSJonas Devlieghere            self.assertTrue(
17101263c6cSJonas Devlieghere                totalFrames > 0,
17201263c6cSJonas Devlieghere                "verify totalFrames count is provided by extension that supports "
17301263c6cSJonas Devlieghere                "async frames loading",
17401263c6cSJonas Devlieghere            )
17501263c6cSJonas Devlieghere            return (stackFrames, totalFrames)
17601263c6cSJonas Devlieghere        return (None, 0)
17701263c6cSJonas Devlieghere
17801263c6cSJonas Devlieghere    def get_stackFrames(self, threadId=None, startFrame=None, levels=None, dump=False):
17901263c6cSJonas Devlieghere        (stackFrames, totalFrames) = self.get_stackFrames_and_totalFramesCount(
18001263c6cSJonas Devlieghere            threadId=threadId, startFrame=startFrame, levels=levels, dump=dump
18101263c6cSJonas Devlieghere        )
18201263c6cSJonas Devlieghere        return stackFrames
18301263c6cSJonas Devlieghere
1845b4100ccSJohn Harrison    def get_exceptionInfo(self, threadId=None):
1855b4100ccSJohn Harrison        response = self.dap_server.request_exceptionInfo(threadId=threadId)
1865b4100ccSJohn Harrison        return self.get_dict_value(response, ["body"])
1875b4100ccSJohn Harrison
18801263c6cSJonas Devlieghere    def get_source_and_line(self, threadId=None, frameIndex=0):
18901263c6cSJonas Devlieghere        stackFrames = self.get_stackFrames(
19001263c6cSJonas Devlieghere            threadId=threadId, startFrame=frameIndex, levels=1
19101263c6cSJonas Devlieghere        )
19201263c6cSJonas Devlieghere        if stackFrames is not None:
19301263c6cSJonas Devlieghere            stackFrame = stackFrames[0]
19401263c6cSJonas Devlieghere            ["source", "path"]
19501263c6cSJonas Devlieghere            if "source" in stackFrame:
19601263c6cSJonas Devlieghere                source = stackFrame["source"]
19701263c6cSJonas Devlieghere                if "path" in source:
19801263c6cSJonas Devlieghere                    if "line" in stackFrame:
19901263c6cSJonas Devlieghere                        return (source["path"], stackFrame["line"])
20001263c6cSJonas Devlieghere        return ("", 0)
20101263c6cSJonas Devlieghere
20201263c6cSJonas Devlieghere    def get_stdout(self, timeout=0.0):
20301263c6cSJonas Devlieghere        return self.dap_server.get_output("stdout", timeout=timeout)
20401263c6cSJonas Devlieghere
20501263c6cSJonas Devlieghere    def get_console(self, timeout=0.0):
20601263c6cSJonas Devlieghere        return self.dap_server.get_output("console", timeout=timeout)
20701263c6cSJonas Devlieghere
20811a4d43fSMiro Bucko    def collect_console(self, timeout_secs, pattern=None):
20911a4d43fSMiro Bucko        return self.dap_server.collect_output(
21011a4d43fSMiro Bucko            "console", timeout_secs=timeout_secs, pattern=pattern
21111a4d43fSMiro Bucko        )
21201263c6cSJonas Devlieghere
21330ca06c4SJohn Harrison    def collect_stdout(self, timeout_secs, pattern=None):
21430ca06c4SJohn Harrison        return self.dap_server.collect_output(
21530ca06c4SJohn Harrison            "stdout", timeout_secs=timeout_secs, pattern=pattern
21630ca06c4SJohn Harrison        )
21730ca06c4SJohn Harrison
21801263c6cSJonas Devlieghere    def get_local_as_int(self, name, threadId=None):
21901263c6cSJonas Devlieghere        value = self.dap_server.get_local_variable_value(name, threadId=threadId)
22006effaf4Ssanthoshe447        # 'value' may have the variable value and summary.
22106effaf4Ssanthoshe447        # Extract the variable value since summary can have nonnumeric characters.
22206effaf4Ssanthoshe447        value = value.split(" ")[0]
22301263c6cSJonas Devlieghere        if value.startswith("0x"):
22401263c6cSJonas Devlieghere            return int(value, 16)
22501263c6cSJonas Devlieghere        elif value.startswith("0"):
22601263c6cSJonas Devlieghere            return int(value, 8)
22701263c6cSJonas Devlieghere        else:
22801263c6cSJonas Devlieghere            return int(value)
22901263c6cSJonas Devlieghere
23001263c6cSJonas Devlieghere    def set_local(self, name, value, id=None):
23101263c6cSJonas Devlieghere        """Set a top level local variable only."""
23201263c6cSJonas Devlieghere        return self.dap_server.request_setVariable(1, name, str(value), id=id)
23301263c6cSJonas Devlieghere
23401263c6cSJonas Devlieghere    def set_global(self, name, value, id=None):
23501263c6cSJonas Devlieghere        """Set a top level global variable only."""
23601263c6cSJonas Devlieghere        return self.dap_server.request_setVariable(2, name, str(value), id=id)
23701263c6cSJonas Devlieghere
2386257a98bSAdrian Vogelsgesang    def stepIn(
2396257a98bSAdrian Vogelsgesang        self, threadId=None, targetId=None, waitForStop=True, granularity="statement"
2406257a98bSAdrian Vogelsgesang    ):
241*ceeb08b9SMichael Buch        self.dap_server.request_stepIn(
2426257a98bSAdrian Vogelsgesang            threadId=threadId, targetId=targetId, granularity=granularity
2436257a98bSAdrian Vogelsgesang        )
24401263c6cSJonas Devlieghere        if waitForStop:
24501263c6cSJonas Devlieghere            return self.dap_server.wait_for_stopped()
24601263c6cSJonas Devlieghere        return None
24701263c6cSJonas Devlieghere
2486257a98bSAdrian Vogelsgesang    def stepOver(self, threadId=None, waitForStop=True, granularity="statement"):
2496257a98bSAdrian Vogelsgesang        self.dap_server.request_next(threadId=threadId, granularity=granularity)
25001263c6cSJonas Devlieghere        if waitForStop:
25101263c6cSJonas Devlieghere            return self.dap_server.wait_for_stopped()
25201263c6cSJonas Devlieghere        return None
25301263c6cSJonas Devlieghere
25401263c6cSJonas Devlieghere    def stepOut(self, threadId=None, waitForStop=True):
25501263c6cSJonas Devlieghere        self.dap_server.request_stepOut(threadId=threadId)
25601263c6cSJonas Devlieghere        if waitForStop:
25701263c6cSJonas Devlieghere            return self.dap_server.wait_for_stopped()
25801263c6cSJonas Devlieghere        return None
25901263c6cSJonas Devlieghere
26001263c6cSJonas Devlieghere    def continue_to_next_stop(self):
26101263c6cSJonas Devlieghere        self.dap_server.request_continue()
26201263c6cSJonas Devlieghere        return self.dap_server.wait_for_stopped()
26301263c6cSJonas Devlieghere
26401263c6cSJonas Devlieghere    def continue_to_breakpoints(self, breakpoint_ids):
26501263c6cSJonas Devlieghere        self.dap_server.request_continue()
26601263c6cSJonas Devlieghere        self.verify_breakpoint_hit(breakpoint_ids)
26701263c6cSJonas Devlieghere
26801263c6cSJonas Devlieghere    def continue_to_exception_breakpoint(self, filter_label):
26901263c6cSJonas Devlieghere        self.dap_server.request_continue()
27001263c6cSJonas Devlieghere        self.assertTrue(
27101263c6cSJonas Devlieghere            self.verify_stop_exception_info(filter_label),
27201263c6cSJonas Devlieghere            'verify we got "%s"' % (filter_label),
27301263c6cSJonas Devlieghere        )
27401263c6cSJonas Devlieghere
27501263c6cSJonas Devlieghere    def continue_to_exit(self, exitCode=0):
27601263c6cSJonas Devlieghere        self.dap_server.request_continue()
27701263c6cSJonas Devlieghere        stopped_events = self.dap_server.wait_for_stopped()
278737bc9f7SJonas Devlieghere        self.assertEqual(
27901263c6cSJonas Devlieghere            len(stopped_events), 1, "stopped_events = {}".format(stopped_events)
28001263c6cSJonas Devlieghere        )
281737bc9f7SJonas Devlieghere        self.assertEqual(
28201263c6cSJonas Devlieghere            stopped_events[0]["event"], "exited", "make sure program ran to completion"
28301263c6cSJonas Devlieghere        )
284737bc9f7SJonas Devlieghere        self.assertEqual(
28501263c6cSJonas Devlieghere            stopped_events[0]["body"]["exitCode"],
28601263c6cSJonas Devlieghere            exitCode,
28701263c6cSJonas Devlieghere            "exitCode == %i" % (exitCode),
28801263c6cSJonas Devlieghere        )
28901263c6cSJonas Devlieghere
29001263c6cSJonas Devlieghere    def disassemble(self, threadId=None, frameIndex=None):
29101263c6cSJonas Devlieghere        stackFrames = self.get_stackFrames(
29201263c6cSJonas Devlieghere            threadId=threadId, startFrame=frameIndex, levels=1
29301263c6cSJonas Devlieghere        )
29401263c6cSJonas Devlieghere        self.assertIsNotNone(stackFrames)
29501263c6cSJonas Devlieghere        memoryReference = stackFrames[0]["instructionPointerReference"]
29601263c6cSJonas Devlieghere        self.assertIsNotNone(memoryReference)
29701263c6cSJonas Devlieghere
29801263c6cSJonas Devlieghere        if memoryReference not in self.dap_server.disassembled_instructions:
29901263c6cSJonas Devlieghere            self.dap_server.request_disassemble(memoryReference=memoryReference)
30001263c6cSJonas Devlieghere
30101263c6cSJonas Devlieghere        return self.dap_server.disassembled_instructions[memoryReference]
30201263c6cSJonas Devlieghere
30301263c6cSJonas Devlieghere    def attach(
30401263c6cSJonas Devlieghere        self,
30501263c6cSJonas Devlieghere        program=None,
30601263c6cSJonas Devlieghere        pid=None,
30701263c6cSJonas Devlieghere        waitFor=None,
30801263c6cSJonas Devlieghere        trace=None,
30901263c6cSJonas Devlieghere        initCommands=None,
31001263c6cSJonas Devlieghere        preRunCommands=None,
31101263c6cSJonas Devlieghere        stopCommands=None,
31201263c6cSJonas Devlieghere        exitCommands=None,
31301263c6cSJonas Devlieghere        attachCommands=None,
31401263c6cSJonas Devlieghere        coreFile=None,
31501263c6cSJonas Devlieghere        disconnectAutomatically=True,
31601263c6cSJonas Devlieghere        terminateCommands=None,
31701263c6cSJonas Devlieghere        postRunCommands=None,
31801263c6cSJonas Devlieghere        sourceMap=None,
31901263c6cSJonas Devlieghere        sourceInitFile=False,
320aa207674SWalter Erquinigo        expectFailure=False,
321a52be0ccSSanthosh Kumar Ellendula        gdbRemotePort=None,
322a52be0ccSSanthosh Kumar Ellendula        gdbRemoteHostname=None,
32301263c6cSJonas Devlieghere    ):
32401263c6cSJonas Devlieghere        """Build the default Makefile target, create the DAP debug adaptor,
32501263c6cSJonas Devlieghere        and attach to the process.
32601263c6cSJonas Devlieghere        """
32701263c6cSJonas Devlieghere
32801263c6cSJonas Devlieghere        # Make sure we disconnect and terminate the DAP debug adaptor even
32901263c6cSJonas Devlieghere        # if we throw an exception during the test case.
33001263c6cSJonas Devlieghere        def cleanup():
33101263c6cSJonas Devlieghere            if disconnectAutomatically:
33201263c6cSJonas Devlieghere                self.dap_server.request_disconnect(terminateDebuggee=True)
33301263c6cSJonas Devlieghere            self.dap_server.terminate()
33401263c6cSJonas Devlieghere
33501263c6cSJonas Devlieghere        # Execute the cleanup function during test case tear down.
33601263c6cSJonas Devlieghere        self.addTearDownHook(cleanup)
33701263c6cSJonas Devlieghere        # Initialize and launch the program
33801263c6cSJonas Devlieghere        self.dap_server.request_initialize(sourceInitFile)
33901263c6cSJonas Devlieghere        response = self.dap_server.request_attach(
34001263c6cSJonas Devlieghere            program=program,
34101263c6cSJonas Devlieghere            pid=pid,
34201263c6cSJonas Devlieghere            waitFor=waitFor,
34301263c6cSJonas Devlieghere            trace=trace,
34401263c6cSJonas Devlieghere            initCommands=initCommands,
34501263c6cSJonas Devlieghere            preRunCommands=preRunCommands,
34601263c6cSJonas Devlieghere            stopCommands=stopCommands,
34701263c6cSJonas Devlieghere            exitCommands=exitCommands,
34801263c6cSJonas Devlieghere            attachCommands=attachCommands,
34901263c6cSJonas Devlieghere            terminateCommands=terminateCommands,
35001263c6cSJonas Devlieghere            coreFile=coreFile,
35101263c6cSJonas Devlieghere            postRunCommands=postRunCommands,
35201263c6cSJonas Devlieghere            sourceMap=sourceMap,
353a52be0ccSSanthosh Kumar Ellendula            gdbRemotePort=gdbRemotePort,
354a52be0ccSSanthosh Kumar Ellendula            gdbRemoteHostname=gdbRemoteHostname,
35501263c6cSJonas Devlieghere        )
356aa207674SWalter Erquinigo        if expectFailure:
357aa207674SWalter Erquinigo            return response
35801263c6cSJonas Devlieghere        if not (response and response["success"]):
35901263c6cSJonas Devlieghere            self.assertTrue(
36001263c6cSJonas Devlieghere                response["success"], "attach failed (%s)" % (response["message"])
36101263c6cSJonas Devlieghere            )
36201263c6cSJonas Devlieghere
36301263c6cSJonas Devlieghere    def launch(
36401263c6cSJonas Devlieghere        self,
36501263c6cSJonas Devlieghere        program=None,
36601263c6cSJonas Devlieghere        args=None,
36701263c6cSJonas Devlieghere        cwd=None,
36801263c6cSJonas Devlieghere        env=None,
36901263c6cSJonas Devlieghere        stopOnEntry=False,
3702d26ef09SMichael Buch        disableASLR=False,
37101263c6cSJonas Devlieghere        disableSTDIO=False,
37201263c6cSJonas Devlieghere        shellExpandArguments=False,
37301263c6cSJonas Devlieghere        trace=False,
37401263c6cSJonas Devlieghere        initCommands=None,
37501263c6cSJonas Devlieghere        preRunCommands=None,
37601263c6cSJonas Devlieghere        stopCommands=None,
37701263c6cSJonas Devlieghere        exitCommands=None,
37801263c6cSJonas Devlieghere        terminateCommands=None,
37901263c6cSJonas Devlieghere        sourcePath=None,
38001263c6cSJonas Devlieghere        debuggerRoot=None,
38101263c6cSJonas Devlieghere        sourceInitFile=False,
38201263c6cSJonas Devlieghere        launchCommands=None,
38301263c6cSJonas Devlieghere        sourceMap=None,
38401263c6cSJonas Devlieghere        disconnectAutomatically=True,
38501263c6cSJonas Devlieghere        runInTerminal=False,
38601263c6cSJonas Devlieghere        expectFailure=False,
38701263c6cSJonas Devlieghere        postRunCommands=None,
38801263c6cSJonas Devlieghere        enableAutoVariableSummaries=False,
38919ecdedcSAdrian Vogelsgesang        displayExtendedBacktrace=False,
39001263c6cSJonas Devlieghere        enableSyntheticChildDebugging=False,
39185ee3fc7Sjeffreytan81        commandEscapePrefix=None,
392d9ec4b24SWalter Erquinigo        customFrameFormat=None,
3931654d7dcSWalter Erquinigo        customThreadFormat=None,
39401263c6cSJonas Devlieghere    ):
39501263c6cSJonas Devlieghere        """Sending launch request to dap"""
39601263c6cSJonas Devlieghere
39701263c6cSJonas Devlieghere        # Make sure we disconnect and terminate the DAP debug adapter,
39801263c6cSJonas Devlieghere        # if we throw an exception during the test case
39901263c6cSJonas Devlieghere        def cleanup():
40001263c6cSJonas Devlieghere            if disconnectAutomatically:
40101263c6cSJonas Devlieghere                self.dap_server.request_disconnect(terminateDebuggee=True)
40201263c6cSJonas Devlieghere            self.dap_server.terminate()
40301263c6cSJonas Devlieghere
40401263c6cSJonas Devlieghere        # Execute the cleanup function during test case tear down.
40501263c6cSJonas Devlieghere        self.addTearDownHook(cleanup)
40601263c6cSJonas Devlieghere
40701263c6cSJonas Devlieghere        # Initialize and launch the program
40801263c6cSJonas Devlieghere        self.dap_server.request_initialize(sourceInitFile)
40901263c6cSJonas Devlieghere        response = self.dap_server.request_launch(
41001263c6cSJonas Devlieghere            program,
41101263c6cSJonas Devlieghere            args=args,
41201263c6cSJonas Devlieghere            cwd=cwd,
41301263c6cSJonas Devlieghere            env=env,
41401263c6cSJonas Devlieghere            stopOnEntry=stopOnEntry,
41501263c6cSJonas Devlieghere            disableASLR=disableASLR,
41601263c6cSJonas Devlieghere            disableSTDIO=disableSTDIO,
41701263c6cSJonas Devlieghere            shellExpandArguments=shellExpandArguments,
41801263c6cSJonas Devlieghere            trace=trace,
41901263c6cSJonas Devlieghere            initCommands=initCommands,
42001263c6cSJonas Devlieghere            preRunCommands=preRunCommands,
42101263c6cSJonas Devlieghere            stopCommands=stopCommands,
42201263c6cSJonas Devlieghere            exitCommands=exitCommands,
42301263c6cSJonas Devlieghere            terminateCommands=terminateCommands,
42401263c6cSJonas Devlieghere            sourcePath=sourcePath,
42501263c6cSJonas Devlieghere            debuggerRoot=debuggerRoot,
42601263c6cSJonas Devlieghere            launchCommands=launchCommands,
42701263c6cSJonas Devlieghere            sourceMap=sourceMap,
42801263c6cSJonas Devlieghere            runInTerminal=runInTerminal,
42901263c6cSJonas Devlieghere            postRunCommands=postRunCommands,
43001263c6cSJonas Devlieghere            enableAutoVariableSummaries=enableAutoVariableSummaries,
43119ecdedcSAdrian Vogelsgesang            displayExtendedBacktrace=displayExtendedBacktrace,
43201263c6cSJonas Devlieghere            enableSyntheticChildDebugging=enableSyntheticChildDebugging,
43310664813SWalter Erquinigo            commandEscapePrefix=commandEscapePrefix,
434d9ec4b24SWalter Erquinigo            customFrameFormat=customFrameFormat,
4351654d7dcSWalter Erquinigo            customThreadFormat=customThreadFormat,
43601263c6cSJonas Devlieghere        )
43701263c6cSJonas Devlieghere
43801263c6cSJonas Devlieghere        if expectFailure:
43901263c6cSJonas Devlieghere            return response
44001263c6cSJonas Devlieghere
44101263c6cSJonas Devlieghere        if not (response and response["success"]):
44201263c6cSJonas Devlieghere            self.assertTrue(
44301263c6cSJonas Devlieghere                response["success"], "launch failed (%s)" % (response["message"])
44401263c6cSJonas Devlieghere            )
44501263c6cSJonas Devlieghere        return response
44601263c6cSJonas Devlieghere
44701263c6cSJonas Devlieghere    def build_and_launch(
44801263c6cSJonas Devlieghere        self,
44901263c6cSJonas Devlieghere        program,
45001263c6cSJonas Devlieghere        args=None,
45101263c6cSJonas Devlieghere        cwd=None,
45201263c6cSJonas Devlieghere        env=None,
45301263c6cSJonas Devlieghere        stopOnEntry=False,
4542d26ef09SMichael Buch        disableASLR=False,
45501263c6cSJonas Devlieghere        disableSTDIO=False,
45601263c6cSJonas Devlieghere        shellExpandArguments=False,
45701263c6cSJonas Devlieghere        trace=False,
45801263c6cSJonas Devlieghere        initCommands=None,
45901263c6cSJonas Devlieghere        preRunCommands=None,
46001263c6cSJonas Devlieghere        stopCommands=None,
46101263c6cSJonas Devlieghere        exitCommands=None,
46201263c6cSJonas Devlieghere        terminateCommands=None,
46301263c6cSJonas Devlieghere        sourcePath=None,
46401263c6cSJonas Devlieghere        debuggerRoot=None,
46501263c6cSJonas Devlieghere        sourceInitFile=False,
46601263c6cSJonas Devlieghere        runInTerminal=False,
46701263c6cSJonas Devlieghere        disconnectAutomatically=True,
46801263c6cSJonas Devlieghere        postRunCommands=None,
46901263c6cSJonas Devlieghere        lldbDAPEnv=None,
47001263c6cSJonas Devlieghere        enableAutoVariableSummaries=False,
47119ecdedcSAdrian Vogelsgesang        displayExtendedBacktrace=False,
47201263c6cSJonas Devlieghere        enableSyntheticChildDebugging=False,
47385ee3fc7Sjeffreytan81        commandEscapePrefix=None,
474d9ec4b24SWalter Erquinigo        customFrameFormat=None,
4751654d7dcSWalter Erquinigo        customThreadFormat=None,
476aa207674SWalter Erquinigo        launchCommands=None,
477aa207674SWalter Erquinigo        expectFailure=False,
47801263c6cSJonas Devlieghere    ):
47901263c6cSJonas Devlieghere        """Build the default Makefile target, create the DAP debug adaptor,
48001263c6cSJonas Devlieghere        and launch the process.
48101263c6cSJonas Devlieghere        """
48201263c6cSJonas Devlieghere        self.build_and_create_debug_adaptor(lldbDAPEnv)
48301263c6cSJonas Devlieghere        self.assertTrue(os.path.exists(program), "executable must exist")
48401263c6cSJonas Devlieghere
48501263c6cSJonas Devlieghere        return self.launch(
48601263c6cSJonas Devlieghere            program,
48701263c6cSJonas Devlieghere            args,
48801263c6cSJonas Devlieghere            cwd,
48901263c6cSJonas Devlieghere            env,
49001263c6cSJonas Devlieghere            stopOnEntry,
49101263c6cSJonas Devlieghere            disableASLR,
49201263c6cSJonas Devlieghere            disableSTDIO,
49301263c6cSJonas Devlieghere            shellExpandArguments,
49401263c6cSJonas Devlieghere            trace,
49501263c6cSJonas Devlieghere            initCommands,
49601263c6cSJonas Devlieghere            preRunCommands,
49701263c6cSJonas Devlieghere            stopCommands,
49801263c6cSJonas Devlieghere            exitCommands,
49901263c6cSJonas Devlieghere            terminateCommands,
50001263c6cSJonas Devlieghere            sourcePath,
50101263c6cSJonas Devlieghere            debuggerRoot,
50201263c6cSJonas Devlieghere            sourceInitFile,
50301263c6cSJonas Devlieghere            runInTerminal=runInTerminal,
50401263c6cSJonas Devlieghere            disconnectAutomatically=disconnectAutomatically,
50501263c6cSJonas Devlieghere            postRunCommands=postRunCommands,
50601263c6cSJonas Devlieghere            enableAutoVariableSummaries=enableAutoVariableSummaries,
50701263c6cSJonas Devlieghere            enableSyntheticChildDebugging=enableSyntheticChildDebugging,
50819ecdedcSAdrian Vogelsgesang            displayExtendedBacktrace=displayExtendedBacktrace,
50910664813SWalter Erquinigo            commandEscapePrefix=commandEscapePrefix,
510d9ec4b24SWalter Erquinigo            customFrameFormat=customFrameFormat,
5111654d7dcSWalter Erquinigo            customThreadFormat=customThreadFormat,
512aa207674SWalter Erquinigo            launchCommands=launchCommands,
513aa207674SWalter Erquinigo            expectFailure=expectFailure,
51401263c6cSJonas Devlieghere        )
515a52be0ccSSanthosh Kumar Ellendula
516a52be0ccSSanthosh Kumar Ellendula    def getBuiltinDebugServerTool(self):
517a52be0ccSSanthosh Kumar Ellendula        # Tries to find simulation/lldb-server/gdbserver tool path.
518a52be0ccSSanthosh Kumar Ellendula        server_tool = None
519a52be0ccSSanthosh Kumar Ellendula        if lldbplatformutil.getPlatform() == "linux":
520a52be0ccSSanthosh Kumar Ellendula            server_tool = lldbgdbserverutils.get_lldb_server_exe()
521a52be0ccSSanthosh Kumar Ellendula            if server_tool is None:
522a52be0ccSSanthosh Kumar Ellendula                self.dap_server.request_disconnect(terminateDebuggee=True)
523a52be0ccSSanthosh Kumar Ellendula                self.assertIsNotNone(server_tool, "lldb-server not found.")
524a52be0ccSSanthosh Kumar Ellendula        elif lldbplatformutil.getPlatform() == "macosx":
525a52be0ccSSanthosh Kumar Ellendula            server_tool = lldbgdbserverutils.get_debugserver_exe()
526a52be0ccSSanthosh Kumar Ellendula            if server_tool is None:
527a52be0ccSSanthosh Kumar Ellendula                self.dap_server.request_disconnect(terminateDebuggee=True)
528a52be0ccSSanthosh Kumar Ellendula                self.assertIsNotNone(server_tool, "debugserver not found.")
529a52be0ccSSanthosh Kumar Ellendula        return server_tool
530