Skip to content

Commit 94a43de

Browse files
authored
Merge pull request #2958 from apple/merge-db98a70056ad8e84f90487ca3ea4205f2243dae2-into-5.5
Merge db98a70 into 5.5
2 parents 3e7d153 + 37c6079 commit 94a43de

File tree

16 files changed

+348
-157
lines changed

16 files changed

+348
-157
lines changed

clang/lib/Index/IndexDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -759,7 +759,7 @@ bool IndexingContext::indexDeclContext(const DeclContext *DC) {
759759
}
760760

761761
bool IndexingContext::indexTopLevelDecl(const Decl *D) {
762-
if (D->getLocation().isInvalid())
762+
if (!D || D->getLocation().isInvalid())
763763
return true;
764764

765765
if (isa<ObjCMethodDecl>(D))

lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3665,12 +3665,25 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
36653665
__FUNCTION__, arg, process->GetID());
36663666

36673667
EventSP event_sp;
3668+
3669+
// We need to ignore any packets that come in after we have
3670+
// have decided the process has exited. There are some
3671+
// situations, for instance when we try to interrupt a running
3672+
// process and the interrupt fails, where another packet might
3673+
// get delivered after we've decided to give up on the process.
3674+
// But once we've decided we are done with the process we will
3675+
// not be in a state to do anything useful with new packets.
3676+
// So it is safer to simply ignore any remaining packets by
3677+
// explicitly checking for eStateExited before reentering the
3678+
// fetch loop.
3679+
36683680
bool done = false;
3669-
while (!done) {
3681+
while (!done && process->GetPrivateState() != eStateExited) {
36703682
LLDB_LOGF(log,
36713683
"ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
36723684
") listener.WaitForEvent (NULL, event_sp)...",
36733685
__FUNCTION__, arg, process->GetID());
3686+
36743687
if (process->m_async_listener_sp->GetEvent(event_sp, llvm::None)) {
36753688
const uint32_t event_type = event_sp->GetType();
36763689
if (event_sp->BroadcasterIs(&process->m_async_broadcaster)) {
@@ -3769,6 +3782,7 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
37693782
} else {
37703783
process->SetExitStatus(-1, "lost connection");
37713784
}
3785+
done = true;
37723786
break;
37733787
}
37743788

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1961,6 +1961,8 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(
19611961
const SourceLocationSpec &src_location_spec,
19621962
SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
19631963
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1964+
const FileSpec &file_spec = src_location_spec.GetFileSpec();
1965+
const uint32_t line = src_location_spec.GetLine().getValueOr(0);
19641966
const bool check_inlines = src_location_spec.GetCheckInlines();
19651967
const uint32_t prev_size = sc_list.GetSize();
19661968
if (resolve_scope & eSymbolContextCompUnit) {
@@ -1973,7 +1975,72 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(
19731975
bool file_spec_matches_cu_file_spec = FileSpec::Match(
19741976
src_location_spec.GetFileSpec(), dc_cu->GetPrimaryFile());
19751977
if (check_inlines || file_spec_matches_cu_file_spec) {
1976-
dc_cu->ResolveSymbolContext(src_location_spec, resolve_scope, sc_list);
1978+
SymbolContext sc(m_objfile_sp->GetModule());
1979+
sc.comp_unit = dc_cu;
1980+
uint32_t file_idx = UINT32_MAX;
1981+
1982+
// If we are looking for inline functions only and we don't find it
1983+
// in the support files, we are done.
1984+
if (check_inlines) {
1985+
file_idx =
1986+
sc.comp_unit->GetSupportFiles().FindFileIndex(1, file_spec, true);
1987+
if (file_idx == UINT32_MAX)
1988+
continue;
1989+
}
1990+
1991+
if (line != 0) {
1992+
LineTable *line_table = sc.comp_unit->GetLineTable();
1993+
1994+
if (line_table != nullptr && line != 0) {
1995+
// We will have already looked up the file index if we are
1996+
// searching for inline entries.
1997+
if (!check_inlines)
1998+
file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex(
1999+
1, file_spec, true);
2000+
2001+
if (file_idx != UINT32_MAX) {
2002+
uint32_t found_line;
2003+
uint16_t found_column;
2004+
uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex(
2005+
0, file_idx, src_location_spec, &sc.line_entry);
2006+
found_line = sc.line_entry.line;
2007+
found_column = sc.line_entry.column;
2008+
2009+
while (line_idx != UINT32_MAX) {
2010+
sc.function = nullptr;
2011+
sc.block = nullptr;
2012+
if (resolve_scope &
2013+
(eSymbolContextFunction | eSymbolContextBlock)) {
2014+
const lldb::addr_t file_vm_addr =
2015+
sc.line_entry.range.GetBaseAddress().GetFileAddress();
2016+
if (file_vm_addr != LLDB_INVALID_ADDRESS) {
2017+
ResolveFunctionAndBlock(
2018+
file_vm_addr, resolve_scope & eSymbolContextBlock, sc);
2019+
}
2020+
}
2021+
2022+
SourceLocationSpec found_location_spec(
2023+
file_spec, found_line, found_column,
2024+
/*check_inlines=*/false, /*exact=*/true);
2025+
sc_list.Append(sc);
2026+
line_idx = line_table->FindLineEntryIndexByFileIndex(
2027+
line_idx + 1, file_idx, found_location_spec,
2028+
&sc.line_entry);
2029+
}
2030+
}
2031+
} else if (file_spec_matches_cu_file_spec && !check_inlines) {
2032+
// only append the context if we aren't looking for inline call
2033+
// sites by file and line and if the file spec matches that of
2034+
// the compile unit
2035+
sc_list.Append(sc);
2036+
}
2037+
} else if (file_spec_matches_cu_file_spec && !check_inlines) {
2038+
// only append the context if we aren't looking for inline call
2039+
// sites by file and line and if the file spec matches that of
2040+
// the compile unit
2041+
sc_list.Append(sc);
2042+
}
2043+
19772044
if (!check_inlines)
19782045
break;
19792046
}

lldb/source/Symbol/CompileUnit.cpp

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -254,18 +254,6 @@ void CompileUnit::ResolveSymbolContext(
254254
if (!file_spec_matches_cu_file_spec && !check_inlines)
255255
return;
256256

257-
SymbolContext sc(GetModule());
258-
sc.comp_unit = this;
259-
260-
if (line == 0) {
261-
if (file_spec_matches_cu_file_spec && !check_inlines) {
262-
// only append the context if we aren't looking for inline call sites by
263-
// file and line and if the file spec matches that of the compile unit
264-
sc_list.Append(sc);
265-
}
266-
return;
267-
}
268-
269257
uint32_t file_idx =
270258
GetSupportFiles().FindFileIndex(0, file_spec, true);
271259
while (file_idx != UINT32_MAX) {
@@ -277,15 +265,23 @@ void CompileUnit::ResolveSymbolContext(
277265
if (num_file_indexes == 0)
278266
return;
279267

280-
LineTable *line_table = sc.comp_unit->GetLineTable();
268+
SymbolContext sc(GetModule());
269+
sc.comp_unit = this;
281270

282-
if (line_table == nullptr) {
271+
if (line == 0) {
283272
if (file_spec_matches_cu_file_spec && !check_inlines) {
273+
// only append the context if we aren't looking for inline call sites by
274+
// file and line and if the file spec matches that of the compile unit
284275
sc_list.Append(sc);
285276
}
286277
return;
287278
}
288279

280+
LineTable *line_table = sc.comp_unit->GetLineTable();
281+
282+
if (line_table == nullptr)
283+
return;
284+
289285
uint32_t line_idx;
290286
LineEntry line_entry;
291287

lldb/source/Target/Target.cpp

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1810,19 +1810,30 @@ size_t Target::ReadMemory(const Address &addr, void *dst, size_t dst_len,
18101810
if (!resolved_addr.IsValid())
18111811
resolved_addr = addr;
18121812

1813-
bool is_readonly = false;
1813+
// If we read from the file cache but can't get as many bytes as requested,
1814+
// we keep the result around in this buffer, in case this result is the
1815+
// best we can do.
1816+
std::unique_ptr<uint8_t[]> file_cache_read_buffer;
1817+
size_t file_cache_bytes_read = 0;
1818+
18141819
// Read from file cache if read-only section.
18151820
if (!force_live_memory && resolved_addr.IsSectionOffset()) {
18161821
SectionSP section_sp(resolved_addr.GetSection());
18171822
if (section_sp) {
18181823
auto permissions = Flags(section_sp->GetPermissions());
1819-
is_readonly = !permissions.Test(ePermissionsWritable) &&
1820-
permissions.Test(ePermissionsReadable);
1821-
}
1822-
if (is_readonly) {
1823-
bytes_read = ReadMemoryFromFileCache(resolved_addr, dst, dst_len, error);
1824-
if (bytes_read > 0)
1825-
return bytes_read;
1824+
bool is_readonly = !permissions.Test(ePermissionsWritable) &&
1825+
permissions.Test(ePermissionsReadable);
1826+
if (is_readonly) {
1827+
file_cache_bytes_read =
1828+
ReadMemoryFromFileCache(resolved_addr, dst, dst_len, error);
1829+
if (file_cache_bytes_read == dst_len)
1830+
return file_cache_bytes_read;
1831+
else if (file_cache_bytes_read > 0) {
1832+
file_cache_read_buffer =
1833+
std::make_unique<uint8_t[]>(file_cache_bytes_read);
1834+
std::memcpy(file_cache_read_buffer.get(), dst, file_cache_bytes_read);
1835+
}
1836+
}
18261837
}
18271838
}
18281839

@@ -1861,7 +1872,14 @@ size_t Target::ReadMemory(const Address &addr, void *dst, size_t dst_len,
18611872
}
18621873
}
18631874

1864-
if (!is_readonly && resolved_addr.IsSectionOffset()) {
1875+
if (file_cache_read_buffer && file_cache_bytes_read > 0) {
1876+
// Reading from the process failed. If we've previously succeeded in reading
1877+
// something from the file cache, then copy that over and return that.
1878+
std::memcpy(dst, file_cache_read_buffer.get(), file_cache_bytes_read);
1879+
return file_cache_bytes_read;
1880+
}
1881+
1882+
if (!file_cache_read_buffer && resolved_addr.IsSectionOffset()) {
18651883
// If we didn't already try and read from the object file cache, then try
18661884
// it after failing to read from the process.
18671885
return ReadMemoryFromFileCache(resolved_addr, dst, dst_len, error);
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
from __future__ import print_function
2+
import lldb
3+
from lldbsuite.test.lldbtest import *
4+
from lldbsuite.test.decorators import *
5+
from gdbclientutils import *
6+
7+
8+
class TestHaltFails(GDBRemoteTestBase):
9+
10+
class MyResponder(MockGDBServerResponder):
11+
12+
def setBreakpoint(self, packet):
13+
return "OK"
14+
15+
def interrupt(self):
16+
# Simulate process waiting longer than the interrupt
17+
# timeout to stop, then sending the reply.
18+
time.sleep(14)
19+
return "T02reason:signal"
20+
21+
def cont(self):
22+
# No response, wait for the client to interrupt us.
23+
return None
24+
25+
def wait_for_and_check_event(self, wait_time, value):
26+
event = lldb.SBEvent()
27+
got_event = self.dbg.GetListener().WaitForEvent(wait_time, event)
28+
self.assertTrue(got_event, "Failed to get event after wait")
29+
self.assertTrue(lldb.SBProcess.EventIsProcessEvent(event), "Event was not a process event")
30+
event_type = lldb.SBProcess.GetStateFromEvent(event)
31+
self.assertEqual(event_type, value)
32+
33+
def get_to_running(self):
34+
self.server.responder = self.MyResponder()
35+
self.target = self.createTarget("a.yaml")
36+
process = self.connect(self.target)
37+
self.dbg.SetAsync(True)
38+
39+
# There should be a stopped event, consume that:
40+
self.wait_for_and_check_event(2, lldb.eStateStopped)
41+
process.Continue()
42+
43+
# There should be a running event, consume that:
44+
self.wait_for_and_check_event(2, lldb.eStateRunning)
45+
return process
46+
47+
@skipIfReproducer # FIXME: Unexpected packet during (passive) replay
48+
def test_destroy_while_running(self):
49+
process = self.get_to_running()
50+
process.Destroy()
51+
52+
# Again pretend that after failing to be interrupted, we delivered the stop
53+
# and make sure we still exit properly.
54+
self.wait_for_and_check_event(14, lldb.eStateExited)
55+
56+
@skipIfReproducer # FIXME: Unexpected packet during (passive) replay
57+
def test_async_interrupt(self):
58+
"""
59+
Test that explicitly calling AsyncInterrupt, which then fails, leads
60+
to an "eStateExited" state.
61+
"""
62+
process = self.get_to_running()
63+
# Now do the interrupt:
64+
process.SendAsyncInterrupt()
65+
66+
# That should have caused the Halt to time out and we should
67+
# be in eStateExited:
68+
self.wait_for_and_check_event(15, lldb.eStateExited)
69+
70+
71+
72+

0 commit comments

Comments
 (0)