Skip to content

Commit 5b1378f

Browse files
committed
Fix incorrect interpretation of includeAll
1 parent 2168161 commit 5b1378f

File tree

3 files changed

+64
-33
lines changed

3 files changed

+64
-33
lines changed

lldb/test/API/tools/lldb-dap/extendedStackTrace/TestDAP_extendedStackTrace.py

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
Test lldb-dap stackTrace request with an extended backtrace thread.
33
"""
44

5-
65
import os
76

87
import lldbdap_testcase
@@ -12,11 +11,8 @@
1211

1312

1413
class TestDAP_extendedStackTrace(lldbdap_testcase.DAPTestCaseBase):
15-
@skipUnlessDarwin
16-
def test_stackTrace(self):
17-
"""
18-
Tests the 'stackTrace' packet on a thread with an extended backtrace.
19-
"""
14+
15+
def build_and_run(self, displayExtendedBacktrace=True):
2016
backtrace_recording_lib = findBacktraceRecordingDylib()
2117
if not backtrace_recording_lib:
2218
self.skipTest(
@@ -36,7 +32,7 @@ def test_stackTrace(self):
3632
"DYLD_LIBRARY_PATH=/usr/lib/system/introspection",
3733
"DYLD_INSERT_LIBRARIES=" + backtrace_recording_lib,
3834
],
39-
displayExtendedBacktrace=True,
35+
displayExtendedBacktrace=displayExtendedBacktrace,
4036
)
4137
source = "main.m"
4238
breakpoint = line_number(source, "breakpoint 1")
@@ -47,6 +43,12 @@ def test_stackTrace(self):
4743
len(breakpoint_ids), len(lines), "expect correct number of breakpoints"
4844
)
4945

46+
@skipUnlessDarwin
47+
def test_stackTrace(self):
48+
"""
49+
Tests the 'stackTrace' packet on a thread with an extended backtrace.
50+
"""
51+
self.build_and_run()
5052
events = self.continue_to_next_stop()
5153

5254
stackFrames, totalFrames = self.get_stackFrames_and_totalFramesCount(
@@ -102,3 +104,23 @@ def test_stackTrace(self):
102104
self.assertGreaterEqual(
103105
totalFrames, i, "total frames should include a pagination offset"
104106
)
107+
108+
@skipIfWindows
109+
def test_stackTraceWithFormat(self):
110+
"""
111+
Tests the 'stackTrace' packet on a thread with an extended backtrace using stack trace formats.
112+
"""
113+
self.build_and_run(displayExtendedBacktrace=False)
114+
events = self.continue_to_next_stop()
115+
116+
stackFrames, _ = self.get_stackFrames_and_totalFramesCount(
117+
threadId=events[0]["body"]["threadId"], format={"includeAll": True}
118+
)
119+
120+
stackLabels = [
121+
(i, frame)
122+
for i, frame in enumerate(stackFrames)
123+
if frame.get("presentationHint", "") == "label"
124+
]
125+
126+
self.assertEqual(len(stackLabels), 2, "expected two label stack frames")

lldb/test/API/tools/lldb-dap/stackTrace/TestDAP_stackTrace.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
Test lldb-dap stackTrace request
33
"""
44

5-
65
import os
76

87
import lldbdap_testcase
@@ -230,9 +229,6 @@ def test_StackFrameFormat(self):
230229
self.set_source_breakpoints(source, [line_number(source, "recurse end")])
231230

232231
self.continue_to_next_stop()
233-
frame = self.get_stackFrames(format={"includeAll": True})[0]
234-
self.assertEqual(frame["name"], "a.out main.c:6:5 recurse(x=1)")
235-
236232
frame = self.get_stackFrames(format={"parameters": True})[0]
237233
self.assertEqual(frame["name"], "recurse(x=1)")
238234

lldb/tools/lldb-dap/Handler/StackTraceRequestHandler.cpp

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ static constexpr int StackPageSize = 20;
5151
static bool FillStackFrames(DAP &dap, lldb::SBThread &thread,
5252
lldb::SBFormat &frame_format,
5353
llvm::json::Array &stack_frames, int64_t &offset,
54-
const int64_t start_frame, const int64_t levels) {
54+
const int64_t start_frame, const int64_t levels,
55+
const bool include_all) {
5556
bool reached_end_of_stack = false;
5657
for (int64_t i = start_frame;
5758
static_cast<int64_t>(stack_frames.size()) < levels; i++) {
@@ -71,7 +72,9 @@ static bool FillStackFrames(DAP &dap, lldb::SBThread &thread,
7172
stack_frames.emplace_back(CreateStackFrame(frame, frame_format));
7273
}
7374

74-
if (dap.configuration.displayExtendedBacktrace && reached_end_of_stack) {
75+
const bool include_extended_backtrace =
76+
include_all || dap.configuration.displayExtendedBacktrace;
77+
if (include_extended_backtrace && reached_end_of_stack) {
7578
// Check for any extended backtraces.
7679
for (uint32_t bt = 0;
7780
bt < thread.GetProcess().GetNumExtendedBacktraceTypes(); bt++) {
@@ -82,7 +85,8 @@ static bool FillStackFrames(DAP &dap, lldb::SBThread &thread,
8285

8386
reached_end_of_stack = FillStackFrames(
8487
dap, backtrace, frame_format, stack_frames, offset,
85-
(start_frame - offset) > 0 ? start_frame - offset : -1, levels);
88+
(start_frame - offset) > 0 ? start_frame - offset : -1, levels,
89+
include_all);
8690
if (static_cast<int64_t>(stack_frames.size()) >= levels)
8791
break;
8892
}
@@ -180,44 +184,53 @@ void StackTraceRequestHandler::operator()(
180184
llvm::json::Object body;
181185

182186
lldb::SBFormat frame_format = dap.frame_format;
187+
bool include_all = false;
183188

184189
if (const auto *format = arguments->getObject("format")) {
190+
// Indicates that all stack frames should be included, even those the debug
191+
// adapter might otherwise hide.
192+
include_all = GetBoolean(format, "includeAll").value_or(false);
193+
194+
// Parse the properties that have a corresponding format string.
195+
// FIXME: Support "parameterTypes" and "hex".
196+
const bool module = GetBoolean(format, "module").value_or(false);
197+
const bool line = GetBoolean(format, "line").value_or(false);
185198
const bool parameters = GetBoolean(format, "parameters").value_or(false);
186199
const bool parameter_names =
187200
GetBoolean(format, "parameterNames").value_or(false);
188201
const bool parameter_values =
189202
GetBoolean(format, "parameterValues").value_or(false);
190-
const bool line = GetBoolean(format, "line").value_or(false);
191-
const bool module = GetBoolean(format, "module").value_or(false);
192-
const bool include_all = GetBoolean(format, "includeAll").value_or(false);
193203

194-
std::string format_str;
195-
llvm::raw_string_ostream os(format_str);
204+
// Only change the format string if we have to.
205+
if (module || line || parameters || parameter_names || parameter_values) {
206+
std::string format_str;
207+
llvm::raw_string_ostream os(format_str);
196208

197-
if (include_all || module)
198-
os << "{${module.file.basename} }";
209+
if (module)
210+
os << "{${module.file.basename} }";
199211

200-
if (include_all || line)
201-
os << "{${line.file.basename}:${line.number}:${line.column} }";
212+
if (line)
213+
os << "{${line.file.basename}:${line.number}:${line.column} }";
202214

203-
if (include_all || parameters || parameter_names || parameter_values)
204-
os << "{${function.name-with-args}}";
205-
else
206-
os << "{${function.name-without-args}}";
215+
if (parameters || parameter_names || parameter_values)
216+
os << "{${function.name-with-args}}";
217+
else
218+
os << "{${function.name-without-args}}";
207219

208-
lldb::SBError error;
209-
frame_format = lldb::SBFormat(format_str.c_str(), error);
210-
assert(error.Success());
220+
lldb::SBError error;
221+
frame_format = lldb::SBFormat(format_str.c_str(), error);
222+
assert(error.Success());
223+
}
211224
}
212225

213226
if (thread.IsValid()) {
214227
const auto start_frame =
215228
GetInteger<uint64_t>(arguments, "startFrame").value_or(0);
216229
const auto levels = GetInteger<uint64_t>(arguments, "levels").value_or(0);
217230
int64_t offset = 0;
218-
bool reached_end_of_stack =
219-
FillStackFrames(dap, thread, frame_format, stack_frames, offset,
220-
start_frame, levels == 0 ? INT64_MAX : levels);
231+
bool reached_end_of_stack = FillStackFrames(
232+
dap, thread, frame_format, stack_frames, offset, start_frame,
233+
levels == 0 ? INT64_MAX : levels, include_all);
221234
body.try_emplace("totalFrames",
222235
start_frame + stack_frames.size() +
223236
(reached_end_of_stack ? 0 : StackPageSize));

0 commit comments

Comments
 (0)