11import os
22import time
3+ from typing import Optional
34import uuid
45
56import dap_server
1112class DAPTestCaseBase (TestBase ):
1213 # set timeout based on whether ASAN was enabled or not. Increase
1314 # timeout by a factor of 10 if ASAN is enabled.
14- timeoutval = 10 * (10 if ("ASAN_OPTIONS" in os .environ ) else 1 )
15+ DEFAULT_TIMEOUT = 10 * (10 if ("ASAN_OPTIONS" in os .environ ) else 1 )
1516 NO_DEBUG_INFO_TESTCASE = True
1617
17- def create_debug_adapter (self , lldbDAPEnv = None , connection = None ):
18+ def create_debug_adapter (
19+ self ,
20+ lldbDAPEnv : Optional [dict [str , str ]] = None ,
21+ connection : Optional [str ] = None ,
22+ ):
1823 """Create the Visual Studio Code debug adapter"""
1924 self .assertTrue (
2025 is_exe (self .lldbDAPExec ), "lldb-dap must exist and be executable"
@@ -28,7 +33,11 @@ def create_debug_adapter(self, lldbDAPEnv=None, connection=None):
2833 env = lldbDAPEnv ,
2934 )
3035
31- def build_and_create_debug_adapter (self , lldbDAPEnv = None , dictionary = None ):
36+ def build_and_create_debug_adapter (
37+ self ,
38+ lldbDAPEnv : Optional [dict [str , str ]] = None ,
39+ dictionary : Optional [dict ] = None ,
40+ ):
3241 self .build (dictionary = dictionary )
3342 self .create_debug_adapter (lldbDAPEnv )
3443
@@ -78,13 +87,13 @@ def waitUntil(self, condition_callback):
7887 time .sleep (0.5 )
7988 return False
8089
81- def verify_breakpoint_hit (self , breakpoint_ids ):
90+ def verify_breakpoint_hit (self , breakpoint_ids , timeout = DEFAULT_TIMEOUT ):
8291 """Wait for the process we are debugging to stop, and verify we hit
8392 any breakpoint location in the "breakpoint_ids" array.
8493 "breakpoint_ids" should be a list of breakpoint ID strings
8594 (["1", "2"]). The return value from self.set_source_breakpoints()
8695 or self.set_function_breakpoints() can be passed to this function"""
87- stopped_events = self .dap_server .wait_for_stopped ()
96+ stopped_events = self .dap_server .wait_for_stopped (timeout )
8897 for stopped_event in stopped_events :
8998 if "body" in stopped_event :
9099 body = stopped_event ["body" ]
@@ -110,16 +119,15 @@ def verify_breakpoint_hit(self, breakpoint_ids):
110119 match_desc = "breakpoint %s." % (breakpoint_id )
111120 if match_desc in description :
112121 return
113- self .assertTrue (False , "breakpoint not hit" )
122+ self .assertTrue (False , f "breakpoint not hit, stopped_events= { stopped_events } " )
114123
115- def verify_stop_exception_info (self , expected_description , timeout = timeoutval ):
124+ def verify_stop_exception_info (self , expected_description , timeout = DEFAULT_TIMEOUT ):
116125 """Wait for the process we are debugging to stop, and verify the stop
117126 reason is 'exception' and that the description matches
118127 'expected_description'
119128 """
120- stopped_events = self .dap_server .wait_for_stopped (timeout = timeout )
129+ stopped_events = self .dap_server .wait_for_stopped (timeout )
121130 for stopped_event in stopped_events :
122- print ("stopped_event" , stopped_event )
123131 if "body" in stopped_event :
124132 body = stopped_event ["body" ]
125133 if "reason" not in body :
@@ -263,46 +271,61 @@ def set_global(self, name, value, id=None):
263271 return self .dap_server .request_setVariable (2 , name , str (value ), id = id )
264272
265273 def stepIn (
266- self , threadId = None , targetId = None , waitForStop = True , granularity = "statement"
274+ self ,
275+ threadId = None ,
276+ targetId = None ,
277+ waitForStop = True ,
278+ granularity = "statement" ,
279+ timeout = DEFAULT_TIMEOUT ,
267280 ):
268281 response = self .dap_server .request_stepIn (
269282 threadId = threadId , targetId = targetId , granularity = granularity
270283 )
271284 self .assertTrue (response ["success" ])
272285 if waitForStop :
273- return self .dap_server .wait_for_stopped ()
286+ return self .dap_server .wait_for_stopped (timeout )
274287 return None
275288
276- def stepOver (self , threadId = None , waitForStop = True , granularity = "statement" ):
289+ def stepOver (
290+ self ,
291+ threadId = None ,
292+ waitForStop = True ,
293+ granularity = "statement" ,
294+ timeout = DEFAULT_TIMEOUT ,
295+ ):
277296 self .dap_server .request_next (threadId = threadId , granularity = granularity )
278297 if waitForStop :
279- return self .dap_server .wait_for_stopped ()
298+ return self .dap_server .wait_for_stopped (timeout )
280299 return None
281300
282- def stepOut (self , threadId = None , waitForStop = True ):
301+ def stepOut (self , threadId = None , waitForStop = True , timeout = DEFAULT_TIMEOUT ):
283302 self .dap_server .request_stepOut (threadId = threadId )
284303 if waitForStop :
285- return self .dap_server .wait_for_stopped ()
304+ return self .dap_server .wait_for_stopped (timeout )
286305 return None
287306
288- def continue_to_next_stop (self ):
289- self .dap_server .request_continue ()
290- return self .dap_server .wait_for_stopped ()
307+ def do_continue (self ): # `continue` is a keyword.
308+ resp = self .dap_server .request_continue ()
309+ self .assertTrue (resp ["success" ], f"continue request failed: { resp } " )
310+
311+ def continue_to_next_stop (self , timeout = DEFAULT_TIMEOUT ):
312+ self .do_continue ()
313+ return self .dap_server .wait_for_stopped (timeout )
291314
292- def continue_to_breakpoints (self , breakpoint_ids ):
293- self .dap_server . request_continue ()
294- self .verify_breakpoint_hit (breakpoint_ids )
315+ def continue_to_breakpoints (self , breakpoint_ids , timeout = DEFAULT_TIMEOUT ):
316+ self .do_continue ()
317+ self .verify_breakpoint_hit (breakpoint_ids , timeout )
295318
296- def continue_to_exception_breakpoint (self , filter_label ):
297- self .dap_server . request_continue ()
319+ def continue_to_exception_breakpoint (self , filter_label , timeout = DEFAULT_TIMEOUT ):
320+ self .do_continue ()
298321 self .assertTrue (
299- self .verify_stop_exception_info (filter_label ),
322+ self .verify_stop_exception_info (filter_label , timeout ),
300323 'verify we got "%s"' % (filter_label ),
301324 )
302325
303- def continue_to_exit (self , exitCode = 0 ):
304- self .dap_server . request_continue ()
305- stopped_events = self .dap_server .wait_for_stopped ()
326+ def continue_to_exit (self , exitCode = 0 , timeout = DEFAULT_TIMEOUT ):
327+ self .do_continue ()
328+ stopped_events = self .dap_server .wait_for_stopped (timeout )
306329 self .assertEqual (
307330 len (stopped_events ), 1 , "stopped_events = {}" .format (stopped_events )
308331 )
@@ -330,27 +353,15 @@ def disassemble(self, threadId=None, frameIndex=None):
330353
331354 def attach (
332355 self ,
333- program = None ,
334- pid = None ,
335- waitFor = None ,
336- trace = None ,
337- initCommands = None ,
338- preRunCommands = None ,
339- stopCommands = None ,
340- exitCommands = None ,
341- attachCommands = None ,
342- coreFile = None ,
356+ * ,
343357 stopOnAttach = True ,
344358 disconnectAutomatically = True ,
345- terminateCommands = None ,
346- postRunCommands = None ,
347- sourceMap = None ,
348359 sourceInitFile = False ,
349360 expectFailure = False ,
350- gdbRemotePort = None ,
351- gdbRemoteHostname = None ,
352361 sourceBreakpoints = None ,
353362 functionBreakpoints = None ,
363+ timeout = DEFAULT_TIMEOUT ,
364+ ** kwargs ,
354365 ):
355366 """Build the default Makefile target, create the DAP debug adapter,
356367 and attach to the process.
@@ -367,7 +378,7 @@ def cleanup():
367378 self .addTearDownHook (cleanup )
368379 # Initialize and launch the program
369380 self .dap_server .request_initialize (sourceInitFile )
370- self .dap_server .wait_for_event ("initialized" )
381+ self .dap_server .wait_for_event ("initialized" , timeout )
371382
372383 # Set source breakpoints as part of the launch sequence.
373384 if sourceBreakpoints :
@@ -389,64 +400,28 @@ def cleanup():
389400 )
390401
391402 self .dap_server .request_configurationDone ()
392- response = self .dap_server .request_attach (
393- program = program ,
394- pid = pid ,
395- waitFor = waitFor ,
396- trace = trace ,
397- initCommands = initCommands ,
398- preRunCommands = preRunCommands ,
399- stopCommands = stopCommands ,
400- exitCommands = exitCommands ,
401- attachCommands = attachCommands ,
402- terminateCommands = terminateCommands ,
403- coreFile = coreFile ,
404- stopOnAttach = stopOnAttach ,
405- postRunCommands = postRunCommands ,
406- sourceMap = sourceMap ,
407- gdbRemotePort = gdbRemotePort ,
408- gdbRemoteHostname = gdbRemoteHostname ,
409- )
403+ response = self .dap_server .request_attach (stopOnAttach = stopOnAttach , ** kwargs )
410404 if expectFailure :
411405 return response
412406 if not (response and response ["success" ]):
413407 self .assertTrue (
414408 response ["success" ], "attach failed (%s)" % (response ["message" ])
415409 )
410+ if stopOnAttach :
411+ self .dap_server .wait_for_stopped (timeout )
416412
417413 def launch (
418414 self ,
419415 program = None ,
420- args = None ,
421- cwd = None ,
422- env = None ,
423- stopOnEntry = False ,
424- disableASLR = False ,
425- disableSTDIO = False ,
426- shellExpandArguments = False ,
427- trace = False ,
428- initCommands = None ,
429- preRunCommands = None ,
430- stopCommands = None ,
431- exitCommands = None ,
432- terminateCommands = None ,
433- sourcePath = None ,
434- debuggerRoot = None ,
416+ * ,
435417 sourceInitFile = False ,
436- launchCommands = None ,
437- sourceMap = None ,
438418 disconnectAutomatically = True ,
439- runInTerminal = False ,
440- expectFailure = False ,
441- postRunCommands = None ,
442- enableAutoVariableSummaries = False ,
443- displayExtendedBacktrace = False ,
444- enableSyntheticChildDebugging = False ,
445- commandEscapePrefix = None ,
446- customFrameFormat = None ,
447- customThreadFormat = None ,
448419 sourceBreakpoints = None ,
449420 functionBreakpoints = None ,
421+ expectFailure = False ,
422+ stopOnEntry = True ,
423+ timeout = DEFAULT_TIMEOUT ,
424+ ** kwargs ,
450425 ):
451426 """Sending launch request to dap"""
452427
@@ -462,7 +437,7 @@ def cleanup():
462437
463438 # Initialize and launch the program
464439 self .dap_server .request_initialize (sourceInitFile )
465- self .dap_server .wait_for_event ("initialized" )
440+ self .dap_server .wait_for_event ("initialized" , timeout )
466441
467442 # Set source breakpoints as part of the launch sequence.
468443 if sourceBreakpoints :
@@ -487,115 +462,36 @@ def cleanup():
487462
488463 response = self .dap_server .request_launch (
489464 program ,
490- args = args ,
491- cwd = cwd ,
492- env = env ,
493465 stopOnEntry = stopOnEntry ,
494- disableASLR = disableASLR ,
495- disableSTDIO = disableSTDIO ,
496- shellExpandArguments = shellExpandArguments ,
497- trace = trace ,
498- initCommands = initCommands ,
499- preRunCommands = preRunCommands ,
500- stopCommands = stopCommands ,
501- exitCommands = exitCommands ,
502- terminateCommands = terminateCommands ,
503- sourcePath = sourcePath ,
504- debuggerRoot = debuggerRoot ,
505- launchCommands = launchCommands ,
506- sourceMap = sourceMap ,
507- runInTerminal = runInTerminal ,
508- postRunCommands = postRunCommands ,
509- enableAutoVariableSummaries = enableAutoVariableSummaries ,
510- displayExtendedBacktrace = displayExtendedBacktrace ,
511- enableSyntheticChildDebugging = enableSyntheticChildDebugging ,
512- commandEscapePrefix = commandEscapePrefix ,
513- customFrameFormat = customFrameFormat ,
514- customThreadFormat = customThreadFormat ,
466+ ** kwargs ,
515467 )
516468
517469 if expectFailure :
518470 return response
519-
520471 if not (response and response ["success" ]):
521472 self .assertTrue (
522473 response ["success" ],
523474 "launch failed (%s)" % (response ["body" ]["error" ]["format" ]),
524475 )
476+ if stopOnEntry :
477+ self .dap_server .wait_for_stopped (timeout )
478+
525479 return response
526480
527481 def build_and_launch (
528482 self ,
529483 program ,
530- args = None ,
531- cwd = None ,
532- env = None ,
533- stopOnEntry = False ,
534- disableASLR = False ,
535- disableSTDIO = False ,
536- shellExpandArguments = False ,
537- trace = False ,
538- initCommands = None ,
539- preRunCommands = None ,
540- stopCommands = None ,
541- exitCommands = None ,
542- terminateCommands = None ,
543- sourcePath = None ,
544- debuggerRoot = None ,
545- sourceInitFile = False ,
546- runInTerminal = False ,
547- disconnectAutomatically = True ,
548- postRunCommands = None ,
549- lldbDAPEnv = None ,
550- enableAutoVariableSummaries = False ,
551- displayExtendedBacktrace = False ,
552- enableSyntheticChildDebugging = False ,
553- commandEscapePrefix = None ,
554- customFrameFormat = None ,
555- customThreadFormat = None ,
556- launchCommands = None ,
557- expectFailure = False ,
558- sourceBreakpoints = None ,
559- functionBreakpoints = None ,
484+ * ,
485+ lldbDAPEnv : Optional [dict [str , str ]] = None ,
486+ ** kwargs ,
560487 ):
561488 """Build the default Makefile target, create the DAP debug adapter,
562489 and launch the process.
563490 """
564491 self .build_and_create_debug_adapter (lldbDAPEnv )
565492 self .assertTrue (os .path .exists (program ), "executable must exist" )
566493
567- return self .launch (
568- program ,
569- args ,
570- cwd ,
571- env ,
572- stopOnEntry ,
573- disableASLR ,
574- disableSTDIO ,
575- shellExpandArguments ,
576- trace ,
577- initCommands ,
578- preRunCommands ,
579- stopCommands ,
580- exitCommands ,
581- terminateCommands ,
582- sourcePath ,
583- debuggerRoot ,
584- sourceInitFile ,
585- runInTerminal = runInTerminal ,
586- disconnectAutomatically = disconnectAutomatically ,
587- postRunCommands = postRunCommands ,
588- enableAutoVariableSummaries = enableAutoVariableSummaries ,
589- enableSyntheticChildDebugging = enableSyntheticChildDebugging ,
590- displayExtendedBacktrace = displayExtendedBacktrace ,
591- commandEscapePrefix = commandEscapePrefix ,
592- customFrameFormat = customFrameFormat ,
593- customThreadFormat = customThreadFormat ,
594- launchCommands = launchCommands ,
595- expectFailure = expectFailure ,
596- sourceBreakpoints = sourceBreakpoints ,
597- functionBreakpoints = functionBreakpoints ,
598- )
494+ return self .launch (program , ** kwargs )
599495
600496 def getBuiltinDebugServerTool (self ):
601497 # Tries to find simulation/lldb-server/gdbserver tool path.
0 commit comments