[Lldb-commits] [lldb] Allow option to ignore module load errors in ScriptedProcess (PR #127153)
https://github.com/rchamala edited https://github.com/llvm/llvm-project/pull/127153 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Move requests into their own object/file (PR #128262)
https://github.com/ashgti approved this pull request. https://github.com/llvm/llvm-project/pull/128262 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add DIL code for handling plain variable names. (PR #120971)
https://github.com/cmtice edited https://github.com/llvm/llvm-project/pull/120971 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Refactor request handlers (NFC) (PR #128262)
https://github.com/JDevlieghere edited https://github.com/llvm/llvm-project/pull/128262 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Refactor request handlers (NFC) (PR #128262)
https://github.com/JDevlieghere closed https://github.com/llvm/llvm-project/pull/128262 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add DIL code for handling plain variable names. (PR #120971)
cmtice wrote: I've addressed most of the review comments now. I have not done the format_provider requests (waiting for response to questions) nor the bit about the DIagnosticManager. I haven't removed the code to look up global variables, but I think I may have fixed the main objection (it now uses StackFrame::GetInScopeVariableList rather than FindGlobalVariables). https://github.com/llvm/llvm-project/pull/120971 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Add 'source' references to stack frames without source files. (PR #128268)
labath wrote: Could we make the test self contained (i.e. without the qsort reference)? If all you need is a function without debug info, then `__attribute__((nodebug))` should suffice. https://github.com/llvm/llvm-project/pull/128268 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Allow option to ignore module load errors in ScriptedProcess (PR #127153)
https://github.com/rchamala updated https://github.com/llvm/llvm-project/pull/127153 >From a4fdb2d54e76aefb771fe8ad8399494bb5fa8b70 Mon Sep 17 00:00:00 2001 From: rchamala Date: Thu, 13 Feb 2025 15:00:37 -0800 Subject: [PATCH 1/5] Allow option to ignore module load errors in ScriptedProcess --- .../Process/scripted/ScriptedProcess.cpp | 39 .../TestStackCoreScriptedProcess.py | 15 - .../stack_core_scripted_process.py| 60 ++- 3 files changed, 85 insertions(+), 29 deletions(-) diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp index d2111ce877ce5..79d0bc51bc18c 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp +++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp @@ -165,7 +165,7 @@ Status ScriptedProcess::DoLoadCore() { Status ScriptedProcess::DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) { LLDB_LOGF(GetLog(LLDBLog::Process), "ScriptedProcess::%s launching process", __FUNCTION__); - + /* MARK: This doesn't reflect how lldb actually launches a process. In reality, it attaches to debugserver, then resume the process. That's not true in all cases. If debugserver is remote, lldb @@ -422,9 +422,11 @@ bool ScriptedProcess::GetProcessInfo(ProcessInstanceInfo &info) { lldb_private::StructuredData::ObjectSP ScriptedProcess::GetLoadedDynamicLibrariesInfos() { Status error; - auto error_with_message = [&error](llvm::StringRef message) { -return ScriptedInterface::ErrorWithMessage(LLVM_PRETTY_FUNCTION, - message.data(), error); + auto handle_error_with_message = [&error](llvm::StringRef message, +bool ignore_error) { +ScriptedInterface::ErrorWithMessage(LLVM_PRETTY_FUNCTION, + message.data(), error); +return ignore_error; }; StructuredData::ArraySP loaded_images_sp = GetInterface().GetLoadedImages(); @@ -436,12 +438,13 @@ ScriptedProcess::GetLoadedDynamicLibrariesInfos() { ModuleList module_list; Target &target = GetTarget(); - auto reload_image = [&target, &module_list, &error_with_message]( + auto reload_image = [&target, &module_list, &handle_error_with_message]( StructuredData::Object *obj) -> bool { StructuredData::Dictionary *dict = obj->GetAsDictionary(); if (!dict) - return error_with_message("Couldn't cast image object into dictionary."); + return handle_error_with_message( + "Couldn't cast image object into dictionary.", false); ModuleSpec module_spec; llvm::StringRef value; @@ -449,9 +452,11 @@ ScriptedProcess::GetLoadedDynamicLibrariesInfos() { bool has_path = dict->HasKey("path"); bool has_uuid = dict->HasKey("uuid"); if (!has_path && !has_uuid) - return error_with_message("Dictionary should have key 'path' or 'uuid'"); + return handle_error_with_message( + "Dictionary should have key 'path' or 'uuid'", false); if (!dict->HasKey("load_addr")) - return error_with_message("Dictionary is missing key 'load_addr'"); + return handle_error_with_message("Dictionary is missing key 'load_addr'", + false); if (has_path) { dict->GetValueForKeyAsString("path", value); @@ -467,16 +472,21 @@ ScriptedProcess::GetLoadedDynamicLibrariesInfos() { ModuleSP module_sp = target.GetOrCreateModule(module_spec, true /* notify */); +bool ignore_module_load_error = false; +dict->GetValueForKeyAsBoolean("ignore_module_load_error", + ignore_module_load_error); if (!module_sp) - return error_with_message("Couldn't create or get module."); + return handle_error_with_message("Couldn't create or get module.", + ignore_module_load_error); lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; lldb::offset_t slide = LLDB_INVALID_OFFSET; dict->GetValueForKeyAsInteger("load_addr", load_addr); dict->GetValueForKeyAsInteger("slide", slide); if (load_addr == LLDB_INVALID_ADDRESS) - return error_with_message( - "Couldn't get valid load address or slide offset."); + return handle_error_with_message( + "Couldn't get valid load address or slide offset.", + ignore_module_load_error); if (slide != LLDB_INVALID_OFFSET) load_addr += slide; @@ -486,13 +496,16 @@ ScriptedProcess::GetLoadedDynamicLibrariesInfos() { changed); if (!changed && !module_sp->GetObjectFile()) - return error_with_message("Couldn't set the load address for module."); + return handle_error_with_message( + "Couldn't set the load address for module.", +
[Lldb-commits] [lldb] 2ff3b18 - Allow option to ignore module load errors in ScriptedProcess (#127153)
Author: rchamala Date: 2025-02-23T00:51:43-08:00 New Revision: 2ff3b18554b115b17d5085b9a4cd779eeafd278a URL: https://github.com/llvm/llvm-project/commit/2ff3b18554b115b17d5085b9a4cd779eeafd278a DIFF: https://github.com/llvm/llvm-project/commit/2ff3b18554b115b17d5085b9a4cd779eeafd278a.diff LOG: Allow option to ignore module load errors in ScriptedProcess (#127153) Current state in scripted process expects [all the modules](https://github.com/llvm/llvm-project/blob/912b154f3a3f8c3cebf5cc5731fd8b0749762da5/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp#L498) passed into "get_loaded_images" to load successfully else none of them load. Even if a module loads fine, [but has already been appended](https://github.com/llvm/llvm-project/blob/912b154f3a3f8c3cebf5cc5731fd8b0749762da5/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp#L495) it still fails. This is restrictive and does not help our usecase. **Usecase**: We have a parent scripted process using coredump + tombstone. 1) Scripted process uses child elf-core process to read memory dump 2) Uses tombstones to pass thread names and modules. We do not know whether the modules will be successfully downloaded before creating the scripted process. We use [python module callbacks](https://github.com/llvm/llvm-project/blob/a57e58dbfaae0e86eb5cafeddf8b598f14b96e36/lldb/source/Target/Platform.cpp#L1593) to download a module from symbol server at LLDB load time when the scripted process is being created. The issue is that if one of the symbol is not found from the list specified in tombstone, none of the modules load in scripted process. Even if we ensure symbols are present in symbol server before creating the scripted process, if the load address is wrong or if the module is already appended, all module loads are skipped. **Solution**: Pass in a custom boolean option arg for every module from python scripted process plugin which will indicate whether to ignore the module load error. This will provide the flexibility to user for loading the successfully fetched modules into target while ignoring the failed ones - Co-authored-by: rchamala Added: Modified: lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp lldb/test/API/functionalities/scripted_process/TestStackCoreScriptedProcess.py lldb/test/API/functionalities/scripted_process/stack_core_scripted_process.py Removed: diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp index d2111ce877ce5..6b371a151668d 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp +++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp @@ -25,6 +25,8 @@ #include "lldb/Utility/ScriptedMetadata.h" #include "lldb/Utility/State.h" +#include "Plugins/ObjectFile/Placeholder/ObjectFilePlaceholder.h" + #include LLDB_PLUGIN_DEFINE(ScriptedProcess) @@ -165,7 +167,7 @@ Status ScriptedProcess::DoLoadCore() { Status ScriptedProcess::DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) { LLDB_LOGF(GetLog(LLDBLog::Process), "ScriptedProcess::%s launching process", __FUNCTION__); - + /* MARK: This doesn't reflect how lldb actually launches a process. In reality, it attaches to debugserver, then resume the process. That's not true in all cases. If debugserver is remote, lldb @@ -444,7 +446,6 @@ ScriptedProcess::GetLoadedDynamicLibrariesInfos() { return error_with_message("Couldn't cast image object into dictionary."); ModuleSpec module_spec; -llvm::StringRef value; bool has_path = dict->HasKey("path"); bool has_uuid = dict->HasKey("uuid"); @@ -453,22 +454,17 @@ ScriptedProcess::GetLoadedDynamicLibrariesInfos() { if (!dict->HasKey("load_addr")) return error_with_message("Dictionary is missing key 'load_addr'"); +llvm::StringRef path = ""; if (has_path) { - dict->GetValueForKeyAsString("path", value); - module_spec.GetFileSpec().SetPath(value); + dict->GetValueForKeyAsString("path", path); + module_spec.GetFileSpec().SetPath(path); } +llvm::StringRef uuid = ""; if (has_uuid) { - dict->GetValueForKeyAsString("uuid", value); - module_spec.GetUUID().SetFromStringRef(value); + dict->GetValueForKeyAsString("uuid", uuid); + module_spec.GetUUID().SetFromStringRef(uuid); } -module_spec.GetArchitecture() = target.GetArchitecture(); - -ModuleSP module_sp = -target.GetOrCreateModule(module_spec, true /* notify */); - -if (!module_sp) - return error_with_message("Couldn't create or get module."); lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; lldb::offset_t slide = LLDB_INVALID_OFFSET; @@ -481,6 +477,27 @@ ScriptedProcess::GetLoadedDynamicLibrariesInfos() { if (slide != LLDB_INVALID_
[Lldb-commits] [lldb] Allow option to ignore module load errors in ScriptedProcess (PR #127153)
https://github.com/rchamala closed https://github.com/llvm/llvm-project/pull/127153 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add DIL code for handling plain variable names. (PR #120971)
@@ -0,0 +1,308 @@ +//===-- DILParser.cpp -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// This implements the recursive descent parser for the Data Inspection +// Language (DIL), and its helper functions, which will eventually underlie the +// 'frame variable' command. The language that this parser recognizes is +// described in lldb/docs/dil-expr-lang.ebnf +// +//===--===// + +#include "lldb/ValueObject/DILParser.h" +#include "lldb/Target/ExecutionContextScope.h" +#include "lldb/ValueObject/DILAST.h" +#include "lldb/ValueObject/DILEval.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/FormatAdapters.h" +#include +#include +#include +#include +#include + +namespace lldb_private::dil { + +inline void TokenKindsJoinImpl(std::ostringstream &os, Token::Kind k) { + os << "'" << Token::GetTokenName(k).str() << "'"; +} + +template +inline void TokenKindsJoinImpl(std::ostringstream &os, Token::Kind k, + Ts... ks) { + TokenKindsJoinImpl(os, k); + os << ", "; + TokenKindsJoinImpl(os, ks...); +} + +template +inline std::string TokenKindsJoin(Token::Kind k, Ts... ks) { + std::ostringstream os; + TokenKindsJoinImpl(os, k, ks...); + + return os.str(); +} + +std::string FormatDiagnostics(llvm::StringRef text, const std::string &message, + uint32_t loc) { + // Get the source buffer and the location of the current token. + size_t loc_offset = (size_t)loc; + + // Look for the start of the line. + size_t line_start = text.rfind('\n', loc_offset); + line_start = line_start == llvm::StringRef::npos ? 0 : line_start + 1; + + // Look for the end of the line. + size_t line_end = text.find('\n', loc_offset); + line_end = line_end == llvm::StringRef::npos ? text.size() : line_end; + + // Get a view of the current line in the source code and the position of the + // diagnostics pointer. + llvm::StringRef line = text.slice(line_start, line_end); + int32_t arrow = loc + 1; // Column offset starts at 1, not 0. + + // Calculate the padding in case we point outside of the expression (this can + // happen if the parser expected something, but got EOF).˚ + size_t expr_rpad = std::max(0, arrow - static_cast(line.size())); + size_t arrow_rpad = std::max(0, static_cast(line.size()) - arrow); + + return llvm::formatv(": {1}\n{2}\n{3}", loc, message, + llvm::fmt_pad(line, 0, expr_rpad), + llvm::fmt_pad("^", arrow - 1, arrow_rpad)); +} + +DILParser::DILParser(llvm::StringRef dil_input_expr, DILLexer lexer, + std::shared_ptr exe_ctx_scope, + lldb::DynamicValueType use_dynamic, bool use_synthetic, + bool fragile_ivar, bool check_ptr_vs_member) +: m_ctx_scope(exe_ctx_scope), m_input_expr(dil_input_expr), + m_dil_lexer(lexer), m_dil_token(lexer.GetCurrentToken()), + m_use_dynamic(use_dynamic), m_use_synthetic(use_synthetic), + m_fragile_ivar(fragile_ivar), m_check_ptr_vs_member(check_ptr_vs_member) { +} + +llvm::Expected DILParser::Run() { + DILASTNodeUP expr; + + expr = ParseExpression(); + + Expect(Token::Kind::eof); + + if (m_error.Fail()) +return m_error.ToError(); + + return expr; +} + +// Parse an expression. +// +// expression: +//primary_expression +// +DILASTNodeUP DILParser::ParseExpression() { return ParsePrimaryExpression(); } + +// Parse a primary_expression. +// +// primary_expression: +//id_expression +//"this" +//"(" expression ")" +// +DILASTNodeUP DILParser::ParsePrimaryExpression() { + if (m_dil_token.IsOneOf(Token::coloncolon, Token::identifier)) { +// Save the source location for the diagnostics message. +uint32_t loc = m_dil_token.GetLocation(); +auto identifier = ParseIdExpression(); + +return std::make_unique(loc, identifier, m_use_dynamic, +m_ctx_scope); + } else if (m_dil_token.Is(Token::l_paren)) { +ConsumeToken(); +auto expr = ParseExpression(); +Expect(Token::r_paren); +ConsumeToken(); +return expr; + } + + BailOut(ErrorCode::kInvalidExpressionSyntax, + llvm::formatv("Unexpected token: {0}", TokenDescription(m_dil_token)), + m_dil_token.GetLocation()); + return std::make_unique(); +} + +// Parse nested_name_specifier. +// +// nested_name_specifier: +//type_name "::" +//namespace_name "::" +//nested_name_specifier identifier "::" +// +std::string DILParser::ParseNestedNameSpecifier() { + // The first token in nested_name_specifier is always an identifier, or + // '(anonymous namespace)'. + if (m_dil_token.IsNot(Token::identifier) && + m_dil_toke
[Lldb-commits] [lldb] [lldb-dap] Refactor request handlers (NFC) (PR #128262)
https://github.com/JDevlieghere edited https://github.com/llvm/llvm-project/pull/128262 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add DIL code for handling plain variable names. (PR #120971)
@@ -0,0 +1,308 @@ +//===-- DILParser.cpp -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// This implements the recursive descent parser for the Data Inspection +// Language (DIL), and its helper functions, which will eventually underlie the +// 'frame variable' command. The language that this parser recognizes is +// described in lldb/docs/dil-expr-lang.ebnf +// +//===--===// + +#include "lldb/ValueObject/DILParser.h" +#include "lldb/Target/ExecutionContextScope.h" +#include "lldb/ValueObject/DILAST.h" +#include "lldb/ValueObject/DILEval.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/FormatAdapters.h" +#include +#include +#include +#include +#include + +namespace lldb_private::dil { + +inline void TokenKindsJoinImpl(std::ostringstream &os, Token::Kind k) { + os << "'" << Token::GetTokenName(k).str() << "'"; +} + +template +inline void TokenKindsJoinImpl(std::ostringstream &os, Token::Kind k, + Ts... ks) { + TokenKindsJoinImpl(os, k); + os << ", "; + TokenKindsJoinImpl(os, ks...); +} + +template +inline std::string TokenKindsJoin(Token::Kind k, Ts... ks) { + std::ostringstream os; + TokenKindsJoinImpl(os, k, ks...); + + return os.str(); +} + +std::string FormatDiagnostics(llvm::StringRef text, const std::string &message, + uint32_t loc) { + // Get the source buffer and the location of the current token. + size_t loc_offset = (size_t)loc; + + // Look for the start of the line. + size_t line_start = text.rfind('\n', loc_offset); + line_start = line_start == llvm::StringRef::npos ? 0 : line_start + 1; + + // Look for the end of the line. + size_t line_end = text.find('\n', loc_offset); + line_end = line_end == llvm::StringRef::npos ? text.size() : line_end; + + // Get a view of the current line in the source code and the position of the + // diagnostics pointer. + llvm::StringRef line = text.slice(line_start, line_end); + int32_t arrow = loc + 1; // Column offset starts at 1, not 0. + + // Calculate the padding in case we point outside of the expression (this can + // happen if the parser expected something, but got EOF).˚ + size_t expr_rpad = std::max(0, arrow - static_cast(line.size())); + size_t arrow_rpad = std::max(0, static_cast(line.size()) - arrow); + + return llvm::formatv(": {1}\n{2}\n{3}", loc, message, + llvm::fmt_pad(line, 0, expr_rpad), + llvm::fmt_pad("^", arrow - 1, arrow_rpad)); +} + +DILParser::DILParser(llvm::StringRef dil_input_expr, DILLexer lexer, + std::shared_ptr exe_ctx_scope, + lldb::DynamicValueType use_dynamic, bool use_synthetic, + bool fragile_ivar, bool check_ptr_vs_member) +: m_ctx_scope(exe_ctx_scope), m_input_expr(dil_input_expr), + m_dil_lexer(lexer), m_dil_token(lexer.GetCurrentToken()), + m_use_dynamic(use_dynamic), m_use_synthetic(use_synthetic), + m_fragile_ivar(fragile_ivar), m_check_ptr_vs_member(check_ptr_vs_member) { +} + +llvm::Expected DILParser::Run() { + DILASTNodeUP expr; + + expr = ParseExpression(); + + Expect(Token::Kind::eof); + + if (m_error.Fail()) +return m_error.ToError(); + + return expr; +} + +// Parse an expression. +// +// expression: +//primary_expression +// +DILASTNodeUP DILParser::ParseExpression() { return ParsePrimaryExpression(); } + +// Parse a primary_expression. +// +// primary_expression: +//id_expression +//"this" +//"(" expression ")" +// +DILASTNodeUP DILParser::ParsePrimaryExpression() { + if (m_dil_token.IsOneOf(Token::coloncolon, Token::identifier)) { +// Save the source location for the diagnostics message. +uint32_t loc = m_dil_token.GetLocation(); +auto identifier = ParseIdExpression(); + +return std::make_unique(loc, identifier, m_use_dynamic, +m_ctx_scope); + } else if (m_dil_token.Is(Token::l_paren)) { +ConsumeToken(); +auto expr = ParseExpression(); +Expect(Token::r_paren); +ConsumeToken(); +return expr; + } + + BailOut(ErrorCode::kInvalidExpressionSyntax, + llvm::formatv("Unexpected token: {0}", TokenDescription(m_dil_token)), + m_dil_token.GetLocation()); + return std::make_unique(); +} + +// Parse nested_name_specifier. +// +// nested_name_specifier: +//type_name "::" +//namespace_name "::" +//nested_name_specifier identifier "::" +// +std::string DILParser::ParseNestedNameSpecifier() { + // The first token in nested_name_specifier is always an identifier, or + // '(anonymous namespace)'. + if (m_dil_token.IsNot(Token::identifier) && + m_dil_toke
[Lldb-commits] [lldb] [lldb-dap] Refactor stepping related request handlers (NFC) (PR #128453)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Jonas Devlieghere (JDevlieghere) Changes Continuation of the work started in #128262. --- Patch is 32.82 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/128453.diff 8 Files Affected: - (modified) lldb/tools/lldb-dap/CMakeLists.txt (+4) - (added) lldb/tools/lldb-dap/Handler/NextRequestHandler.cpp (+79) - (modified) lldb/tools/lldb-dap/Handler/RequestHandler.cpp (+7) - (modified) lldb/tools/lldb-dap/Handler/RequestHandler.h (+32-1) - (added) lldb/tools/lldb-dap/Handler/StepInRequestHandler.cpp (+96) - (added) lldb/tools/lldb-dap/Handler/StepInTargetsRequestHandler.cpp (+149) - (added) lldb/tools/lldb-dap/Handler/StepOutRequestHandler.cpp (+68) - (modified) lldb/tools/lldb-dap/lldb-dap.cpp (+5-339) ``diff diff --git a/lldb/tools/lldb-dap/CMakeLists.txt b/lldb/tools/lldb-dap/CMakeLists.txt index 73762af5c2fd7..61271e1a9f2a6 100644 --- a/lldb/tools/lldb-dap/CMakeLists.txt +++ b/lldb/tools/lldb-dap/CMakeLists.txt @@ -47,8 +47,12 @@ add_lldb_tool(lldb-dap Handler/ExceptionInfoRequestHandler.cpp Handler/InitializeRequestHandler.cpp Handler/LaunchRequestHandler.cpp + Handler/NextRequestHandler.cpp Handler/RequestHandler.cpp Handler/RestartRequestHandler.cpp + Handler/StepInRequestHandler.cpp + Handler/StepInTargetsRequestHandler.cpp + Handler/StepOutRequestHandler.cpp LINK_LIBS liblldb diff --git a/lldb/tools/lldb-dap/Handler/NextRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/NextRequestHandler.cpp new file mode 100644 index 0..695703fe301b3 --- /dev/null +++ b/lldb/tools/lldb-dap/Handler/NextRequestHandler.cpp @@ -0,0 +1,79 @@ +//===-- NextRequestHandler.cpp ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "DAP.h" +#include "EventHelper.h" +#include "JSONUtils.h" +#include "RequestHandler.h" + +namespace lldb_dap { + +// "NextRequest": { +// "allOf": [ { "$ref": "#/definitions/Request" }, { +// "type": "object", +// "description": "Next request; value of command field is 'next'. The +// request starts the debuggee to run again for one step. +// The debug adapter first sends the NextResponse and then +// a StoppedEvent (event type 'step') after the step has +// completed.", +// "properties": { +// "command": { +// "type": "string", +// "enum": [ "next" ] +// }, +// "arguments": { +// "$ref": "#/definitions/NextArguments" +// } +// }, +// "required": [ "command", "arguments" ] +// }] +// }, +// "NextArguments": { +// "type": "object", +// "description": "Arguments for 'next' request.", +// "properties": { +// "threadId": { +// "type": "integer", +// "description": "Execute 'next' for this thread." +// }, +// "granularity": { +// "$ref": "#/definitions/SteppingGranularity", +// "description": "Stepping granularity. If no granularity is specified, a +// granularity of `statement` is assumed." +// } +// }, +// "required": [ "threadId" ] +// }, +// "NextResponse": { +// "allOf": [ { "$ref": "#/definitions/Response" }, { +// "type": "object", +// "description": "Response to 'next' request. This is just an +// acknowledgement, so no body field is required." +// }] +// } +void NextRequestHandler::operator()(const llvm::json::Object &request) { + llvm::json::Object response; + FillResponse(request, response); + const auto *arguments = request.getObject("arguments"); + lldb::SBThread thread = dap.GetLLDBThread(*arguments); + if (thread.IsValid()) { +// Remember the thread ID that caused the resume so we can set the +// "threadCausedFocus" boolean value in the "stopped" events. +dap.focus_tid = thread.GetThreadID(); +if (HasInstructionGranularity(*arguments)) { + thread.StepInstruction(/*step_over=*/true); +} else { + thread.StepOver(); +} + } else { +response["success"] = llvm::json::Value(false); + } + dap.SendJSON(llvm::json::Value(std::move(response))); +} + +} // namespace lldb_dap diff --git a/lldb/tools/lldb-dap/Handler/RequestHandler.cpp b/lldb/tools/lldb-dap/Handler/RequestHandler.cpp index c09ddf55dd5e9..3b1c2b0dc7e31 100644 --- a/lldb/tools/lldb-dap/Handler/RequestHandler.cpp +++ b/lldb/tools/lldb-dap/Handler/RequestHandler.cpp @@ -225,4 +225,11 @@ void RequestHandler::PrintWelcomeMessage() { #endif } +bool RequestHandler::HasInstructionGranularity( +const llvm::json::Object &request) { + if (std::optional value = request.getString("gran
[Lldb-commits] [lldb] [lldb-dap] Refactor stepping related request handlers (NFC) (PR #128453)
https://github.com/JDevlieghere created https://github.com/llvm/llvm-project/pull/128453 Continuation of the work started in #128262. >From 34bd7c56ad67145501217464ef3e6b87a48d587a Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Sun, 23 Feb 2025 21:07:55 -0600 Subject: [PATCH] [lldb-dap] Refactor stepping related request handlers (NFC) Continuation of the work started in #128262. --- lldb/tools/lldb-dap/CMakeLists.txt| 4 + .../lldb-dap/Handler/NextRequestHandler.cpp | 79 .../tools/lldb-dap/Handler/RequestHandler.cpp | 7 + lldb/tools/lldb-dap/Handler/RequestHandler.h | 33 +- .../lldb-dap/Handler/StepInRequestHandler.cpp | 96 + .../Handler/StepInTargetsRequestHandler.cpp | 149 .../Handler/StepOutRequestHandler.cpp | 68 lldb/tools/lldb-dap/lldb-dap.cpp | 344 +- 8 files changed, 440 insertions(+), 340 deletions(-) create mode 100644 lldb/tools/lldb-dap/Handler/NextRequestHandler.cpp create mode 100644 lldb/tools/lldb-dap/Handler/StepInRequestHandler.cpp create mode 100644 lldb/tools/lldb-dap/Handler/StepInTargetsRequestHandler.cpp create mode 100644 lldb/tools/lldb-dap/Handler/StepOutRequestHandler.cpp diff --git a/lldb/tools/lldb-dap/CMakeLists.txt b/lldb/tools/lldb-dap/CMakeLists.txt index 73762af5c2fd7..61271e1a9f2a6 100644 --- a/lldb/tools/lldb-dap/CMakeLists.txt +++ b/lldb/tools/lldb-dap/CMakeLists.txt @@ -47,8 +47,12 @@ add_lldb_tool(lldb-dap Handler/ExceptionInfoRequestHandler.cpp Handler/InitializeRequestHandler.cpp Handler/LaunchRequestHandler.cpp + Handler/NextRequestHandler.cpp Handler/RequestHandler.cpp Handler/RestartRequestHandler.cpp + Handler/StepInRequestHandler.cpp + Handler/StepInTargetsRequestHandler.cpp + Handler/StepOutRequestHandler.cpp LINK_LIBS liblldb diff --git a/lldb/tools/lldb-dap/Handler/NextRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/NextRequestHandler.cpp new file mode 100644 index 0..695703fe301b3 --- /dev/null +++ b/lldb/tools/lldb-dap/Handler/NextRequestHandler.cpp @@ -0,0 +1,79 @@ +//===-- NextRequestHandler.cpp ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "DAP.h" +#include "EventHelper.h" +#include "JSONUtils.h" +#include "RequestHandler.h" + +namespace lldb_dap { + +// "NextRequest": { +// "allOf": [ { "$ref": "#/definitions/Request" }, { +// "type": "object", +// "description": "Next request; value of command field is 'next'. The +// request starts the debuggee to run again for one step. +// The debug adapter first sends the NextResponse and then +// a StoppedEvent (event type 'step') after the step has +// completed.", +// "properties": { +// "command": { +// "type": "string", +// "enum": [ "next" ] +// }, +// "arguments": { +// "$ref": "#/definitions/NextArguments" +// } +// }, +// "required": [ "command", "arguments" ] +// }] +// }, +// "NextArguments": { +// "type": "object", +// "description": "Arguments for 'next' request.", +// "properties": { +// "threadId": { +// "type": "integer", +// "description": "Execute 'next' for this thread." +// }, +// "granularity": { +// "$ref": "#/definitions/SteppingGranularity", +// "description": "Stepping granularity. If no granularity is specified, a +// granularity of `statement` is assumed." +// } +// }, +// "required": [ "threadId" ] +// }, +// "NextResponse": { +// "allOf": [ { "$ref": "#/definitions/Response" }, { +// "type": "object", +// "description": "Response to 'next' request. This is just an +// acknowledgement, so no body field is required." +// }] +// } +void NextRequestHandler::operator()(const llvm::json::Object &request) { + llvm::json::Object response; + FillResponse(request, response); + const auto *arguments = request.getObject("arguments"); + lldb::SBThread thread = dap.GetLLDBThread(*arguments); + if (thread.IsValid()) { +// Remember the thread ID that caused the resume so we can set the +// "threadCausedFocus" boolean value in the "stopped" events. +dap.focus_tid = thread.GetThreadID(); +if (HasInstructionGranularity(*arguments)) { + thread.StepInstruction(/*step_over=*/true); +} else { + thread.StepOver(); +} + } else { +response["success"] = llvm::json::Value(false); + } + dap.SendJSON(llvm::json::Value(std::move(response))); +} + +} // namespace lldb_dap diff --git a/lldb/tools/lldb-dap/Handler/RequestHandler.cpp b/lldb/tools/lldb-dap/Handle