Skip to content

Commit 9c6de5b

Browse files
committed
[Dexter] Work around flaky LLDB DAP stackTrace response
Buildbot cross-project-tests-sie-ubuntu sees sporadic test failures due to missing "stackTrace" "source" "path". The "path" field is optional for "source" according to DAP, so it's well formed. It works _most_ of the time, and doesn't consistently fail for any one test which is all strangely inconsistent. I can't replicate the failure locally after running the feature_tests in a loop for 3 hours, and haven't been able to work out why the "source" is sometimes missing by just looking at LLDB code. So, instead, here is a plaster that I am hoping will improve bot consistency. Attempt to get the stack frames with source paths 3 times before giving up. It would be ideal if we didn't need to do any of this. I think `_post_step_hook` could be removed if the behaviour in gh#156650 was fixed/changed.
1 parent 22fb21a commit 9c6de5b

File tree

1 file changed

+31
-11
lines changed
  • cross-project-tests/debuginfo-tests/dexter/dex/debugger/lldb

1 file changed

+31
-11
lines changed

cross-project-tests/debuginfo-tests/dexter/dex/debugger/lldb/LLDB.py

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import shlex
1212
from subprocess import CalledProcessError, check_output, STDOUT
1313
import sys
14+
import time
1415

1516
from dex.debugger.DebuggerBase import DebuggerBase, watch_is_active
1617
from dex.debugger.DAP import DAP
@@ -419,20 +420,39 @@ def frames_below_main(self):
419420
"_start",
420421
]
421422

423+
def _get_current_path_and_addr(self):
424+
trace_req_id = self.send_message(
425+
self.make_request(
426+
"stackTrace", {"threadId": self._debugger_state.thread, "levels": 1}
427+
)
428+
)
429+
trace_response = self._await_response(trace_req_id)
430+
if not trace_response["success"]:
431+
raise DebuggerException("failed to get stack frames")
432+
stackframes = trace_response["body"]["stackFrames"]
433+
path = stackframes[0]["source"]["path"]
434+
addr = stackframes[0]["instructionPointerReference"]
435+
return (path, addr)
436+
422437
def _post_step_hook(self):
423438
"""Hook to be executed after completing a step request."""
424439
if self._debugger_state.stopped_reason == "step":
425-
trace_req_id = self.send_message(
426-
self.make_request(
427-
"stackTrace", {"threadId": self._debugger_state.thread, "levels": 1}
428-
)
429-
)
430-
trace_response = self._await_response(trace_req_id)
431-
if not trace_response["success"]:
432-
raise DebuggerException("failed to get stack frames")
433-
stackframes = trace_response["body"]["stackFrames"]
434-
path = stackframes[0]["source"]["path"]
435-
addr = stackframes[0]["instructionPointerReference"]
440+
# Buildbot cross-project-tests-sie-ubuntu sees sporadic test
441+
# failures due to missing stackFrames[0].source.path. The "path"
442+
# field is optional for "source" according to DAP, so it's not
443+
# ill-formed. But it works most of the time, and doesn't
444+
# consistently fail for any one test. Attempt to get the stack
445+
# frames with source paths 3 times before giving up.
446+
# FIXME: It would be ideal if we didn't need to do any of this.
447+
# This entire function could be removed if gh#156650 gets resolved.
448+
for attempt in range(1, 3):
449+
try:
450+
path, addr = self._get_current_path_and_addr()
451+
except KeyError as e:
452+
if attempt == 3:
453+
raise e
454+
time.sleep(0.1)
455+
436456
if any(
437457
self._debugger_state.bp_addr_map.get(self.dex_id_to_dap_id[dex_bp_id])
438458
== addr

0 commit comments

Comments
 (0)