[Lldb-commits] [lldb] [lldb-dap] Support StackFrameFormat (PR #137113)
via lldb-commits
lldb-commits at lists.llvm.org
Wed Apr 23 20:11:00 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
Author: Jonas Devlieghere (JDevlieghere)
<details>
<summary>Changes</summary>
The debug adapter protocol supports an option to provide formatting information for a stack frames as part of the StackTrace request. lldb-dap incorrectly advertises it supports this, but until this PR that support wasn't actually implemented.
Fixes #<!-- -->137057
---
Full diff: https://github.com/llvm/llvm-project/pull/137113.diff
4 Files Affected:
- (modified) lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py (+3-1)
- (modified) lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py (+14-4)
- (modified) lldb/test/API/tools/lldb-dap/stackTrace/TestDAP_stackTrace.py (+30)
- (modified) lldb/tools/lldb-dap/Handler/StackTraceRequestHandler.cpp (+37-5)
``````````diff
diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index a9915ba2f6de6..dadf6b1f8774c 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -1046,7 +1046,7 @@ def request_modules(self):
return self.send_recv({"command": "modules", "type": "request"})
def request_stackTrace(
- self, threadId=None, startFrame=None, levels=None, dump=False
+ self, threadId=None, startFrame=None, levels=None, format=None, dump=False
):
if threadId is None:
threadId = self.get_thread_id()
@@ -1055,6 +1055,8 @@ def request_stackTrace(
args_dict["startFrame"] = startFrame
if levels is not None:
args_dict["levels"] = levels
+ if format is not None:
+ args_dict["format"] = format
command_dict = {
"command": "stackTrace",
"type": "request",
diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
index 70b04b051e0ec..b5b55b336d535 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
@@ -161,10 +161,14 @@ def get_dict_value(self, d, key_path):
return value
def get_stackFrames_and_totalFramesCount(
- self, threadId=None, startFrame=None, levels=None, dump=False
+ self, threadId=None, startFrame=None, levels=None, format=None, dump=False
):
response = self.dap_server.request_stackTrace(
- threadId=threadId, startFrame=startFrame, levels=levels, dump=dump
+ threadId=threadId,
+ startFrame=startFrame,
+ levels=levels,
+ format=format,
+ dump=dump,
)
if response:
stackFrames = self.get_dict_value(response, ["body", "stackFrames"])
@@ -177,9 +181,15 @@ def get_stackFrames_and_totalFramesCount(
return (stackFrames, totalFrames)
return (None, 0)
- def get_stackFrames(self, threadId=None, startFrame=None, levels=None, dump=False):
+ def get_stackFrames(
+ self, threadId=None, startFrame=None, levels=None, format=None, dump=False
+ ):
(stackFrames, totalFrames) = self.get_stackFrames_and_totalFramesCount(
- threadId=threadId, startFrame=startFrame, levels=levels, dump=dump
+ threadId=threadId,
+ startFrame=startFrame,
+ levels=levels,
+ format=format,
+ dump=dump,
)
return stackFrames
diff --git a/lldb/test/API/tools/lldb-dap/stackTrace/TestDAP_stackTrace.py b/lldb/test/API/tools/lldb-dap/stackTrace/TestDAP_stackTrace.py
index 56ed1ebdf7ab4..713b5d841cfcd 100644
--- a/lldb/test/API/tools/lldb-dap/stackTrace/TestDAP_stackTrace.py
+++ b/lldb/test/API/tools/lldb-dap/stackTrace/TestDAP_stackTrace.py
@@ -217,3 +217,33 @@ def test_functionNameWithArgs(self):
self.continue_to_next_stop()
frame = self.get_stackFrames()[0]
self.assertEqual(frame["name"], "recurse(x=1)")
+
+ @skipIfWindows
+ def test_StackFrameFormat(self):
+ """
+ Test the StackFrameFormat.
+ """
+ program = self.getBuildArtifact("a.out")
+ self.build_and_launch(program)
+ source = "main.c"
+
+ self.set_source_breakpoints(source, [line_number(source, "recurse end")])
+
+ self.continue_to_next_stop()
+ frame = self.get_stackFrames(format={"includeAll": True})[0]
+ self.assertEqual(frame["name"], "a.out main.c:6:5 recurse(x=1)")
+
+ frame = self.get_stackFrames(format={"parameters": True})[0]
+ self.assertEqual(frame["name"], "recurse(x=1)")
+
+ frame = self.get_stackFrames(format={"parameterNames": True})[0]
+ self.assertEqual(frame["name"], "recurse(x=1)")
+
+ frame = self.get_stackFrames(format={"parameterValues": True})[0]
+ self.assertEqual(frame["name"], "recurse(x=1)")
+
+ frame = self.get_stackFrames(format={"parameters": False, "line": True})[0]
+ self.assertEqual(frame["name"], "main.c:6:5 recurse")
+
+ frame = self.get_stackFrames(format={"parameters": False, "module": True})[0]
+ self.assertEqual(frame["name"], "a.out recurse")
diff --git a/lldb/tools/lldb-dap/Handler/StackTraceRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/StackTraceRequestHandler.cpp
index a58e3325af100..359237f1db0b4 100644
--- a/lldb/tools/lldb-dap/Handler/StackTraceRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/StackTraceRequestHandler.cpp
@@ -49,6 +49,7 @@ static constexpr int StackPageSize = 20;
//
// s=3,l=3 = [th0->s3, label1, th1->s0]
static bool FillStackFrames(DAP &dap, lldb::SBThread &thread,
+ lldb::SBFormat &frame_format,
llvm::json::Array &stack_frames, int64_t &offset,
const int64_t start_frame, const int64_t levels) {
bool reached_end_of_stack = false;
@@ -56,7 +57,7 @@ static bool FillStackFrames(DAP &dap, lldb::SBThread &thread,
static_cast<int64_t>(stack_frames.size()) < levels; i++) {
if (i == -1) {
stack_frames.emplace_back(
- CreateExtendedStackFrameLabel(thread, dap.frame_format));
+ CreateExtendedStackFrameLabel(thread, frame_format));
continue;
}
@@ -67,7 +68,7 @@ static bool FillStackFrames(DAP &dap, lldb::SBThread &thread,
break;
}
- stack_frames.emplace_back(CreateStackFrame(frame, dap.frame_format));
+ stack_frames.emplace_back(CreateStackFrame(frame, frame_format));
}
if (dap.configuration.displayExtendedBacktrace && reached_end_of_stack) {
@@ -80,7 +81,7 @@ static bool FillStackFrames(DAP &dap, lldb::SBThread &thread,
continue;
reached_end_of_stack = FillStackFrames(
- dap, backtrace, stack_frames, offset,
+ dap, backtrace, frame_format, stack_frames, offset,
(start_frame - offset) > 0 ? start_frame - offset : -1, levels);
if (static_cast<int64_t>(stack_frames.size()) >= levels)
break;
@@ -178,14 +179,45 @@ void StackTraceRequestHandler::operator()(
llvm::json::Array stack_frames;
llvm::json::Object body;
+ lldb::SBFormat frame_format = dap.frame_format;
+
+ if (const auto *format = arguments->getObject("format")) {
+ const bool parameters = GetBoolean(format, "parameters").value_or(false);
+ const bool parameter_names =
+ GetBoolean(format, "parameterNames").value_or(false);
+ const bool parameter_values =
+ GetBoolean(format, "parameterValues").value_or(false);
+ const bool line = GetBoolean(format, "line").value_or(false);
+ const bool module = GetBoolean(format, "module").value_or(false);
+ const bool include_all = GetBoolean(format, "includeAll").value_or(false);
+
+ std::string format_str;
+ llvm::raw_string_ostream os(format_str);
+
+ if (include_all || module)
+ os << "{${module.file.basename} }";
+
+ if (include_all || line)
+ os << "{${line.file.basename}:${line.number}:${line.column} }";
+
+ if (include_all || parameters || parameter_names || parameter_values)
+ os << "{${function.name-with-args}}";
+ else
+ os << "{${function.name-without-args}}";
+
+ lldb::SBError error;
+ frame_format = lldb::SBFormat(format_str.c_str(), error);
+ assert(error.Success());
+ }
+
if (thread.IsValid()) {
const auto start_frame =
GetInteger<uint64_t>(arguments, "startFrame").value_or(0);
const auto levels = GetInteger<uint64_t>(arguments, "levels").value_or(0);
int64_t offset = 0;
bool reached_end_of_stack =
- FillStackFrames(dap, thread, stack_frames, offset, start_frame,
- levels == 0 ? INT64_MAX : levels);
+ FillStackFrames(dap, thread, frame_format, stack_frames, offset,
+ start_frame, levels == 0 ? INT64_MAX : levels);
body.try_emplace("totalFrames",
start_frame + stack_frames.size() +
(reached_end_of_stack ? 0 : StackPageSize));
``````````
</details>
https://github.com/llvm/llvm-project/pull/137113
More information about the lldb-commits
mailing list