[Lldb-commits] [lldb] [lldb] Turn LineEntry into a class and make AddressRange member optional (PR #158811)
Med Ismail Bennani via lldb-commits
lldb-commits at lists.llvm.org
Tue Dec 2 12:40:08 PST 2025
https://github.com/medismailben updated https://github.com/llvm/llvm-project/pull/158811
>From 86e61fb180385d2c6a34017c33cf1c35cf5c5ca9 Mon Sep 17 00:00:00 2001
From: Med Ismail Bennani <ismail at bennani.ma>
Date: Tue, 2 Dec 2025 12:39:01 -0800
Subject: [PATCH] [lldb] Turn LineEntry into a class and make AddressRange
member optional
This patch relaxes the LineEntry validity from requiring a valid
AddressRange to turning the LineEntry `struct` into a `class` and make
the AddressRange member a private optional.
This addresses a problem for when LineEntry are created from the SB API,
because there is no way of adding an address range to an SBLineEntry,
it's always invalid. This becomes a bigger problem when trying to set
the line entry into a SymbolContext object and it discards it after
checking its validity.
This patch is necessary to extend ScriptedFrames ability to create
synthetic frames with invalid addresses and invalid line entries.
Signed-off-by: Med Ismail Bennani <ismail at bennani.ma>
---
.../lldb/Breakpoint/BreakpointLocation.h | 3 +-
lldb/include/lldb/Symbol/LineEntry.h | 16 +++++-
lldb/source/API/SBLineEntry.cpp | 10 ++--
lldb/source/API/SBThread.cpp | 13 +++--
lldb/source/Breakpoint/BreakpointResolver.cpp | 22 +++++--
.../Commands/CommandObjectDisassemble.cpp | 4 +-
lldb/source/Commands/CommandObjectSource.cpp | 6 +-
lldb/source/Commands/CommandObjectTarget.cpp | 4 +-
lldb/source/Commands/CommandObjectThread.cpp | 4 +-
lldb/source/Core/AddressResolverFileLine.cpp | 4 +-
lldb/source/Core/FormatEntity.cpp | 15 ++---
lldb/source/DataFormatters/TypeSummary.cpp | 4 +-
.../Plugins/SymbolFile/PDB/SymbolFilePDB.cpp | 2 +-
lldb/source/Symbol/CompileUnit.cpp | 16 ++++--
lldb/source/Symbol/Function.cpp | 17 +++---
lldb/source/Symbol/LineEntry.cpp | 57 ++++++++++++-------
lldb/source/Symbol/LineTable.cpp | 15 ++---
lldb/source/Symbol/Symbol.cpp | 7 ++-
lldb/source/Symbol/SymbolContext.cpp | 28 ++++++---
.../Target/ThreadPlanShouldStopHere.cpp | 2 +-
.../source/Target/ThreadPlanStepOverRange.cpp | 4 +-
lldb/source/Target/ThreadPlanStepRange.cpp | 12 ++--
.../dummy_scripted_process.py | 15 +++++
lldb/tools/lldb-test/lldb-test.cpp | 11 +++-
lldb/unittests/Symbol/LineTableTest.cpp | 11 +++-
25 files changed, 200 insertions(+), 102 deletions(-)
diff --git a/lldb/include/lldb/Breakpoint/BreakpointLocation.h b/lldb/include/lldb/Breakpoint/BreakpointLocation.h
index c44ff471b8c4b..4d239ec64cd08 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointLocation.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointLocation.h
@@ -308,7 +308,8 @@ class BreakpointLocation
/// The line entry must have the same start address as the address for this
/// location.
bool SetPreferredLineEntry(const LineEntry &line_entry) {
- if (m_address == line_entry.range.GetBaseAddress()) {
+ if (line_entry.HasValidRange() &&
+ m_address == line_entry.GetRange().GetBaseAddress()) {
m_preferred_line_entry = line_entry;
return true;
}
diff --git a/lldb/include/lldb/Symbol/LineEntry.h b/lldb/include/lldb/Symbol/LineEntry.h
index a61b72f253dd7..1ca6e7170e896 100644
--- a/lldb/include/lldb/Symbol/LineEntry.h
+++ b/lldb/include/lldb/Symbol/LineEntry.h
@@ -13,6 +13,7 @@
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/SupportFile.h"
#include "lldb/lldb-private.h"
+#include <optional>
namespace lldb_private {
@@ -133,8 +134,15 @@ struct LineEntry {
/// Helper to access the file.
const FileSpec &GetFile() const { return file_sp->GetSpecOnly(); }
- /// The section offset address range for this line entry.
- AddressRange range;
+ /// Get the address range for this line entry.
+ /// \return The address range if valid, otherwise an invalid AddressRange.
+ const AddressRange &GetRange() const;
+
+ /// Check if this line entry has a valid address range.
+ bool HasValidRange() const;
+
+ /// Set the address range for this line entry.
+ void SetRange(const AddressRange &range);
/// The source file, possibly mapped by the target.source-map setting.
SupportFileNSP file_sp;
@@ -167,6 +175,10 @@ struct LineEntry {
/// Indicates this entry is that of the first byte after the end of a sequence
/// of target machine instructions.
uint16_t is_terminal_entry : 1;
+
+private:
+ /// The section offset address range for this line entry (optional).
+ std::optional<AddressRange> m_range;
};
/// Less than operator.
diff --git a/lldb/source/API/SBLineEntry.cpp b/lldb/source/API/SBLineEntry.cpp
index 0f4936f32a074..78ff488e8927f 100644
--- a/lldb/source/API/SBLineEntry.cpp
+++ b/lldb/source/API/SBLineEntry.cpp
@@ -50,8 +50,8 @@ SBAddress SBLineEntry::GetStartAddress() const {
LLDB_INSTRUMENT_VA(this);
SBAddress sb_address;
- if (m_opaque_up)
- sb_address.SetAddress(m_opaque_up->range.GetBaseAddress());
+ if (m_opaque_up && m_opaque_up->HasValidRange())
+ sb_address.SetAddress(m_opaque_up->GetRange().GetBaseAddress());
return sb_address;
}
@@ -60,9 +60,9 @@ SBAddress SBLineEntry::GetEndAddress() const {
LLDB_INSTRUMENT_VA(this);
SBAddress sb_address;
- if (m_opaque_up) {
- sb_address.SetAddress(m_opaque_up->range.GetBaseAddress());
- sb_address.OffsetAddress(m_opaque_up->range.GetByteSize());
+ if (m_opaque_up && m_opaque_up->HasValidRange()) {
+ sb_address.SetAddress(m_opaque_up->GetRange().GetBaseAddress());
+ sb_address.OffsetAddress(m_opaque_up->GetRange().GetByteSize());
}
return sb_address;
}
diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp
index f32c5c56444cd..1a8f1dcf3788b 100644
--- a/lldb/source/API/SBThread.cpp
+++ b/lldb/source/API/SBThread.cpp
@@ -539,9 +539,14 @@ void SBThread::StepInto(const char *target_name, uint32_t end_line,
if (frame_sp && frame_sp->HasDebugInformation()) {
SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
AddressRange range;
- if (end_line == LLDB_INVALID_LINE_NUMBER)
- range = sc.line_entry.range;
- else {
+ if (end_line == LLDB_INVALID_LINE_NUMBER) {
+ if (sc.line_entry.HasValidRange())
+ range = sc.line_entry.GetRange();
+ else {
+ error = Status::FromErrorString("No valid range for line entry");
+ return;
+ }
+ } else {
llvm::Error err = sc.GetAddressRangeFromHereToEndLine(end_line, range);
if (err) {
error = Status::FromErrorString(llvm::toString(std::move(err)).c_str());
@@ -811,7 +816,7 @@ SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
eSymbolContextLineEntry, sc_list);
for (const SymbolContext &sc : sc_list) {
addr_t step_addr =
- sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
+ sc.line_entry.GetRange().GetBaseAddress().GetLoadAddress(target);
if (step_addr != LLDB_INVALID_ADDRESS) {
AddressRange unused_range;
if (frame_sc.function->GetRangeContainingLoadAddress(step_addr, *target,
diff --git a/lldb/source/Breakpoint/BreakpointResolver.cpp b/lldb/source/Breakpoint/BreakpointResolver.cpp
index 4ac40501a5df5..a91805156a63c 100644
--- a/lldb/source/Breakpoint/BreakpointResolver.cpp
+++ b/lldb/source/Breakpoint/BreakpointResolver.cpp
@@ -273,11 +273,19 @@ void BreakpointResolver::SetSCMatchesByLine(
}
// Sort by file address.
- llvm::sort(worklist_begin, worklist_end,
- [](const SymbolContext &a, const SymbolContext &b) {
- return a.line_entry.range.GetBaseAddress().GetFileAddress() <
- b.line_entry.range.GetBaseAddress().GetFileAddress();
- });
+ llvm::sort(
+ worklist_begin, worklist_end,
+ [](const SymbolContext &a, const SymbolContext &b) {
+ auto a_addr =
+ a.line_entry.HasValidRange()
+ ? a.line_entry.GetRange().GetBaseAddress().GetFileAddress()
+ : LLDB_INVALID_ADDRESS;
+ auto b_addr =
+ b.line_entry.HasValidRange()
+ ? b.line_entry.GetRange().GetBaseAddress().GetFileAddress()
+ : LLDB_INVALID_ADDRESS;
+ return a_addr < b_addr;
+ });
// Go through and see if there are line table entries that are
// contiguous, and if so keep only the first of the contiguous range.
@@ -307,7 +315,9 @@ void BreakpointResolver::AddLocation(SearchFilter &filter,
bool skip_prologue,
llvm::StringRef log_ident) {
Log *log = GetLog(LLDBLog::Breakpoints);
- Address line_start = sc.line_entry.range.GetBaseAddress();
+ Address line_start = sc.line_entry.HasValidRange()
+ ? sc.line_entry.GetRange().GetBaseAddress()
+ : Address();
if (!line_start.IsValid()) {
LLDB_LOGF(log,
"error: Unable to set breakpoint %s at file address "
diff --git a/lldb/source/Commands/CommandObjectDisassemble.cpp b/lldb/source/Commands/CommandObjectDisassemble.cpp
index c0553d2c6c8b2..5c32e985c78b8 100644
--- a/lldb/source/Commands/CommandObjectDisassemble.cpp
+++ b/lldb/source/Commands/CommandObjectDisassemble.cpp
@@ -356,8 +356,8 @@ CommandObjectDisassemble::GetCurrentLineRanges() {
LineEntry pc_line_entry(
frame->GetSymbolContext(eSymbolContextLineEntry).line_entry);
- if (pc_line_entry.IsValid())
- return std::vector<AddressRange>{pc_line_entry.range};
+ if (pc_line_entry.IsValid() && pc_line_entry.HasValidRange())
+ return std::vector<AddressRange>{pc_line_entry.GetRange()};
// No line entry, so just disassemble around the current pc
m_options.show_mixed = false;
diff --git a/lldb/source/Commands/CommandObjectSource.cpp b/lldb/source/Commands/CommandObjectSource.cpp
index c9835e74ac51b..b3aed928a4ba7 100644
--- a/lldb/source/Commands/CommandObjectSource.cpp
+++ b/lldb/source/Commands/CommandObjectSource.cpp
@@ -1032,9 +1032,11 @@ class CommandObjectSourceList : public CommandObjectParsed {
bool show_inlined_frames = true;
const bool show_function_arguments = true;
const bool show_function_name = true;
+ Address addr = sc.line_entry.HasValidRange()
+ ? sc.line_entry.GetRange().GetBaseAddress()
+ : Address();
sc.DumpStopContext(&result.GetOutputStream(),
- m_exe_ctx.GetBestExecutionContextScope(),
- sc.line_entry.range.GetBaseAddress(),
+ m_exe_ctx.GetBestExecutionContextScope(), addr,
show_fullpaths, show_module, show_inlined_frames,
show_function_arguments, show_function_name);
result.GetOutputStream().EOL();
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index 6e8c94fa234cd..27ed753f31c65 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -1634,8 +1634,8 @@ static void DumpSymbolContextList(
strm.EOL();
Address addr;
- if (sc.line_entry.IsValid())
- addr = sc.line_entry.range.GetBaseAddress();
+ if (sc.line_entry.IsValid() && sc.line_entry.HasValidRange())
+ addr = sc.line_entry.GetRange().GetBaseAddress();
else if (sc.block && sc.block->GetContainingInlinedBlock())
sc.block->GetContainingInlinedBlock()->GetStartAddress(addr);
else
diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp
index bbec714642ec9..9c9573cba9529 100644
--- a/lldb/source/Commands/CommandObjectThread.cpp
+++ b/lldb/source/Commands/CommandObjectThread.cpp
@@ -519,7 +519,7 @@ class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed {
block_range.GetByteSize() - pc_offset_in_block;
range = AddressRange(pc_address, range_length);
} else {
- range = sc.line_entry.range;
+ range = sc.line_entry.GetRange();
}
new_plan_sp = thread->QueueThreadPlanForStepInRange(
@@ -999,7 +999,7 @@ class CommandObjectThreadUntil : public CommandObjectParsed {
while (idx < end_func_idx) {
if (line_idx_ranges.FindEntryIndexThatContains(idx) != UINT32_MAX) {
addr_t address =
- line_entry.range.GetBaseAddress().GetLoadAddress(target);
+ line_entry.GetRange().GetBaseAddress().GetLoadAddress(target);
if (address != LLDB_INVALID_ADDRESS)
address_list.push_back(address);
}
diff --git a/lldb/source/Core/AddressResolverFileLine.cpp b/lldb/source/Core/AddressResolverFileLine.cpp
index 6ab3b8fcee154..be2f3aa4bebbe 100644
--- a/lldb/source/Core/AddressResolverFileLine.cpp
+++ b/lldb/source/Core/AddressResolverFileLine.cpp
@@ -46,8 +46,8 @@ AddressResolverFileLine::SearchCallback(SearchFilter &filter,
cu->ResolveSymbolContext(m_src_location_spec, eSymbolContextEverything,
sc_list);
for (const SymbolContext &sc : sc_list) {
- Address line_start = sc.line_entry.range.GetBaseAddress();
- addr_t byte_size = sc.line_entry.range.GetByteSize();
+ Address line_start = sc.line_entry.GetRange().GetBaseAddress();
+ addr_t byte_size = sc.line_entry.GetRange().GetByteSize();
if (line_start.IsValid()) {
AddressRange new_range(line_start, byte_size);
m_address_ranges.push_back(new_range);
diff --git a/lldb/source/Core/FormatEntity.cpp b/lldb/source/Core/FormatEntity.cpp
index c528a14fa76d0..fa1223a45d943 100644
--- a/lldb/source/Core/FormatEntity.cpp
+++ b/lldb/source/Core/FormatEntity.cpp
@@ -1937,10 +1937,11 @@ bool FormatEntity::Format(const Entry &entry, Stream &s,
return false;
case Entry::Type::FunctionLineOffset:
- if (sc)
- return (DumpAddressOffsetFromFunction(
- s, sc, exe_ctx, sc->line_entry.range.GetBaseAddress(), false, false,
- false));
+ if (sc) {
+ Address line_addr = sc->line_entry.GetRange().GetBaseAddress();
+ return (DumpAddressOffsetFromFunction(s, sc, exe_ctx, line_addr, false,
+ false, false));
+ }
return false;
case Entry::Type::FunctionPCOffset:
@@ -2005,11 +2006,11 @@ bool FormatEntity::Format(const Entry &entry, Stream &s,
case Entry::Type::LineEntryStartAddress:
case Entry::Type::LineEntryEndAddress:
- if (sc && sc->line_entry.range.GetBaseAddress().IsValid()) {
- Address addr = sc->line_entry.range.GetBaseAddress();
+ if (sc && sc->line_entry.HasValidRange()) {
+ Address addr = sc->line_entry.GetRange().GetBaseAddress();
if (entry.type == Entry::Type::LineEntryEndAddress)
- addr.Slide(sc->line_entry.range.GetByteSize());
+ addr.Slide(sc->line_entry.GetRange().GetByteSize());
if (DumpAddressAndContent(s, sc, exe_ctx, addr, false))
return true;
}
diff --git a/lldb/source/DataFormatters/TypeSummary.cpp b/lldb/source/DataFormatters/TypeSummary.cpp
index 6aa290698cd12..489d6c43f5092 100644
--- a/lldb/source/DataFormatters/TypeSummary.cpp
+++ b/lldb/source/DataFormatters/TypeSummary.cpp
@@ -105,8 +105,8 @@ bool StringSummaryFormat::FormatObject(ValueObject *valobj, std::string &retval,
retval = std::string(s.GetString());
return true;
} else {
- if (FormatEntity::Format(m_format, s, &sc, &exe_ctx,
- &sc.line_entry.range.GetBaseAddress(), valobj,
+ Address temp_addr = sc.line_entry.GetRange().GetBaseAddress();
+ if (FormatEntity::Format(m_format, s, &sc, &exe_ctx, &temp_addr, valobj,
false, false)) {
retval.assign(std::string(s.GetString()));
return true;
diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
index 97c995fc9b22a..d6b2ab3c3b94c 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -952,7 +952,7 @@ uint32_t SymbolFilePDB::ResolveSymbolContext(
continue;
auto file_vm_addr =
- sc.line_entry.range.GetBaseAddress().GetFileAddress();
+ sc.line_entry.GetRange().GetBaseAddress().GetFileAddress();
if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0)
continue;
diff --git a/lldb/source/Symbol/CompileUnit.cpp b/lldb/source/Symbol/CompileUnit.cpp
index 703ef131ad6bf..10710fd59c41a 100644
--- a/lldb/source/Symbol/CompileUnit.cpp
+++ b/lldb/source/Symbol/CompileUnit.cpp
@@ -335,7 +335,7 @@ void CompileUnit::ResolveSymbolContext(
// line entry will be the in function that contained the line that might
// be a CallSite, and we can just iterate over that function to find any
// inline records, and dig up their call sites.
- Address start_addr = line_entry.range.GetBaseAddress();
+ Address start_addr = line_entry.GetRange().GetBaseAddress();
Function *function = start_addr.CalculateSymbolContextFunction();
// Record the size of the list to see if we added to it:
size_t old_sc_list_size = sc_list.GetSize();
@@ -390,8 +390,9 @@ void CompileUnit::ResolveSymbolContext(
*src_location_spec.GetColumn() == call_site_line.column))
matches_spec = true;
}
- if (matches_spec &&
- sibling_block->GetRangeAtIndex(0, call_site_line.range)) {
+ AddressRange range;
+ if (matches_spec && sibling_block->GetRangeAtIndex(0, range)) {
+ call_site_line.SetRange(range);
SymbolContext call_site_sc(sc.target_sp, sc.module_sp,
sc.comp_unit, sc.function, sc.block,
&call_site_line, sc.symbol);
@@ -446,8 +447,9 @@ void CompileUnit::ResolveSymbolContext(
if (resolve_scope == eSymbolContextLineEntry) {
sc_list.Append(sc);
} else {
- line_entry.range.GetBaseAddress().CalculateSymbolContext(&resolved_sc,
- resolve_scope);
+ if (line_entry.HasValidRange())
+ line_entry.GetRange().GetBaseAddress().CalculateSymbolContext(
+ &resolved_sc, resolve_scope);
// Sometimes debug info is bad and isn't able to resolve the line entry's
// address back to the same compile unit and/or line entry. If the compile
// unit changed, then revert back to just the compile unit and line entry.
@@ -474,7 +476,9 @@ void CompileUnit::ResolveSymbolContext(
"unable to resolve a line table file address {0:x16} back "
"to a compile unit, please file a bug and attach the address "
"and file.",
- line_entry.range.GetBaseAddress().GetFileAddress());
+ line_entry.HasValidRange()
+ ? line_entry.GetRange().GetBaseAddress().GetFileAddress()
+ : 0);
}
sc_list.Append(sc);
}
diff --git a/lldb/source/Symbol/Function.cpp b/lldb/source/Symbol/Function.cpp
index 11b823c8c53d6..6a4385863a029 100644
--- a/lldb/source/Symbol/Function.cpp
+++ b/lldb/source/Symbol/Function.cpp
@@ -593,7 +593,7 @@ uint32_t Function::GetPrologueByteSize() {
if (first_line_entry.is_prologue_end) {
prologue_end_file_addr =
- first_line_entry.range.GetBaseAddress().GetFileAddress();
+ first_line_entry.GetRange().GetBaseAddress().GetFileAddress();
prologue_end_line_idx = first_line_entry_idx;
} else {
// Check the first few instructions and look for one that has
@@ -605,7 +605,7 @@ uint32_t Function::GetPrologueByteSize() {
if (line_table->GetLineEntryAtIndex(idx, line_entry)) {
if (line_entry.is_prologue_end) {
prologue_end_file_addr =
- line_entry.range.GetBaseAddress().GetFileAddress();
+ line_entry.GetRange().GetBaseAddress().GetFileAddress();
prologue_end_line_idx = idx;
break;
}
@@ -625,7 +625,7 @@ uint32_t Function::GetPrologueByteSize() {
if (line_table->GetLineEntryAtIndex(idx, line_entry)) {
if (line_entry.line != first_line_entry.line) {
prologue_end_file_addr =
- line_entry.range.GetBaseAddress().GetFileAddress();
+ line_entry.GetRange().GetBaseAddress().GetFileAddress();
prologue_end_line_idx = idx;
break;
}
@@ -634,8 +634,8 @@ uint32_t Function::GetPrologueByteSize() {
if (prologue_end_file_addr == LLDB_INVALID_ADDRESS) {
prologue_end_file_addr =
- first_line_entry.range.GetBaseAddress().GetFileAddress() +
- first_line_entry.range.GetByteSize();
+ first_line_entry.GetRange().GetBaseAddress().GetFileAddress() +
+ first_line_entry.GetRange().GetByteSize();
prologue_end_line_idx = first_line_entry_idx;
}
}
@@ -659,7 +659,7 @@ uint32_t Function::GetPrologueByteSize() {
if (line_entry.line != 0)
break;
}
- if (line_entry.range.GetBaseAddress().GetFileAddress() >=
+ if (line_entry.GetRange().GetBaseAddress().GetFileAddress() >=
range_end_file_addr)
break;
@@ -670,8 +670,9 @@ uint32_t Function::GetPrologueByteSize() {
LineEntry first_non_zero_entry;
if (line_table->GetLineEntryAtIndex(first_non_zero_line,
first_non_zero_entry)) {
- line_zero_end_file_addr =
- first_non_zero_entry.range.GetBaseAddress().GetFileAddress();
+ line_zero_end_file_addr = first_non_zero_entry.GetRange()
+ .GetBaseAddress()
+ .GetFileAddress();
}
}
diff --git a/lldb/source/Symbol/LineEntry.cpp b/lldb/source/Symbol/LineEntry.cpp
index c941a6927cb93..962b2389a3b6c 100644
--- a/lldb/source/Symbol/LineEntry.cpp
+++ b/lldb/source/Symbol/LineEntry.cpp
@@ -14,13 +14,13 @@
using namespace lldb_private;
LineEntry::LineEntry()
- : range(), file_sp(std::make_shared<SupportFile>()),
+ : file_sp(std::make_shared<SupportFile>()),
original_file_sp(std::make_shared<SupportFile>()),
is_start_of_statement(0), is_start_of_basic_block(0), is_prologue_end(0),
- is_epilogue_begin(0), is_terminal_entry(0) {}
+ is_epilogue_begin(0), is_terminal_entry(0), m_range() {}
void LineEntry::Clear() {
- range.Clear();
+ m_range.reset();
file_sp = std::make_shared<SupportFile>();
original_file_sp = std::make_shared<SupportFile>();
line = LLDB_INVALID_LINE_NUMBER;
@@ -32,10 +32,19 @@ void LineEntry::Clear() {
is_terminal_entry = 0;
}
-bool LineEntry::IsValid() const {
- return range.GetBaseAddress().IsValid() && line != LLDB_INVALID_LINE_NUMBER;
+bool LineEntry::IsValid() const { return line != LLDB_INVALID_LINE_NUMBER; }
+
+const AddressRange &LineEntry::GetRange() const {
+ static AddressRange invalid_range;
+ return m_range ? *m_range : invalid_range;
+}
+
+bool LineEntry::HasValidRange() const {
+ return m_range.has_value() && m_range->GetBaseAddress().IsValid();
}
+void LineEntry::SetRange(const AddressRange &range) { m_range = range; }
+
bool LineEntry::DumpStopContext(Stream *s, bool show_fullpaths) const {
const FileSpec &file = file_sp->GetSpecOnly();
if (file) {
@@ -62,11 +71,12 @@ bool LineEntry::Dump(Stream *s, Target *target, bool show_file,
Address::DumpStyle fallback_style, bool show_range) const {
if (show_range) {
// Show address range
- if (!range.Dump(s, target, style, fallback_style))
+ if (!HasValidRange() || !GetRange().Dump(s, target, style, fallback_style))
return false;
} else {
// Show address only
- if (!range.GetBaseAddress().Dump(s, target, style, fallback_style))
+ if (!HasValidRange() ||
+ !GetRange().GetBaseAddress().Dump(s, target, style, fallback_style))
return false;
}
if (show_file)
@@ -99,11 +109,16 @@ bool LineEntry::GetDescription(Stream *s, lldb::DescriptionLevel level,
if (level == lldb::eDescriptionLevelBrief ||
level == lldb::eDescriptionLevelFull) {
if (show_address_only) {
- range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress,
- Address::DumpStyleFileAddress);
+ if (HasValidRange()) {
+ GetRange().GetBaseAddress().Dump(s, target,
+ Address::DumpStyleLoadAddress,
+ Address::DumpStyleFileAddress);
+ }
} else {
- range.Dump(s, target, Address::DumpStyleLoadAddress,
- Address::DumpStyleFileAddress);
+ if (HasValidRange()) {
+ GetRange().Dump(s, target, Address::DumpStyleLoadAddress,
+ Address::DumpStyleFileAddress);
+ }
}
*s << ": " << GetFile();
@@ -145,13 +160,13 @@ bool lldb_private::operator<(const LineEntry &a, const LineEntry &b) {
}
int LineEntry::Compare(const LineEntry &a, const LineEntry &b) {
- int result = Address::CompareFileAddress(a.range.GetBaseAddress(),
- b.range.GetBaseAddress());
+ int result = Address::CompareFileAddress(a.GetRange().GetBaseAddress(),
+ b.GetRange().GetBaseAddress());
if (result != 0)
return result;
- const lldb::addr_t a_byte_size = a.range.GetByteSize();
- const lldb::addr_t b_byte_size = b.range.GetByteSize();
+ const lldb::addr_t a_byte_size = a.GetRange().GetByteSize();
+ const lldb::addr_t b_byte_size = b.GetRange().GetByteSize();
if (a_byte_size < b_byte_size)
return -1;
@@ -183,7 +198,10 @@ AddressRange LineEntry::GetSameLineContiguousAddressRange(
bool include_inlined_functions) const {
// Add each LineEntry's range to complete_line_range until we find a
// different file / line number.
- AddressRange complete_line_range = range;
+ if (!HasValidRange())
+ return {};
+ AddressRange complete_line_range = GetRange();
+
auto symbol_context_scope = lldb::eSymbolContextLineEntry;
Declaration start_call_site(original_file_sp->GetSpecOnly(), line);
if (include_inlined_functions)
@@ -196,7 +214,8 @@ AddressRange LineEntry::GetSameLineContiguousAddressRange(
range_end.CalculateSymbolContext(&next_line_sc, symbol_context_scope);
if (!next_line_sc.line_entry.IsValid() ||
- next_line_sc.line_entry.range.GetByteSize() == 0)
+ !next_line_sc.line_entry.HasValidRange() ||
+ next_line_sc.line_entry.GetRange().GetByteSize() == 0)
break;
if (original_file_sp->Equal(*next_line_sc.line_entry.original_file_sp,
@@ -209,7 +228,7 @@ AddressRange LineEntry::GetSameLineContiguousAddressRange(
// our AddressRange by its size and continue to see if there are more
// LineEntries that we can combine. However, if there was nothing to
// extend we're done.
- if (!complete_line_range.Extend(next_line_sc.line_entry.range))
+ if (!complete_line_range.Extend(next_line_sc.line_entry.GetRange()))
break;
continue;
}
@@ -231,7 +250,7 @@ AddressRange LineEntry::GetSameLineContiguousAddressRange(
break;
// Extend our AddressRange by the size of the inlined block, but if there
// was nothing to add then we're done.
- if (!complete_line_range.Extend(next_line_sc.line_entry.range))
+ if (!complete_line_range.Extend(next_line_sc.line_entry.GetRange()))
break;
continue;
}
diff --git a/lldb/source/Symbol/LineTable.cpp b/lldb/source/Symbol/LineTable.cpp
index ae2abf5befb48..e592f9bd1cfb7 100644
--- a/lldb/source/Symbol/LineTable.cpp
+++ b/lldb/source/Symbol/LineTable.cpp
@@ -244,19 +244,20 @@ bool LineTable::ConvertEntryAtIndexToLineEntry(uint32_t idx,
if (entry.is_terminal_entry)
--file_addr;
- if (!module_sp->ResolveFileAddress(file_addr,
- line_entry.range.GetBaseAddress()))
+ AddressRange range;
+ if (!module_sp->ResolveFileAddress(file_addr, range.GetBaseAddress()))
return false;
// Now undo the decrement above.
- if (entry.is_terminal_entry)
- line_entry.range.GetBaseAddress().Slide(1);
+ if (entry.is_terminal_entry) {
+ range.GetBaseAddress().Slide(1);
+ }
if (!entry.is_terminal_entry && idx + 1 < m_entries.size())
- line_entry.range.SetByteSize(m_entries[idx + 1].file_addr -
- entry.file_addr);
+ range.SetByteSize(m_entries[idx + 1].file_addr - entry.file_addr);
else
- line_entry.range.SetByteSize(0);
+ range.SetByteSize(0);
+ line_entry.SetRange(range);
line_entry.file_sp =
m_comp_unit->GetSupportFiles().GetSupportFileAtIndex(entry.file_idx);
diff --git a/lldb/source/Symbol/Symbol.cpp b/lldb/source/Symbol/Symbol.cpp
index 40497dbccc5c3..a27e168bd8edd 100644
--- a/lldb/source/Symbol/Symbol.cpp
+++ b/lldb/source/Symbol/Symbol.cpp
@@ -330,7 +330,7 @@ uint32_t Symbol::GetPrologueByteSize() {
base_address, eSymbolContextLineEntry, sc);
if (resolved_flags & eSymbolContextLineEntry) {
// Default to the end of the first line entry.
- m_type_data = sc.line_entry.range.GetByteSize();
+ m_type_data = sc.line_entry.GetRange().GetByteSize();
// Set address for next line.
Address addr(base_address);
@@ -356,8 +356,9 @@ uint32_t Symbol::GetPrologueByteSize() {
}
// Slide addr up to the next line address.
- addr.Slide(sc_temp.line_entry.range.GetByteSize());
- total_offset += sc_temp.line_entry.range.GetByteSize();
+ addr_t slide_amount = sc_temp.line_entry.GetRange().GetByteSize();
+ addr.Slide(slide_amount);
+ total_offset += slide_amount;
// If we've gone too far, bail out.
if (total_offset >= m_addr_range.GetByteSize())
break;
diff --git a/lldb/source/Symbol/SymbolContext.cpp b/lldb/source/Symbol/SymbolContext.cpp
index 3bbd1eff824e6..f53295f7a96f1 100644
--- a/lldb/source/Symbol/SymbolContext.cpp
+++ b/lldb/source/Symbol/SymbolContext.cpp
@@ -341,8 +341,10 @@ bool SymbolContext::GetAddressRange(uint32_t scope, uint32_t range_idx,
bool use_inline_block_range,
AddressRange &range) const {
if ((scope & eSymbolContextLineEntry) && line_entry.IsValid()) {
- range = line_entry.range;
- return true;
+ if (line_entry.HasValidRange()) {
+ range = line_entry.GetRange();
+ return true;
+ }
}
if ((scope & eSymbolContextBlock) && (block != nullptr)) {
@@ -437,7 +439,9 @@ bool SymbolContext::GetParentOfInlinedScope(const Address &curr_frame_pc,
const InlineFunctionInfo *curr_inlined_block_inlined_info =
curr_inlined_block->GetInlinedFunctionInfo();
next_frame_pc = range.GetBaseAddress();
- next_frame_sc.line_entry.range.GetBaseAddress() = next_frame_pc;
+ AddressRange new_range;
+ new_range.GetBaseAddress() = next_frame_pc;
+ next_frame_sc.line_entry.SetRange(new_range);
next_frame_sc.line_entry.file_sp = std::make_shared<SupportFile>(
curr_inlined_block_inlined_info->GetCallSite().GetFile());
next_frame_sc.line_entry.original_file_sp =
@@ -668,7 +672,11 @@ SymbolContext::GetAddressRangeFromHereToEndLine(uint32_t end_line,
return llvm::createStringError("Symbol context has no line table.");
}
- range = line_entry.range;
+ if (!line_entry.HasValidRange()) {
+ return llvm::createStringError("Line entry has no valid address range.");
+ }
+
+ range = line_entry.GetRange();
if (line_entry.line > end_line) {
return llvm::createStringError(
"end line option %d must be after the current line: %d", end_line,
@@ -708,15 +716,19 @@ SymbolContext::GetAddressRangeFromHereToEndLine(uint32_t end_line,
}
Block *func_block = GetFunctionBlock();
- if (func_block && func_block->GetRangeIndexContainingAddress(
- end_entry.range.GetBaseAddress()) == UINT32_MAX) {
+ if (func_block && end_entry.HasValidRange() &&
+ func_block->GetRangeIndexContainingAddress(
+ end_entry.GetRange().GetBaseAddress()) == UINT32_MAX) {
return llvm::createStringError(
"end line number %d is not contained within the current function.",
end_line);
}
- lldb::addr_t range_size = end_entry.range.GetBaseAddress().GetFileAddress() -
- range.GetBaseAddress().GetFileAddress();
+ lldb::addr_t range_size =
+ end_entry.HasValidRange()
+ ? (end_entry.GetRange().GetBaseAddress().GetFileAddress() -
+ range.GetBaseAddress().GetFileAddress())
+ : 0;
range.SetByteSize(range_size);
return llvm::Error::success();
}
diff --git a/lldb/source/Target/ThreadPlanShouldStopHere.cpp b/lldb/source/Target/ThreadPlanShouldStopHere.cpp
index d2cca49987f0f..f345c2cc2747a 100644
--- a/lldb/source/Target/ThreadPlanShouldStopHere.cpp
+++ b/lldb/source/Target/ThreadPlanShouldStopHere.cpp
@@ -128,7 +128,7 @@ ThreadPlanSP ThreadPlanShouldStopHere::DefaultStepFromHereCallback(
sc = frame->GetSymbolContext(eSymbolContextLineEntry | eSymbolContextSymbol);
if (sc.line_entry.line == 0) {
- AddressRange range = sc.line_entry.range;
+ AddressRange range = sc.line_entry.GetRange();
bool just_step_out = false;
if (sc.symbol) {
ProcessSP process_sp(current_plan->GetThread().GetProcess());
diff --git a/lldb/source/Target/ThreadPlanStepOverRange.cpp b/lldb/source/Target/ThreadPlanStepOverRange.cpp
index 643ee827c865c..b49eeab6eb12a 100644
--- a/lldb/source/Target/ThreadPlanStepOverRange.cpp
+++ b/lldb/source/Target/ThreadPlanStepOverRange.cpp
@@ -265,7 +265,7 @@ bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) {
SupportFile::eEqualFileSpecAndChecksumIfSet)) {
SymbolContext prev_sc;
Address prev_address =
- prev_line_entry.range.GetBaseAddress();
+ prev_line_entry.GetRange().GetBaseAddress();
prev_address.CalculateSymbolContext(&prev_sc);
if (prev_sc.block) {
Block *inlined_block =
@@ -290,7 +290,7 @@ bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) {
// Make sure we haven't wandered out of the function we
// started from...
Address next_line_address =
- next_line_entry.range.GetBaseAddress();
+ next_line_entry.GetRange().GetBaseAddress();
Function *next_line_function =
next_line_address.CalculateSymbolContextFunction();
if (next_line_function != m_addr_context.function)
diff --git a/lldb/source/Target/ThreadPlanStepRange.cpp b/lldb/source/Target/ThreadPlanStepRange.cpp
index 3a9deb6f5c6fd..fb5bd18881b53 100644
--- a/lldb/source/Target/ThreadPlanStepRange.cpp
+++ b/lldb/source/Target/ThreadPlanStepRange.cpp
@@ -160,8 +160,10 @@ bool ThreadPlanStepRange::InRange() {
"stepping through that range: %s",
s.GetData());
}
- } else if (new_context.line_entry.range.GetBaseAddress().GetLoadAddress(
- &GetTarget()) != pc_load_addr) {
+ } else if (new_context.line_entry.HasValidRange() &&
+ new_context.line_entry.GetRange()
+ .GetBaseAddress()
+ .GetLoadAddress(&GetTarget()) != pc_load_addr) {
// Another thing that sometimes happens here is that we step out of
// one line into the MIDDLE of another line. So far I mostly see
// this due to bugs in the debug information. But we probably don't
@@ -170,7 +172,9 @@ bool ThreadPlanStepRange::InRange() {
// and continue.
m_addr_context = new_context;
m_address_ranges.clear();
- AddRange(m_addr_context.line_entry.range);
+ if (m_addr_context.line_entry.HasValidRange()) {
+ AddRange(m_addr_context.line_entry.GetRange());
+ }
ret_value = true;
if (log) {
StreamString s;
@@ -430,7 +434,7 @@ bool ThreadPlanStepRange::SetNextBranchBreakpoint() {
FileSpec call_site_file_spec = call_site.GetFile();
top_most_line_entry.original_file_sp =
std::make_shared<SupportFile>(call_site_file_spec);
- top_most_line_entry.range = range;
+ top_most_line_entry.SetRange(range);
top_most_line_entry.file_sp = std::make_shared<SupportFile>();
top_most_line_entry.ApplyFileMappings(
GetThread().CalculateTarget());
diff --git a/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py b/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py
index 835267221ddb4..6e66ddec48dc3 100644
--- a/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py
+++ b/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py
@@ -74,6 +74,21 @@ def __init__(self, process, args):
self.frames.append(DummyScriptedFrame(self, args, len(self.frames), "bar"))
self.frames.append(DummyScriptedFrame(self, args, len(self.frames), "foo"))
+ breakpoint()
+ cwd = os.path.dirname(os.path.abspath(__file__))
+
+ le = lldb.SBLineEntry()
+ le.SetFileSpec(lldb.SBFileSpec(os.path.join(cwd, "baz.cpp"), True))
+ le.SetLine(9)
+ le.SetColumn(10)
+
+ sym_ctx = lldb.SBSymbolContext()
+ sym_ctx.SetLineEntry(le)
+
+ self.frames.append(
+ DummyScriptedFrame(self, args, len(self.frames), "baz", sym_ctx)
+ )
+
def get_thread_id(self) -> int:
return 0x19
diff --git a/lldb/tools/lldb-test/lldb-test.cpp b/lldb/tools/lldb-test/lldb-test.cpp
index 3f198d963a93b..383409069bcc6 100644
--- a/lldb/tools/lldb-test/lldb-test.cpp
+++ b/lldb/tools/lldb-test/lldb-test.cpp
@@ -786,13 +786,18 @@ Error opts::symbols::verify(lldb_private::Module &Module) {
return make_string_error("Can't get a line entry of a compile unit.");
for (uint32_t i = 1; i < count; i++) {
- lldb::addr_t curr_end =
- le.range.GetBaseAddress().GetFileAddress() + le.range.GetByteSize();
+ lldb::addr_t curr_end = LLDB_INVALID_ADDRESS;
+ if (le.HasValidRange()) {
+ const lldb_private::AddressRange &range = le.GetRange();
+ curr_end =
+ range.GetBaseAddress().GetFileAddress() + range.GetByteSize();
+ }
if (!lt->GetLineEntryAtIndex(i, le))
return make_string_error("Can't get a line entry of a compile unit");
- if (curr_end > le.range.GetBaseAddress().GetFileAddress())
+ if (le.HasValidRange() &&
+ curr_end > le.GetRange().GetBaseAddress().GetFileAddress())
return make_string_error(
"Line table of a compile unit is inconsistent.");
}
diff --git a/lldb/unittests/Symbol/LineTableTest.cpp b/lldb/unittests/Symbol/LineTableTest.cpp
index ca63c6ff51dad..4f08eb9ed6d73 100644
--- a/lldb/unittests/Symbol/LineTableTest.cpp
+++ b/lldb/unittests/Symbol/LineTableTest.cpp
@@ -286,9 +286,14 @@ TEST_F(LineTableTest, FindLineEntryByAddress) {
LineEntry entry;
if (!table->FindLineEntryByAddress(Address(fixture->text_sp, addr), entry))
return {LLDB_INVALID_ADDRESS, LLDB_INVALID_ADDRESS, false};
- return {entry.range.GetBaseAddress().GetFileAddress(),
- entry.range.GetByteSize(),
- static_cast<bool>(entry.is_terminal_entry)};
+ if (entry.HasValidRange()) {
+ return {entry.GetRange().GetBaseAddress().GetFileAddress(),
+ entry.GetRange().GetByteSize(),
+ static_cast<bool>(entry.is_terminal_entry)};
+ } else {
+ return {LLDB_INVALID_ADDRESS, 0,
+ static_cast<bool>(entry.is_terminal_entry)};
+ }
};
EXPECT_THAT(find(0), testing::FieldsAre(0, 10, false));
More information about the lldb-commits
mailing list