Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 087a5d2

Browse filesBrowse files
authored
[lldb-dap] Adding additional asserts to unit tests. (#140107)
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 6ebb848 commit 087a5d2
Copy full SHA for 087a5d2

File tree

20 files changed

+365
-429
lines changed
Filter options

20 files changed

+365
-429
lines changed

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

Copy file name to clipboardExpand all lines: lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+160-134
Large diffs are not rendered by default.

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

Copy file name to clipboardExpand all lines: lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
+71-175
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22
import time
3+
from typing import Optional
34
import uuid
45

56
import dap_server
@@ -11,10 +12,14 @@
1112
class 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

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.