Skip to content

Commit ffda8c1

Browse files
author
git apple-llvm automerger
committed
Merge commit '917ed99d815a' from llvm.org/main into next
2 parents 7a3c5a6 + 917ed99 commit ffda8c1

File tree

2 files changed

+69
-41
lines changed

2 files changed

+69
-41
lines changed

lldb/source/Commands/CommandObjectThread.cpp

Lines changed: 30 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -959,7 +959,6 @@ class CommandObjectThreadUntil : public CommandObjectParsed {
959959
}
960960

961961
LineEntry function_start;
962-
uint32_t index_ptr = 0, end_ptr = UINT32_MAX;
963962
std::vector<addr_t> address_list;
964963

965964
// Find the beginning & end index of the function, but first make
@@ -970,19 +969,14 @@ class CommandObjectThreadUntil : public CommandObjectParsed {
970969
return;
971970
}
972971

973-
AddressRange fun_addr_range = sc.function->GetAddressRange();
974-
Address fun_start_addr = fun_addr_range.GetBaseAddress();
975-
line_table->FindLineEntryByAddress(fun_start_addr, function_start,
976-
&index_ptr);
977-
978-
Address fun_end_addr(fun_start_addr.GetSection(),
979-
fun_start_addr.GetOffset() +
980-
fun_addr_range.GetByteSize());
981-
982-
bool all_in_function = true;
972+
RangeVector<uint32_t, uint32_t> line_idx_ranges;
973+
for (const AddressRange &range : sc.function->GetAddressRanges()) {
974+
auto [begin, end] = line_table->GetLineEntryIndexRange(range);
975+
line_idx_ranges.Append(begin, end - begin);
976+
}
977+
line_idx_ranges.Sort();
983978

984-
line_table->FindLineEntryByAddress(fun_end_addr, function_start,
985-
&end_ptr);
979+
bool found_something = false;
986980

987981
// Since not all source lines will contribute code, check if we are
988982
// setting the breakpoint on the exact line number or the nearest
@@ -991,45 +985,43 @@ class CommandObjectThreadUntil : public CommandObjectParsed {
991985
for (uint32_t line_number : line_numbers) {
992986
LineEntry line_entry;
993987
bool exact = false;
994-
uint32_t start_idx_ptr = index_ptr;
995-
start_idx_ptr = sc.comp_unit->FindLineEntry(
996-
index_ptr, line_number, nullptr, exact, &line_entry);
997-
if (start_idx_ptr != UINT32_MAX)
998-
line_number = line_entry.line;
988+
if (sc.comp_unit->FindLineEntry(0, line_number, nullptr, exact,
989+
&line_entry) == UINT32_MAX)
990+
continue;
991+
992+
found_something = true;
993+
line_number = line_entry.line;
999994
exact = true;
1000-
start_idx_ptr = index_ptr;
1001-
while (start_idx_ptr <= end_ptr) {
1002-
start_idx_ptr = sc.comp_unit->FindLineEntry(
1003-
start_idx_ptr, line_number, nullptr, exact, &line_entry);
1004-
if (start_idx_ptr == UINT32_MAX)
1005-
break;
1006-
1007-
addr_t address =
1008-
line_entry.range.GetBaseAddress().GetLoadAddress(target);
1009-
if (address != LLDB_INVALID_ADDRESS) {
1010-
if (fun_addr_range.ContainsLoadAddress(address, target))
995+
uint32_t end_func_idx = line_idx_ranges.GetMaxRangeEnd(0);
996+
uint32_t idx = sc.comp_unit->FindLineEntry(
997+
line_idx_ranges.GetMinRangeBase(UINT32_MAX), line_number, nullptr,
998+
exact, &line_entry);
999+
while (idx < end_func_idx) {
1000+
if (line_idx_ranges.FindEntryIndexThatContains(idx) != UINT32_MAX) {
1001+
addr_t address =
1002+
line_entry.range.GetBaseAddress().GetLoadAddress(target);
1003+
if (address != LLDB_INVALID_ADDRESS)
10111004
address_list.push_back(address);
1012-
else
1013-
all_in_function = false;
10141005
}
1015-
start_idx_ptr++;
1006+
idx = sc.comp_unit->FindLineEntry(idx + 1, line_number, nullptr,
1007+
exact, &line_entry);
10161008
}
10171009
}
10181010

10191011
for (lldb::addr_t address : m_options.m_until_addrs) {
1020-
if (fun_addr_range.ContainsLoadAddress(address, target))
1012+
AddressRange unused;
1013+
if (sc.function->GetRangeContainingLoadAddress(address, *target,
1014+
unused))
10211015
address_list.push_back(address);
1022-
else
1023-
all_in_function = false;
10241016
}
10251017

10261018
if (address_list.empty()) {
1027-
if (all_in_function)
1019+
if (found_something)
10281020
result.AppendErrorWithFormat(
1029-
"No line entries matching until target.\n");
1021+
"Until target outside of the current function.\n");
10301022
else
10311023
result.AppendErrorWithFormat(
1032-
"Until target outside of the current function.\n");
1024+
"No line entries matching until target.\n");
10331025

10341026
return;
10351027
}

lldb/test/API/functionalities/thread/step_until/TestStepUntil.py

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,18 @@ def setUp(self):
1616
self.less_than_two = line_number("main.c", "Less than 2")
1717
self.greater_than_two = line_number("main.c", "Greater than or equal to 2.")
1818
self.back_out_in_main = line_number("main.c", "Back out in main")
19+
self.in_foo = line_number("main.c", "In foo")
20+
21+
def _build_dict_for_discontinuity(self):
22+
return dict(
23+
CFLAGS_EXTRAS="-funique-basic-block-section-names "
24+
+ "-ffunction-sections -fbasic-block-sections=list="
25+
+ self.getSourcePath("function.list"),
26+
LD_EXTRAS="-Wl,--script=" + self.getSourcePath("symbol.order"),
27+
)
1928

20-
def common_setup(self, args):
21-
self.build()
29+
def _common_setup(self, build_dict, args):
30+
self.build(dictionary=build_dict)
2231
exe = self.getBuildArtifact("a.out")
2332

2433
target = self.dbg.CreateTarget(exe)
@@ -45,7 +54,7 @@ def common_setup(self, args):
4554
return thread
4655

4756
def do_until(self, args, until_lines, expected_linenum):
48-
thread = self.common_setup(args)
57+
thread = self._common_setup(None, args)
4958

5059
cmd_interp = self.dbg.GetCommandInterpreter()
5160
ret_obj = lldb.SBCommandReturnObject()
@@ -88,3 +97,30 @@ def test_missing_one(self):
8897
self.do_until(
8998
["foo", "bar", "baz"], [self.less_than_two], self.back_out_in_main
9099
)
100+
101+
@no_debug_info_test
102+
def test_bad_line(self):
103+
"""Test that we get an error if attempting to step outside the current
104+
function"""
105+
thread = self._common_setup(None, None)
106+
self.expect(
107+
f"thread until {self.in_foo}",
108+
substrs=["Until target outside of the current function"],
109+
error=True,
110+
)
111+
112+
@no_debug_info_test
113+
@skipIf(oslist=lldbplatformutil.getDarwinOSTriples() + ["windows"])
114+
@skipIf(archs=no_match(["x86_64", "aarch64"]))
115+
def test_bad_line_discontinuous(self):
116+
"""Test that we get an error if attempting to step outside the current
117+
function -- and the function is discontinuous"""
118+
self.build(dictionary=self._build_dict_for_discontinuity())
119+
_, _, thread, _ = lldbutil.run_to_source_breakpoint(
120+
self, "At the start", lldb.SBFileSpec(self.main_source)
121+
)
122+
self.expect(
123+
f"thread until {self.in_foo}",
124+
substrs=["Until target outside of the current function"],
125+
error=True,
126+
)

0 commit comments

Comments
 (0)