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 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits