Skip to content

Commit d229f34

Browse files
committed
[lldb-dap] Adding additional asserts to unit tests.
Adding an assert that the 'continue' request succeeds caused a number of tests to fail. This showed a number of tests that were not specifying if they should be stopped or not at key points in the test. This is likely contributing to these tests being flaky since the debugger is not in the expected state. Additionally, I spent a little time trying to improve the readability of the dap_server.py and lldbdap_testcase.py.
1 parent 960afcc commit d229f34

File tree

18 files changed

+311
-370
lines changed

18 files changed

+311
-370
lines changed

lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py

Lines changed: 130 additions & 98 deletions
Large diffs are not rendered by default.

lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py

Lines changed: 57 additions & 170 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,13 @@ def waitUntil(self, condition_callback):
7878
time.sleep(0.5)
7979
return False
8080

81-
def verify_breakpoint_hit(self, breakpoint_ids):
81+
def verify_breakpoint_hit(self, breakpoint_ids, timeout=timeoutval):
8282
"""Wait for the process we are debugging to stop, and verify we hit
8383
any breakpoint location in the "breakpoint_ids" array.
8484
"breakpoint_ids" should be a list of breakpoint ID strings
8585
(["1", "2"]). The return value from self.set_source_breakpoints()
8686
or self.set_function_breakpoints() can be passed to this function"""
87-
stopped_events = self.dap_server.wait_for_stopped()
87+
stopped_events = self.dap_server.wait_for_stopped(timeout)
8888
for stopped_event in stopped_events:
8989
if "body" in stopped_event:
9090
body = stopped_event["body"]
@@ -110,16 +110,15 @@ def verify_breakpoint_hit(self, breakpoint_ids):
110110
match_desc = "breakpoint %s." % (breakpoint_id)
111111
if match_desc in description:
112112
return
113-
self.assertTrue(False, "breakpoint not hit")
113+
self.assertTrue(False, f"breakpoint not hit, stopped_events={stopped_events}")
114114

115115
def verify_stop_exception_info(self, expected_description, timeout=timeoutval):
116116
"""Wait for the process we are debugging to stop, and verify the stop
117117
reason is 'exception' and that the description matches
118118
'expected_description'
119119
"""
120-
stopped_events = self.dap_server.wait_for_stopped(timeout=timeout)
120+
stopped_events = self.dap_server.wait_for_stopped(timeout)
121121
for stopped_event in stopped_events:
122-
print("stopped_event", stopped_event)
123122
if "body" in stopped_event:
124123
body = stopped_event["body"]
125124
if "reason" not in body:
@@ -263,46 +262,61 @@ def set_global(self, name, value, id=None):
263262
return self.dap_server.request_setVariable(2, name, str(value), id=id)
264263

265264
def stepIn(
266-
self, threadId=None, targetId=None, waitForStop=True, granularity="statement"
265+
self,
266+
threadId=None,
267+
targetId=None,
268+
waitForStop=True,
269+
granularity="statement",
270+
timeout=timeoutval,
267271
):
268272
response = self.dap_server.request_stepIn(
269273
threadId=threadId, targetId=targetId, granularity=granularity
270274
)
271275
self.assertTrue(response["success"])
272276
if waitForStop:
273-
return self.dap_server.wait_for_stopped()
277+
return self.dap_server.wait_for_stopped(timeout)
274278
return None
275279

276-
def stepOver(self, threadId=None, waitForStop=True, granularity="statement"):
280+
def stepOver(
281+
self,
282+
threadId=None,
283+
waitForStop=True,
284+
granularity="statement",
285+
timeout=timeoutval,
286+
):
277287
self.dap_server.request_next(threadId=threadId, granularity=granularity)
278288
if waitForStop:
279-
return self.dap_server.wait_for_stopped()
289+
return self.dap_server.wait_for_stopped(timeout)
280290
return None
281291

282-
def stepOut(self, threadId=None, waitForStop=True):
292+
def stepOut(self, threadId=None, waitForStop=True, timeout=timeoutval):
283293
self.dap_server.request_stepOut(threadId=threadId)
284294
if waitForStop:
285-
return self.dap_server.wait_for_stopped()
295+
return self.dap_server.wait_for_stopped(timeout)
286296
return None
287297

288-
def continue_to_next_stop(self):
289-
self.dap_server.request_continue()
290-
return self.dap_server.wait_for_stopped()
298+
def verify_continue(self):
299+
resp = self.dap_server.request_continue()
300+
self.assertTrue(resp["success"], f"continue request failed: {resp}")
291301

292-
def continue_to_breakpoints(self, breakpoint_ids):
293-
self.dap_server.request_continue()
294-
self.verify_breakpoint_hit(breakpoint_ids)
302+
def continue_to_next_stop(self, timeout=timeoutval):
303+
self.verify_continue()
304+
return self.dap_server.wait_for_stopped(timeout)
295305

296-
def continue_to_exception_breakpoint(self, filter_label):
297-
self.dap_server.request_continue()
306+
def continue_to_breakpoints(self, breakpoint_ids, timeout=timeoutval):
307+
self.verify_continue()
308+
self.verify_breakpoint_hit(breakpoint_ids, timeout)
309+
310+
def continue_to_exception_breakpoint(self, filter_label, timeout=timeoutval):
311+
self.verify_continue()
298312
self.assertTrue(
299-
self.verify_stop_exception_info(filter_label),
313+
self.verify_stop_exception_info(filter_label, timeout),
300314
'verify we got "%s"' % (filter_label),
301315
)
302316

303-
def continue_to_exit(self, exitCode=0):
304-
self.dap_server.request_continue()
305-
stopped_events = self.dap_server.wait_for_stopped()
317+
def continue_to_exit(self, exitCode=0, timeout=timeoutval):
318+
self.verify_continue()
319+
stopped_events = self.dap_server.wait_for_stopped(timeout)
306320
self.assertEqual(
307321
len(stopped_events), 1, "stopped_events = {}".format(stopped_events)
308322
)
@@ -330,27 +344,15 @@ def disassemble(self, threadId=None, frameIndex=None):
330344

331345
def attach(
332346
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,
347+
/,
343348
stopOnAttach=True,
344349
disconnectAutomatically=True,
345-
terminateCommands=None,
346-
postRunCommands=None,
347-
sourceMap=None,
348350
sourceInitFile=False,
349351
expectFailure=False,
350-
gdbRemotePort=None,
351-
gdbRemoteHostname=None,
352352
sourceBreakpoints=None,
353353
functionBreakpoints=None,
354+
timeout=timeoutval,
355+
**kwargs,
354356
):
355357
"""Build the default Makefile target, create the DAP debug adapter,
356358
and attach to the process.
@@ -367,7 +369,7 @@ def cleanup():
367369
self.addTearDownHook(cleanup)
368370
# Initialize and launch the program
369371
self.dap_server.request_initialize(sourceInitFile)
370-
self.dap_server.wait_for_event("initialized")
372+
self.dap_server.wait_for_event("initialized", timeout)
371373

372374
# Set source breakpoints as part of the launch sequence.
373375
if sourceBreakpoints:
@@ -389,64 +391,28 @@ def cleanup():
389391
)
390392

391393
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-
)
394+
response = self.dap_server.request_attach(stopOnAttach=stopOnAttach, **kwargs)
410395
if expectFailure:
411396
return response
412397
if not (response and response["success"]):
413398
self.assertTrue(
414399
response["success"], "attach failed (%s)" % (response["message"])
415400
)
401+
if stopOnAttach:
402+
self.dap_server.wait_for_stopped(timeout)
416403

417404
def launch(
418405
self,
419406
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,
407+
/,
435408
sourceInitFile=False,
436-
launchCommands=None,
437-
sourceMap=None,
438409
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,
448410
sourceBreakpoints=None,
449411
functionBreakpoints=None,
412+
expectFailure=False,
413+
stopOnEntry=True,
414+
timeout=timeoutval,
415+
**kwargs,
450416
):
451417
"""Sending launch request to dap"""
452418

@@ -462,7 +428,7 @@ def cleanup():
462428

463429
# Initialize and launch the program
464430
self.dap_server.request_initialize(sourceInitFile)
465-
self.dap_server.wait_for_event("initialized")
431+
self.dap_server.wait_for_event("initialized", timeout)
466432

467433
# Set source breakpoints as part of the launch sequence.
468434
if sourceBreakpoints:
@@ -487,115 +453,36 @@ def cleanup():
487453

488454
response = self.dap_server.request_launch(
489455
program,
490-
args=args,
491-
cwd=cwd,
492-
env=env,
493456
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,
457+
**kwargs,
515458
)
516459

517460
if expectFailure:
518461
return response
519-
520462
if not (response and response["success"]):
521463
self.assertTrue(
522464
response["success"],
523465
"launch failed (%s)" % (response["body"]["error"]["format"]),
524466
)
467+
if stopOnEntry:
468+
self.dap_server.wait_for_stopped(timeout)
469+
525470
return response
526471

527472
def build_and_launch(
528473
self,
529474
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,
475+
/,
549476
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,
477+
**kwargs,
560478
):
561479
"""Build the default Makefile target, create the DAP debug adapter,
562480
and launch the process.
563481
"""
564482
self.build_and_create_debug_adapter(lldbDAPEnv)
565483
self.assertTrue(os.path.exists(program), "executable must exist")
566484

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-
)
485+
return self.launch(program, **kwargs)
599486

600487
def getBuiltinDebugServerTool(self):
601488
# Tries to find simulation/lldb-server/gdbserver tool path.

0 commit comments

Comments
 (0)