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