llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lldb Author: Ely Ronnen (eronnen) <details> <summary>Changes</summary> Refactor code revolving source objects such that most logics will be reused. The main change is to expose a single `CreateSource(addr, target)` that can return either a normal or an assembly source object, and call `ShouldDisplayAssemblySource()` only from this function instead of multiple places across the code. Other functions can use `source.IsAssemblySource()` in order to check which type the source is. --- Patch is 22.05 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/141426.diff 12 Files Affected: - (modified) lldb/include/lldb/API/SBAddress.h (+7) - (modified) lldb/source/API/SBAddress.cpp (+19-3) - (modified) lldb/source/Core/Module.cpp (+3) - (modified) lldb/tools/lldb-dap/Breakpoint.cpp (+5-9) - (modified) lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp (+9-6) - (modified) lldb/tools/lldb-dap/Handler/LocationsRequestHandler.cpp (+6-3) - (modified) lldb/tools/lldb-dap/Handler/StackTraceRequestHandler.cpp (+1-6) - (modified) lldb/tools/lldb-dap/JSONUtils.cpp (+65-62) - (modified) lldb/tools/lldb-dap/JSONUtils.h (+10-38) - (modified) lldb/tools/lldb-dap/LLDBUtils.cpp (+7) - (modified) lldb/tools/lldb-dap/LLDBUtils.h (+14) - (modified) lldb/tools/lldb-dap/Protocol/ProtocolTypes.h (+2) ``````````diff diff --git a/lldb/include/lldb/API/SBAddress.h b/lldb/include/lldb/API/SBAddress.h index 430dad4862dbf..c61f02702f1ca 100644 --- a/lldb/include/lldb/API/SBAddress.h +++ b/lldb/include/lldb/API/SBAddress.h @@ -11,6 +11,7 @@ #include "lldb/API/SBDefines.h" #include "lldb/API/SBModule.h" +#include "lldb/API/SBTarget.h" namespace lldb { @@ -58,6 +59,9 @@ class LLDB_API SBAddress { // "lldb::SBAddress SBTarget::ResolveLoadAddress (...)". lldb::SBSymbolContext GetSymbolContext(uint32_t resolve_scope); + lldb::SBSymbolContext GetSymbolContext(const SBTarget &target, + uint32_t resolve_scope); + // The following functions grab individual objects for a given address and // are less efficient if you want more than one symbol related objects. Use // one of the following when you want multiple debug symbol related objects @@ -122,6 +126,9 @@ class LLDB_API SBAddress { void SetAddress(const lldb_private::Address &address); + void CalculateSymbolContext(lldb_private::SymbolContext &sc, + uint32_t resolve_scope); + private: std::unique_ptr<lldb_private::Address> m_opaque_up; }; diff --git a/lldb/source/API/SBAddress.cpp b/lldb/source/API/SBAddress.cpp index e519f0bcc83c6..b6b9e238d3cbf 100644 --- a/lldb/source/API/SBAddress.cpp +++ b/lldb/source/API/SBAddress.cpp @@ -213,9 +213,18 @@ SBSymbolContext SBAddress::GetSymbolContext(uint32_t resolve_scope) { LLDB_INSTRUMENT_VA(this, resolve_scope); SBSymbolContext sb_sc; - SymbolContextItem scope = static_cast<SymbolContextItem>(resolve_scope); - if (m_opaque_up->IsValid()) - m_opaque_up->CalculateSymbolContext(&sb_sc.ref(), scope); + CalculateSymbolContext(sb_sc.ref(), resolve_scope); + return sb_sc; +} + +SBSymbolContext SBAddress::GetSymbolContext(const SBTarget &target, + uint32_t resolve_scope) { + LLDB_INSTRUMENT_VA(this, target, resolve_scope); + + SBSymbolContext sb_sc; + lldb_private::SymbolContext &sc = sb_sc.ref(); + sc.target_sp = target.GetSP(); + CalculateSymbolContext(sc, resolve_scope); return sb_sc; } @@ -266,3 +275,10 @@ SBLineEntry SBAddress::GetLineEntry() { } return sb_line_entry; } + +void SBAddress::CalculateSymbolContext(lldb_private::SymbolContext &sc, + uint32_t resolve_scope) { + SymbolContextItem scope = static_cast<SymbolContextItem>(resolve_scope); + if (m_opaque_up->IsValid()) + m_opaque_up->CalculateSymbolContext(&sc, scope); +} diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp index 625c14e4a2153..90997dada3666 100644 --- a/lldb/source/Core/Module.cpp +++ b/lldb/source/Core/Module.cpp @@ -483,6 +483,9 @@ uint32_t Module::ResolveSymbolContextForAddress( symfile->SetLoadDebugInfoEnabled(); resolved_flags |= symfile->ResolveSymbolContext(so_addr, resolve_scope, sc); + + if ((resolve_scope & eSymbolContextLineEntry) && sc.line_entry.IsValid()) + sc.line_entry.ApplyFileMappings(sc.target_sp); } // Resolve the symbol if requested, but don't re-look it up if we've diff --git a/lldb/tools/lldb-dap/Breakpoint.cpp b/lldb/tools/lldb-dap/Breakpoint.cpp index 2d0fd9c9c3954..dea4dbadc0bda 100644 --- a/lldb/tools/lldb-dap/Breakpoint.cpp +++ b/lldb/tools/lldb-dap/Breakpoint.cpp @@ -9,12 +9,10 @@ #include "Breakpoint.h" #include "DAP.h" #include "JSONUtils.h" -#include "LLDBUtils.h" #include "lldb/API/SBAddress.h" #include "lldb/API/SBBreakpointLocation.h" #include "lldb/API/SBLineEntry.h" #include "lldb/API/SBMutex.h" -#include "lldb/lldb-enumerations.h" #include "llvm/ADT/StringExtras.h" #include <cstddef> #include <cstdint> @@ -66,17 +64,15 @@ protocol::Breakpoint Breakpoint::ToProtocolBreakpoint() { "0x" + llvm::utohexstr(bp_addr.GetLoadAddress(m_bp.GetTarget())); breakpoint.instructionReference = formatted_addr; - lldb::StopDisassemblyType stop_disassembly_display = - GetStopDisassemblyDisplay(m_dap.debugger); - auto line_entry = bp_addr.GetLineEntry(); - if (!ShouldDisplayAssemblySource(line_entry, stop_disassembly_display)) { + auto source = CreateSource(bp_addr, m_dap.target); + if (!source.IsAssemblySource()) { + auto line_entry = bp_addr.GetLineEntry(); const auto line = line_entry.GetLine(); if (line != LLDB_INVALID_LINE_NUMBER) breakpoint.line = line; const auto column = line_entry.GetColumn(); if (column != LLDB_INVALID_COLUMN_NUMBER) breakpoint.column = column; - breakpoint.source = CreateSource(line_entry); } else { // Assembly breakpoint. auto symbol = bp_addr.GetSymbol(); @@ -86,10 +82,10 @@ protocol::Breakpoint Breakpoint::ToProtocolBreakpoint() { .ReadInstructions(symbol.GetStartAddress(), bp_addr, nullptr) .GetSize() + 1; - - breakpoint.source = CreateAssemblySource(m_dap.target, bp_addr); } } + + breakpoint.source = std::move(source); } return breakpoint; diff --git a/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp index c9061ef19f17a..4c04612bf173a 100644 --- a/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp +++ b/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp @@ -9,6 +9,7 @@ #include "DAP.h" #include "EventHelper.h" #include "JSONUtils.h" +#include "LLDBUtils.h" #include "Protocol/ProtocolRequests.h" #include "Protocol/ProtocolTypes.h" #include "RequestHandler.h" @@ -138,15 +139,16 @@ static DisassembledInstruction ConvertSBInstructionToDisassembledInstruction( disassembled_inst.instruction = std::move(instruction); - auto line_entry = addr.GetLineEntry(); + auto source = CreateSource(addr, target); + auto line_entry = GetLineEntryForAddress(target, addr); + // If the line number is 0 then the entry represents a compiler generated // location. - - if (line_entry.GetStartAddress() == addr && line_entry.IsValid() && + if (!source.IsAssemblySource() && line_entry.IsValid() && + line_entry.GetStartAddress() == addr && line_entry.IsValid() && line_entry.GetFileSpec().IsValid() && line_entry.GetLine() != 0) { - auto source = CreateSource(line_entry); - disassembled_inst.location = std::move(source); + disassembled_inst.location = std::move(source); const auto line = line_entry.GetLine(); if (line != 0 && line != LLDB_INVALID_LINE_NUMBER) disassembled_inst.line = line; @@ -155,7 +157,8 @@ static DisassembledInstruction ConvertSBInstructionToDisassembledInstruction( if (column != 0 && column != LLDB_INVALID_COLUMN_NUMBER) disassembled_inst.column = column; - auto end_line_entry = line_entry.GetEndAddress().GetLineEntry(); + lldb::SBAddress end_addr = line_entry.GetEndAddress(); + auto end_line_entry = GetLineEntryForAddress(target, end_addr); if (end_line_entry.IsValid() && end_line_entry.GetFileSpec() == line_entry.GetFileSpec()) { const auto end_line = end_line_entry.GetLine(); diff --git a/lldb/tools/lldb-dap/Handler/LocationsRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/LocationsRequestHandler.cpp index 15109d4b8e589..39ad6949990c7 100644 --- a/lldb/tools/lldb-dap/Handler/LocationsRequestHandler.cpp +++ b/lldb/tools/lldb-dap/Handler/LocationsRequestHandler.cpp @@ -9,8 +9,11 @@ #include "DAP.h" #include "EventHelper.h" #include "JSONUtils.h" +#include "LLDBUtils.h" #include "RequestHandler.h" +#include "lldb/API/SBAddress.h" #include "lldb/API/SBDeclaration.h" +#include "lldb/API/SBLineEntry.h" namespace lldb_dap { @@ -122,9 +125,9 @@ void LocationsRequestHandler::operator()( return; } - lldb::addr_t addr = variable.GetValueAsAddress(); - lldb::SBLineEntry line_entry = - dap.target.ResolveLoadAddress(addr).GetLineEntry(); + lldb::addr_t raw_addr = variable.GetValueAsAddress(); + lldb::SBAddress addr = dap.target.ResolveLoadAddress(raw_addr); + lldb::SBLineEntry line_entry = GetLineEntryForAddress(dap.target, addr); if (!line_entry.IsValid()) { response["success"] = false; diff --git a/lldb/tools/lldb-dap/Handler/StackTraceRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/StackTraceRequestHandler.cpp index ff326a47d9a48..4ea4cd1e517d4 100644 --- a/lldb/tools/lldb-dap/Handler/StackTraceRequestHandler.cpp +++ b/lldb/tools/lldb-dap/Handler/StackTraceRequestHandler.cpp @@ -9,9 +9,7 @@ #include "DAP.h" #include "EventHelper.h" #include "JSONUtils.h" -#include "LLDBUtils.h" #include "RequestHandler.h" -#include "lldb/lldb-enumerations.h" namespace lldb_dap { @@ -55,8 +53,6 @@ static bool FillStackFrames(DAP &dap, lldb::SBThread &thread, llvm::json::Array &stack_frames, int64_t &offset, const int64_t start_frame, const int64_t levels, const bool include_all) { - lldb::StopDisassemblyType stop_disassembly_display = - GetStopDisassemblyDisplay(dap.debugger); bool reached_end_of_stack = false; for (int64_t i = start_frame; static_cast<int64_t>(stack_frames.size()) < levels; i++) { @@ -73,8 +69,7 @@ static bool FillStackFrames(DAP &dap, lldb::SBThread &thread, break; } - stack_frames.emplace_back( - CreateStackFrame(frame, frame_format, stop_disassembly_display)); + stack_frames.emplace_back(CreateStackFrame(frame, frame_format)); } if (include_all && reached_end_of_stack) { diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp index c9c6f4554c325..e0c6e19863896 100644 --- a/lldb/tools/lldb-dap/JSONUtils.cpp +++ b/lldb/tools/lldb-dap/JSONUtils.cpp @@ -12,6 +12,7 @@ #include "LLDBUtils.h" #include "lldb/API/SBAddress.h" #include "lldb/API/SBCompileUnit.h" +#include "lldb/API/SBDebugger.h" #include "lldb/API/SBDeclaration.h" #include "lldb/API/SBEnvironment.h" #include "lldb/API/SBError.h" @@ -497,34 +498,33 @@ static std::string GetLoadAddressString(const lldb::addr_t addr) { return result; } -protocol::Source CreateSource(const lldb::SBFileSpec &file) { - protocol::Source source; - if (file.IsValid()) { - const char *name = file.GetFilename(); - if (name) - source.name = name; - char path[PATH_MAX] = ""; - if (file.GetPath(path, sizeof(path)) && - lldb::SBFileSpec::ResolvePath(path, path, PATH_MAX)) - source.path = path; - } - return source; -} +static bool ShouldDisplayAssemblySource( + lldb::SBAddress address, + lldb::StopDisassemblyType stop_disassembly_display) { + if (stop_disassembly_display == lldb::eStopDisassemblyTypeNever) + return false; -protocol::Source CreateSource(const lldb::SBLineEntry &line_entry) { - return CreateSource(line_entry.GetFileSpec()); -} + if (stop_disassembly_display == lldb::eStopDisassemblyTypeAlways) + return true; -protocol::Source CreateSource(llvm::StringRef source_path) { - protocol::Source source; - llvm::StringRef name = llvm::sys::path::filename(source_path); - source.name = name; - source.path = source_path; - return source; + // A line entry of 0 indicates the line is compiler generated i.e. no source + // file is associated with the frame. + auto line_entry = address.GetLineEntry(); + auto file_spec = line_entry.GetFileSpec(); + if (!file_spec.IsValid() || line_entry.GetLine() == 0 || + line_entry.GetLine() == LLDB_INVALID_LINE_NUMBER) + return true; + + if (stop_disassembly_display == lldb::eStopDisassemblyTypeNoSource && + !file_spec.Exists()) { + return true; + } + + return false; } -protocol::Source CreateAssemblySource(const lldb::SBTarget &target, - lldb::SBAddress &address) { +static protocol::Source CreateAssemblySource(const lldb::SBTarget &target, + lldb::SBAddress address) { protocol::Source source; auto symbol = address.GetSymbol(); @@ -558,28 +558,38 @@ protocol::Source CreateAssemblySource(const lldb::SBTarget &target, return source; } -bool ShouldDisplayAssemblySource( - const lldb::SBLineEntry &line_entry, - lldb::StopDisassemblyType stop_disassembly_display) { - if (stop_disassembly_display == lldb::eStopDisassemblyTypeNever) - return false; - - if (stop_disassembly_display == lldb::eStopDisassemblyTypeAlways) - return true; - - // A line entry of 0 indicates the line is compiler generated i.e. no source - // file is associated with the frame. - auto file_spec = line_entry.GetFileSpec(); - if (!file_spec.IsValid() || line_entry.GetLine() == 0 || - line_entry.GetLine() == LLDB_INVALID_LINE_NUMBER) - return true; +protocol::Source CreateSource(const lldb::SBFileSpec &file) { + protocol::Source source; + if (file.IsValid()) { + const char *name = file.GetFilename(); + if (name) + source.name = name; + char path[PATH_MAX] = ""; + if (file.GetPath(path, sizeof(path)) && + lldb::SBFileSpec::ResolvePath(path, path, PATH_MAX)) + source.path = path; + } + return source; +} - if (stop_disassembly_display == lldb::eStopDisassemblyTypeNoSource && - !file_spec.Exists()) { - return true; +protocol::Source CreateSource(lldb::SBAddress address, lldb::SBTarget &target) { + lldb::SBDebugger debugger = target.GetDebugger(); + lldb::StopDisassemblyType stop_disassembly_display = + GetStopDisassemblyDisplay(debugger); + if (!ShouldDisplayAssemblySource(address, stop_disassembly_display)) { + lldb::SBLineEntry line_entry = GetLineEntryForAddress(target, address); + return CreateSource(line_entry.GetFileSpec()); } - return false; + return CreateAssemblySource(target, address); +} + +protocol::Source CreateSource(llvm::StringRef source_path) { + protocol::Source source; + llvm::StringRef name = llvm::sys::path::filename(source_path); + source.name = name; + source.path = source_path; + return source; } // "StackFrame": { @@ -643,9 +653,8 @@ bool ShouldDisplayAssemblySource( // }, // "required": [ "id", "name", "line", "column" ] // } -llvm::json::Value -CreateStackFrame(lldb::SBFrame &frame, lldb::SBFormat &format, - lldb::StopDisassemblyType stop_disassembly_display) { +llvm::json::Value CreateStackFrame(lldb::SBFrame &frame, + lldb::SBFormat &format) { llvm::json::Object object; int64_t frame_id = MakeDAPFrameID(frame); object.try_emplace("id", frame_id); @@ -673,22 +682,18 @@ CreateStackFrame(lldb::SBFrame &frame, lldb::SBFormat &format, EmplaceSafeString(object, "name", frame_name); - auto line_entry = frame.GetLineEntry(); - if (!ShouldDisplayAssemblySource(line_entry, stop_disassembly_display)) { - object.try_emplace("source", CreateSource(line_entry)); + auto target = frame.GetThread().GetProcess().GetTarget(); + auto source = CreateSource(frame.GetPCAddress(), target); + if (!source.IsAssemblySource()) { + // This is a normal source with a valid line entry. + auto line_entry = frame.GetLineEntry(); object.try_emplace("line", line_entry.GetLine()); auto column = line_entry.GetColumn(); object.try_emplace("column", column); } else if (frame.GetSymbol().IsValid()) { - // If no source is associated with the frame, use the DAPFrameID to track - // the 'source' and generate assembly. - auto frame_address = frame.GetPCAddress(); - object.try_emplace("source", CreateAssemblySource( - frame.GetThread().GetProcess().GetTarget(), - frame_address)); - - // Calculate the line of the current PC from the start of the current - // symbol. + // This is a source where the disassembly is used, but there is a valid + // symbol. Calculate the line of the current PC from the start of the + // current symbol. lldb::SBTarget target = frame.GetThread().GetProcess().GetTarget(); lldb::SBInstructionList inst_list = target.ReadInstructions( frame.GetSymbol().GetStartAddress(), frame.GetPCAddress(), nullptr); @@ -699,14 +704,12 @@ CreateStackFrame(lldb::SBFrame &frame, lldb::SBFormat &format, object.try_emplace("column", 1); } else { // No valid line entry or symbol. - auto frame_address = frame.GetPCAddress(); - object.try_emplace("source", CreateAssemblySource( - frame.GetThread().GetProcess().GetTarget(), - frame_address)); object.try_emplace("line", 1); object.try_emplace("column", 1); } + object.try_emplace("source", std::move(source)); + const auto pc = frame.GetPC(); if (pc != LLDB_INVALID_ADDRESS) { std::string formatted_addr = "0x" + llvm::utohexstr(pc); diff --git a/lldb/tools/lldb-dap/JSONUtils.h b/lldb/tools/lldb-dap/JSONUtils.h index 5758c3d56ec90..3f9b3162ad027 100644 --- a/lldb/tools/lldb-dap/JSONUtils.h +++ b/lldb/tools/lldb-dap/JSONUtils.h @@ -11,7 +11,9 @@ #include "DAPForward.h" #include "Protocol/ProtocolTypes.h" +#include "lldb/API/SBAddress.h" #include "lldb/API/SBCompileUnit.h" +#include "lldb/API/SBDebugger.h" #include "lldb/API/SBFileSpec.h" #include "lldb/API/SBFormat.h" #include "lldb/API/SBLineEntry.h" @@ -250,14 +252,16 @@ protocol::Source CreateSource(const lldb::SBFileSpec &file); /// Create a "Source" JSON object as described in the debug adapter definition. /// -/// \param[in] line_entry -/// The LLDB line table to use when populating out the "Source" -/// object +/// \param[in] address +/// The address to use when populating out the "Source" object. +/// +/// \param[in] target +/// The target that has the address. /// /// \return /// A "Source" JSON object that follows the formal JSON /// definition outlined by Microsoft. -protocol::Source CreateSource(const lldb::SBLineEntry &line_entry); +protocol::Source CreateSource(lldb::SBAddress address, lldb::SBTarget &target); /// Create a "Source" object for a given source path. /// @@ -269,35 +273,6 @@ protocol::Source CreateSource(const lldb::SBLineEntry &line_entry); /// definition outlined by Microsoft. protocol::Source CreateSource(llvm::StringRef source_path); -/// Create a "Source" object for a given frame, using its assembly for source. -/// -/// \param[in] target -/// The relevant target. -/// -/// \param[in] address -/// The address to use when creating the "Source" object. -/// -/// \return -/// A "Source" JSON object that follows the formal JSON -/// definition outlined by Microsoft. -protocol::Source CreateAssemblySource(const lldb::SBTarget &target, - lldb::SBAddress &address); - -/// Return true if the given line entry should be displayed as assembly. -/// -/// \param[in] line_entry -/// The LLDB line entry to check. -/// -/// \param[in] stop_disassembly_display -/// The value of the "stop-disassembly-display" setting. -/// -/// \return -/// True if the line entry should be displayed as assembly, false -/// otherwise. -bool ShouldDisplayAssemblySource( - const lldb::SBLineEntry &line_entry, - lldb::StopDisassemblyType stop_disassembly_display); - /// Create a "StackFrame" object for a LLDB frame object. /// /// This function will fill in the following keys in the returned @@ -316,14 +291,11 @@ bool ShouldDisplayAssemblySource( /// The LLDB format to use when populating out the "StackFrame" /// object. /// -/// \param[in] stop_disassembly_display -/// The value of the "stop-disassembly-display" setting. -/// /// \return /// A "StackFrame" JSON object with that follows the formal JSON /// definition outlined by Microsoft. -llvm::json::Value CreateStackFrame(lldb::SBFrame &frame, lldb::SBFormat &format, - lldb::StopDisassemblyType); +llvm::json::Value CreateStackFrame(lldb::SBFrame &frame, + lldb::SBFormat &format); /// Create a "StackFrame" label object for a LLDB thread. /// diff --git a/lldb/tools/lldb-dap/LLDBUtils.cpp b/lldb/tools/lldb-dap/LLDBUtils.cpp index fe0bcda19b4cd..eb23a89be78da 100644 --- a/lldb/tools/lldb-dap/LLDBUtils.cpp +++ b/lldb/tools/lldb-dap/LLDBUtils.cpp @@ -252,4 +252,11 @@ std::string GetSBFileSpecPath(const lldb::SBFileSpec &file_spec) {... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/141426 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits