Skip to content

Commit fd0b760

Browse files
Merge pull request #6048 from adrian-prantl/deadlock
Work around an infinite recursion with deadlock that only exists on
2 parents 16e1dfb + 5ac442f commit fd0b760

File tree

5 files changed

+53
-33
lines changed

5 files changed

+53
-33
lines changed

lldb/include/lldb/Expression/IRExecutionUnit.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,9 @@ class IRExecutionUnit : public std::enable_shared_from_this<IRExecutionUnit>,
391391
std::vector<ConstString> m_failed_lookups;
392392

393393
std::atomic<bool> m_did_jit;
394+
// BEGIN SWIFT
395+
std::atomic<bool> m_in_populate_symtab = false;
396+
// END SWIFT
394397

395398
lldb::addr_t m_function_load_addr;
396399
lldb::addr_t m_function_end_load_addr;

lldb/packages/Python/lldbsuite/test/lldbplaygroundrepl.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ def execute_code(self, inputFile):
7777

7878
with open(inputFile, 'r') as contents_file:
7979
contents = contents_file.read()
80-
self.expect("log enable lldb types expr -f /tmp/types.log")
8180
result = self.frame.EvaluateExpression(contents, self.options)
8281
output = self.frame.EvaluateExpression("get_output()")
8382
with recording(self, self.TraceOn()) as sbuf:

lldb/source/Expression/IRExecutionUnit.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -839,17 +839,20 @@ IRExecutionUnit::FindInSymbols(const std::vector<ConstString> &names,
839839
}
840840

841841
if (sc.target_sp) {
842+
ModuleList images = sc.target_sp->GetImages();
843+
// BEGIN SWIFT
844+
if (m_in_populate_symtab)
845+
if (lldb::ModuleSP module_sp = m_jit_module_wp.lock())
846+
images.Remove(module_sp);
847+
// END SWIFT
848+
842849
SymbolContextList sc_list;
843-
sc.target_sp->GetImages().FindFunctions(name, lldb::eFunctionNameTypeFull,
844-
function_options, sc_list);
850+
images.FindFunctions(name, lldb::eFunctionNameTypeFull, function_options,
851+
sc_list);
845852
if (auto load_addr = resolver.Resolve(sc_list))
846853
return *load_addr;
847-
}
848854

849-
if (sc.target_sp) {
850-
SymbolContextList sc_list;
851-
sc.target_sp->GetImages().FindSymbolsWithNameAndType(
852-
name, lldb::eSymbolTypeAny, sc_list);
855+
images.FindSymbolsWithNameAndType(name, lldb::eSymbolTypeAny, sc_list);
853856
if (auto load_addr = resolver.Resolve(sc_list))
854857
return *load_addr;
855858
}
@@ -1194,6 +1197,9 @@ uint32_t IRExecutionUnit::GetAddressByteSize() const {
11941197

11951198
void IRExecutionUnit::PopulateSymtab(lldb_private::ObjectFile *obj_file,
11961199
lldb_private::Symtab &symtab) {
1200+
// BEGIN SWIFT
1201+
m_in_populate_symtab = true;
1202+
auto _ = llvm::make_scope_exit([this]() { m_in_populate_symtab = false; });
11971203
if (m_execution_engine_up) {
11981204
uint32_t symbol_id = 0;
11991205
lldb_private::SectionList *section_list = obj_file->GetSectionList();
@@ -1271,6 +1277,7 @@ void IRExecutionUnit::PopulateSymtab(lldb_private::ObjectFile *obj_file,
12711277
}
12721278
}
12731279
}
1280+
// END SWIFT
12741281
}
12751282

12761283
void IRExecutionUnit::PopulateSectionList(
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import Dylib
2+
f()

lldb/test/API/lang/swift/playgrounds/TestSwiftPlaygrounds.py

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ def test_no_force_target(self):
8888
@swiftTest
8989
@skipIf(setting=('symbols.use-swift-clangimporter', 'false'))
9090
@skipIf(debug_info=decorators.no_match("dsym"))
91+
@skipIf(macos_version=["<", "12"])
9192
def test_concurrency(self):
9293
"""Test that concurrency is available in playgrounds"""
9394
self.launch(True)
@@ -100,8 +101,7 @@ def test_concurrency(self):
100101
def test_import(self):
101102
"""Test that a dylib can be imported in playgrounds"""
102103
self.launch(True)
103-
self.do_concurrency_test()
104-
104+
self.do_import_test()
105105

106106
def launch(self, force_target):
107107
"""Test that playgrounds work"""
@@ -145,47 +145,56 @@ def launch(self, force_target):
145145
self.options.SetTryAllThreads(True)
146146

147147

148-
def do_basic_test(self, force_target):
149-
contents = ""
150-
151-
with open('Contents.swift', 'r') as contents_file:
148+
def execute_code(self, input_file, expect_error=False):
149+
contents = "syntax error"
150+
with open(input_file, 'r') as contents_file:
152151
contents = contents_file.read()
153-
154-
self.frame().EvaluateExpression(contents, self.options)
152+
res = self.frame().EvaluateExpression(contents, self.options)
155153
ret = self.frame().EvaluateExpression("get_output()")
154+
is_error = res.GetError().Fail() and not (
155+
res.GetError().GetType() == 1 and
156+
res.GetError().GetError() == 0x1001)
156157
playground_output = ret.GetSummary()
158+
with recording(self, self.TraceOn()) as sbuf:
159+
print("playground result: ", file=sbuf)
160+
print(str(res), file=sbuf)
161+
if is_error:
162+
print("error:", file=sbuf)
163+
print(str(res.GetError()), file=sbuf)
164+
else:
165+
print("playground output:", file=sbuf)
166+
print(str(ret), file=sbuf)
167+
168+
if expect_error:
169+
self.assertTrue(is_error)
170+
return playground_output
171+
self.assertFalse(is_error)
172+
self.assertIsNotNone(playground_output)
173+
return playground_output
174+
175+
def do_basic_test(self, force_target):
176+
playground_output = self.execute_code('Contents.swift', not force_target)
157177
if not force_target:
158178
# This is expected to fail because the deployment target
159179
# is less than the availability of the function being
160180
# called.
161181
self.assertEqual(playground_output, '""')
162182
return
163183

164-
self.assertTrue(playground_output is not None)
165-
self.assertTrue("a=\\'3\\'" in playground_output)
166-
self.assertTrue("b=\\'5\\'" in playground_output)
167-
self.assertTrue("=\\'8\\'" in playground_output)
168-
self.assertTrue("=\\'11\\'" in playground_output)
184+
self.assertIn("a=\\'3\\'", playground_output)
185+
self.assertIn("b=\\'5\\'", playground_output)
186+
self.assertIn("=\\'8\\'", playground_output)
187+
self.assertIn("=\\'11\\'", playground_output)
169188

170189
def do_concurrency_test(self):
171-
contents = "error"
172-
with open('Concurrency.swift', 'r') as contents_file:
173-
contents = contents_file.read()
174-
res = self.frame().EvaluateExpression(contents, self.options)
175-
ret = self.frame().EvaluateExpression("get_output()")
176-
playground_output = ret.GetSummary()
177-
self.assertTrue(playground_output is not None)
190+
playground_output = self.execute_code('Concurrency.swift')
178191
self.assertIn("=\\'23\\'", playground_output)
179192

180193
def do_import_test(self):
181194
# Test importing a library that adds new Clang options.
182195
log = self.getBuildArtifact('types.log')
183196
self.expect('log enable lldb types -f ' + log)
184-
contents = "import Dylib\nf()\n"
185-
res = self.frame().EvaluateExpression(contents, self.options)
186-
ret = self.frame().EvaluateExpression("get_output()")
187-
playground_output = ret.GetSummary()
188-
self.assertTrue(playground_output is not None)
197+
playground_output = self.execute_code('Import.swift')
189198
self.assertIn("Hello from the Dylib", playground_output)
190199

191200
# Scan through the types log to make sure the SwiftASTContext was poisoned.

0 commit comments

Comments
 (0)