1
1
import os
2
2
import time
3
+ from typing import Optional
3
4
import uuid
4
5
5
6
import dap_server
11
12
class DAPTestCaseBase (TestBase ):
12
13
# set timeout based on whether ASAN was enabled or not. Increase
13
14
# 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 )
15
16
NO_DEBUG_INFO_TESTCASE = True
16
17
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
+ ):
18
23
"""Create the Visual Studio Code debug adapter"""
19
24
self .assertTrue (
20
25
is_exe (self .lldbDAPExec ), "lldb-dap must exist and be executable"
@@ -28,7 +33,11 @@ def create_debug_adapter(self, lldbDAPEnv=None, connection=None):
28
33
env = lldbDAPEnv ,
29
34
)
30
35
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
+ ):
32
41
self .build (dictionary = dictionary )
33
42
self .create_debug_adapter (lldbDAPEnv )
34
43
@@ -78,13 +87,13 @@ def waitUntil(self, condition_callback):
78
87
time .sleep (0.5 )
79
88
return False
80
89
81
- def verify_breakpoint_hit (self , breakpoint_ids ):
90
+ def verify_breakpoint_hit (self , breakpoint_ids , timeout = DEFAULT_TIMEOUT ):
82
91
"""Wait for the process we are debugging to stop, and verify we hit
83
92
any breakpoint location in the "breakpoint_ids" array.
84
93
"breakpoint_ids" should be a list of breakpoint ID strings
85
94
(["1", "2"]). The return value from self.set_source_breakpoints()
86
95
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 )
88
97
for stopped_event in stopped_events :
89
98
if "body" in stopped_event :
90
99
body = stopped_event ["body" ]
@@ -110,16 +119,15 @@ def verify_breakpoint_hit(self, breakpoint_ids):
110
119
match_desc = "breakpoint %s." % (breakpoint_id )
111
120
if match_desc in description :
112
121
return
113
- self .assertTrue (False , "breakpoint not hit" )
122
+ self .assertTrue (False , f "breakpoint not hit, stopped_events= { stopped_events } " )
114
123
115
- def verify_stop_exception_info (self , expected_description , timeout = timeoutval ):
124
+ def verify_stop_exception_info (self , expected_description , timeout = DEFAULT_TIMEOUT ):
116
125
"""Wait for the process we are debugging to stop, and verify the stop
117
126
reason is 'exception' and that the description matches
118
127
'expected_description'
119
128
"""
120
- stopped_events = self .dap_server .wait_for_stopped (timeout = timeout )
129
+ stopped_events = self .dap_server .wait_for_stopped (timeout )
121
130
for stopped_event in stopped_events :
122
- print ("stopped_event" , stopped_event )
123
131
if "body" in stopped_event :
124
132
body = stopped_event ["body" ]
125
133
if "reason" not in body :
@@ -263,46 +271,61 @@ def set_global(self, name, value, id=None):
263
271
return self .dap_server .request_setVariable (2 , name , str (value ), id = id )
264
272
265
273
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 ,
267
280
):
268
281
response = self .dap_server .request_stepIn (
269
282
threadId = threadId , targetId = targetId , granularity = granularity
270
283
)
271
284
self .assertTrue (response ["success" ])
272
285
if waitForStop :
273
- return self .dap_server .wait_for_stopped ()
286
+ return self .dap_server .wait_for_stopped (timeout )
274
287
return None
275
288
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
+ ):
277
296
self .dap_server .request_next (threadId = threadId , granularity = granularity )
278
297
if waitForStop :
279
- return self .dap_server .wait_for_stopped ()
298
+ return self .dap_server .wait_for_stopped (timeout )
280
299
return None
281
300
282
- def stepOut (self , threadId = None , waitForStop = True ):
301
+ def stepOut (self , threadId = None , waitForStop = True , timeout = DEFAULT_TIMEOUT ):
283
302
self .dap_server .request_stepOut (threadId = threadId )
284
303
if waitForStop :
285
- return self .dap_server .wait_for_stopped ()
304
+ return self .dap_server .wait_for_stopped (timeout )
286
305
return None
287
306
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 )
291
314
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 )
295
318
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 ()
298
321
self .assertTrue (
299
- self .verify_stop_exception_info (filter_label ),
322
+ self .verify_stop_exception_info (filter_label , timeout ),
300
323
'verify we got "%s"' % (filter_label ),
301
324
)
302
325
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 )
306
329
self .assertEqual (
307
330
len (stopped_events ), 1 , "stopped_events = {}" .format (stopped_events )
308
331
)
@@ -330,27 +353,15 @@ def disassemble(self, threadId=None, frameIndex=None):
330
353
331
354
def attach (
332
355
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
+ * ,
343
357
stopOnAttach = True ,
344
358
disconnectAutomatically = True ,
345
- terminateCommands = None ,
346
- postRunCommands = None ,
347
- sourceMap = None ,
348
359
sourceInitFile = False ,
349
360
expectFailure = False ,
350
- gdbRemotePort = None ,
351
- gdbRemoteHostname = None ,
352
361
sourceBreakpoints = None ,
353
362
functionBreakpoints = None ,
363
+ timeout = DEFAULT_TIMEOUT ,
364
+ ** kwargs ,
354
365
):
355
366
"""Build the default Makefile target, create the DAP debug adapter,
356
367
and attach to the process.
@@ -367,7 +378,7 @@ def cleanup():
367
378
self .addTearDownHook (cleanup )
368
379
# Initialize and launch the program
369
380
self .dap_server .request_initialize (sourceInitFile )
370
- self .dap_server .wait_for_event ("initialized" )
381
+ self .dap_server .wait_for_event ("initialized" , timeout )
371
382
372
383
# Set source breakpoints as part of the launch sequence.
373
384
if sourceBreakpoints :
@@ -389,64 +400,28 @@ def cleanup():
389
400
)
390
401
391
402
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 )
410
404
if expectFailure :
411
405
return response
412
406
if not (response and response ["success" ]):
413
407
self .assertTrue (
414
408
response ["success" ], "attach failed (%s)" % (response ["message" ])
415
409
)
410
+ if stopOnAttach :
411
+ self .dap_server .wait_for_stopped (timeout )
416
412
417
413
def launch (
418
414
self ,
419
415
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
+ * ,
435
417
sourceInitFile = False ,
436
- launchCommands = None ,
437
- sourceMap = None ,
438
418
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 ,
448
419
sourceBreakpoints = None ,
449
420
functionBreakpoints = None ,
421
+ expectFailure = False ,
422
+ stopOnEntry = True ,
423
+ timeout = DEFAULT_TIMEOUT ,
424
+ ** kwargs ,
450
425
):
451
426
"""Sending launch request to dap"""
452
427
@@ -462,7 +437,7 @@ def cleanup():
462
437
463
438
# Initialize and launch the program
464
439
self .dap_server .request_initialize (sourceInitFile )
465
- self .dap_server .wait_for_event ("initialized" )
440
+ self .dap_server .wait_for_event ("initialized" , timeout )
466
441
467
442
# Set source breakpoints as part of the launch sequence.
468
443
if sourceBreakpoints :
@@ -487,115 +462,36 @@ def cleanup():
487
462
488
463
response = self .dap_server .request_launch (
489
464
program ,
490
- args = args ,
491
- cwd = cwd ,
492
- env = env ,
493
465
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 ,
515
467
)
516
468
517
469
if expectFailure :
518
470
return response
519
-
520
471
if not (response and response ["success" ]):
521
472
self .assertTrue (
522
473
response ["success" ],
523
474
"launch failed (%s)" % (response ["body" ]["error" ]["format" ]),
524
475
)
476
+ if stopOnEntry :
477
+ self .dap_server .wait_for_stopped (timeout )
478
+
525
479
return response
526
480
527
481
def build_and_launch (
528
482
self ,
529
483
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 ,
560
487
):
561
488
"""Build the default Makefile target, create the DAP debug adapter,
562
489
and launch the process.
563
490
"""
564
491
self .build_and_create_debug_adapter (lldbDAPEnv )
565
492
self .assertTrue (os .path .exists (program ), "executable must exist" )
566
493
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 )
599
495
600
496
def getBuiltinDebugServerTool (self ):
601
497
# Tries to find simulation/lldb-server/gdbserver tool path.
0 commit comments