Intermittent behavior while debugging swift application with LLDB

We use Buck as our swift application build system and we are getting some intermittent behaviors while debugging the app with LLDB.

When stopping at some breakpoints and running a po with some instance value of self we're getting this:

(lldb) po self.customView
error: Couldn't realize type of self.

Searching for some more information about the error with log enable lldb types expr that's what I get for this case:

 == [UserExpression::Evaluate] Parsing expression self.customView ==
 SwiftASTContextForExpressions::GetModule("Swift")
 SwiftUserExpression::ScanContext()
   [SUE::SC] Compilation unit is swift
 SwiftASTContext("CoolApplication")::ReconstructType("$s26CoolModulePresentation0A18MenuViewControllerCD")
 SwiftASTContext("CoolApplication")::ReconstructType("$s26CoolModulePresentation0A18MenuViewControllerCD") -- found in the negative cache
 could not get type metadata from address 4628814032 : an unknown failure occurred

 SwiftASTContext("CoolApplication")::ReconstructType("$s26CoolModulePresentation0A18MenuViewControllerCD")
 SwiftASTContext("CoolApplication")::ReconstructType("$s26CoolModulePresentation0A18MenuViewControllerCD") -- found in the negative cache
   [SUE::SC] Containing class name: CoolModulePresentation.CoolMenuViewController
 Parsing the following code:

extension $__lldb_context {
  @LLDBDebuggerFunction @available(iOS 14.5, *)
  final func $__lldb_wrapped_expr_0(_ $__lldb_arg : UnsafeMutablePointer<Any>) {
    
do {
/*__LLDB_USER_START__*/
self.customView
/*__LLDB_USER_END__*/
} catch (let __lldb_tmp_error) {
  var $__lldb_error_result = __lldb_tmp_error
}
... (thousand lines of loading/linking every application module)
...
SwiftASTContext("CoolApplication")::ReconstructType("$s26CoolModulePresentation0A18MenuViewControllerCD")
SwiftASTContext("CoolApplication")::ReconstructType("$s26CoolModulePresentation0A18MenuViewControllerCD") -- found in the negative cache
SwiftASTContextForExpressions::ReconstructType("$s26CoolModulePresentation0A18MenuViewControllerCD")
SwiftASTContextForExpressions::ReconstructType("$s26CoolModulePresentation0A18MenuViewControllerCD") -- not cached, searching
SwiftASTContextForExpressions::SwiftDWARFImporterDelegate::lookupValue("CoolMenuViewController")
SwiftASTContext("CoolApplication")::SwiftDWARFImporterDelegate::lookupValue("CoolMenuViewController")

thousands of ...SwiftDWARFImporterDelegate::lookupValue("CoolMenuViewController") on each application module

After some clean builds with no change in the codebase or build process, finally get some successful response:

(lldb) po self.customView

<SomeCoolModulePresentation.MenuView: 0x7fbea0883fa0; frame = (0 0; 0 0); layer = <CALayer: 0x600002f65e40>>

Lldb types expr log:

 == [UserExpression::Evaluate] Parsing expression self.customView ==
 SwiftASTContextForExpressions::GetModule("Swift")
 SwiftUserExpression::ScanContext()
   [SUE::SC] Compilation unit is swift
 SwiftASTContext("CoolApplication")::ReconstructType("$s26SomeCoolModulePresentation0A18MenuViewControllerCD")
 SwiftASTContext("CoolApplication")::ReconstructType("$s26SomeCoolModulePresentation0A18MenuViewControllerCD") -- found in the positive cache
 [self 0x7fa00a27a000] might have a dynamic type
 [self 0x7fa00a27a000] has a new dynamic type SomeCoolModulePresentation.MenuViewController
   [SUE::SC] Containing class name: SomeCoolModulePresentation.MenuViewController
 Parsing the following code:

extension $__lldb_context {
  @LLDBDebuggerFunction @available(iOS 14.5, *)
  final func $__lldb_wrapped_expr_3(_ $__lldb_arg : UnsafeMutablePointer<Any>) {
    
do {
/*__LLDB_USER_START__*/
self.customView
/*__LLDB_USER_END__*/
} catch (let __lldb_tmp_error) {
  var $__lldb_error_result = __lldb_tmp_error
}
(thousand lines of loading/linking every application module)
-- EXPR evaluation generated raw sil --
-- EXPR evaluation generated canonical sil --
-- EXPR evaluation generated IR --

Registering JITted Functions:

   Function: s26CoolModulePresentation0A18MenuViewControllerC14__lldb_expr_10E03$__g9_wrapped_H2_4yySpyypGF at 0x16be209c0.
   Function: __swift_destroy_boxed_opaque_existential_0 at 0x16be20a80.
   Function: $sSSWOh at 0x16be20ab0.
 Registering JIIted Symbols:

 == [UserExpression::Evaluate] Executing expression ==
 IRMemoryMap::Malloc process_sp=0x7fa0f50d7a18, process_sp->CanJIT()=true, process_sp->IsAlive()=true
 IRMemoryMap::Malloc (39, 0x8, 0x3, eAllocationPolicyMirror) -> 0x16bca2ed0
 EntityVariable::Materialize [address = 0x16bca2ed0, m_variable_sp = self]

SwiftASTContextForExpressions::ReconstructType("$s26SomeCoolModulePresentation0A18MenuViewControllerCD")
...
SwiftASTContextForExpressions::ReconstructType("$s26SomeCoolModulePresentation0A18MenuViewControllerCD") -- found in the positive cache
SwiftASTContextForExpressions::ReconstructType("$s26SomeCoolModulePresentation0A16MenuViewProtocol_pD")
...
SwiftASTContextForExpressions::ReconstructType("$s26SomeCoolModulePresentation0A16MenuViewProtocol_pD") -- found in the positive cache
 [$R1 0x7fa021f93200] might have a dynamic type

After cleaning the caches/derived data and running a new build the problem returned to appear. My limited knowledge about swift and lldb integration doesn't let me figure out what's different between those two cases.

The app codebase is Swift with some pre-built third-party libs (swift, obj-c, c++). To deal with Buck relative paths and be able to set breakpoints we're using some settings set target.source-map.

We're not generating dsym files to debug, only using object files embedded DWARF (only generating dsyms to symbolicate crashes). But, by generating dsym files we're getting a different error output:

(lldb) po self.customView
error: Couldn't lookup symbols:
direct field offset for SomeCoolModulePresentation.CoolMenuViewController.customView : SomeCoolModulePresentation.CoolMenuViewProtocol
1 Like

Also when trying to print description at Xcode variable view, lldb-rpc-server is crashing with the following thread stack trace:

Thread 8 Crashed:: RPC packet thread for client tid 0011883e (1148990)
0   com.apple.LLDB.framework      	0x0000000109b8c8ed (anonymous namespace)::RemoteASTContextConcreteImpl<swift::External<swift::RuntimeTarget<8u> > >::getDynamicTypeAndAddressForExistential(swift::remote::RemoteAddress, swift::Type) + 29
1   com.apple.LLDB.framework      	0x0000000109b84022 swift::remoteAST::RemoteASTContext::getDynamicTypeAndAddressForExistential(swift::remote::RemoteAddress, swift::Type) + 18
2   com.apple.LLDB.framework      	0x000000010964f0f7 lldb_private::SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_Protocol(lldb_private::ValueObject&, lldb_private::CompilerType, lldb_private::SwiftASTContextForExpressions&, lldb::DynamicValueType, lldb_private::TypeAndOrName&, lldb_private::Address&) + 471
3   com.apple.LLDB.framework      	0x0000000109650bd0 lldb_private::SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress(lldb_private::ValueObject&, lldb::DynamicValueType, lldb_private::TypeAndOrName&, lldb_private::Address&, lldb_private::Value::ValueType&) + 1024
4   com.apple.LLDB.framework      	0x00000001094abc83 lldb_private::ValueObjectDynamicValue::UpdateValue() + 547
5   com.apple.LLDB.framework      	0x000000010949c980 lldb_private::ValueObject::UpdateValueIfNeeded(bool) + 1200
6   com.apple.LLDB.framework      	0x00000001094ab607 lldb_private::ValueObjectDynamicValue::GetCompilerTypeImpl() + 23
7   com.apple.LLDB.framework      	0x000000010949d2b5 lldb_private::ValueObject::MaybeCalculateCompleteType() + 37
8   com.apple.LLDB.framework      	0x000000010949cbc4 lldb_private::ValueObject::UpdateFormatsIfNeeded() + 100
9   com.apple.LLDB.framework      	0x00000001094a2bb5 lldb_private::ValueObject::CalculateSyntheticValue() + 85
10  com.apple.LLDB.framework      	0x000000010949e859 lldb_private::ValueObject::GetSyntheticValue() + 25
11  com.apple.LLDB.framework      	0x00000001093fd47b ValueImpl::GetSP(lldb_private::ProcessRunLock::ProcessRunLocker&, std::__1::unique_lock<std::__1::recursive_mutex>&, lldb_private::Status&) + 571
12  com.apple.LLDB.framework      	0x00000001093e6b3b lldb::SBValue::GetSP(ValueLocker&) const + 139
13  com.apple.LLDB.framework      	0x00000001093e7057 lldb::SBValue::GetName() + 343
14  lldb-rpc-server               	0x0000000108f05154 rpc_server::_ZN4lldb7SBValue7GetNameEv::HandleRPCCall(rpc_common::Connection&, rpc_common::RPCStream&, rpc_common::RPCStream&) + 36
15  lldb-rpc-server               	0x0000000108f08875 rpc_common::Connection::PrivateHandleRPCPacket(rpc_common::RPCPacket&, rpc_common::RPCPacket&, bool&) + 1525
16  lldb-rpc-server               	0x0000000108f0c9da Packets::ProcessPackets() + 954
17  lldb-rpc-server               	0x0000000108f0c58a Packets::ReadThread() + 314
18  lldb-rpc-server               	0x0000000108f0c449 Packets::RunReadThread(void*) + 9
19  libsystem_pthread.dylib       	0x00007fff20555950 _pthread_start + 224
20  libsystem_pthread.dylib       	0x00007fff2055147b thread_start + 15

Hi Lucas, do you think it'd be possible to open a bug report on https://bugs.swift.org and ideally share a sample project that reproduces this issue?

Also when trying to print description at Xcode variable view, lldb-rpc-server is crashing with the following thread stack trace:

We've recently changed how the GetDynamicTypeAndAddress_Protocol works to not use remoteAST. If you'd like, you could try installing the current 5.5 toolchain and see if that error goes away.

Same errors when running po:

(lldb) po self.customView
error: Couldn't realize type of self.

The crash stack trace is a bit different:

Thread 7 Crashed:: RPC packet thread for client tid 001373c6 (1274822)
0   libsystem_kernel.dylib        	0x00007fff20527462 __pthread_kill + 10
1   libsystem_pthread.dylib       	0x00007fff20555610 pthread_kill + 263
2   libsystem_c.dylib             	0x00007fff204a87ba __abort + 139
3   libsystem_c.dylib             	0x00007fff204a872f abort + 135
4   libsystem_c.dylib             	0x00007fff204a79d6 __assert_rtn + 314
5   com.apple.LLDB.framework      	0x00000001138006d3 clang::ObjCMethodDecl::findPropertyDecl(bool) const (.cold.5) + 35
6   com.apple.LLDB.framework      	0x0000000111a01779 clang::ObjCMethodDecl::findPropertyDecl(bool) const + 889
7   com.apple.LLDB.framework      	0x000000010e9b6308 (anonymous namespace)::SwiftDeclConverter::importObjCMethodDecl(clang::ObjCMethodDecl const*, swift::DeclContext*, bool, llvm::Optional<(anonymous namespace)::AccessorInfo>) + 2216
8   com.apple.LLDB.framework      	0x000000010e9bdc24 (anonymous namespace)::SwiftDeclConverter::VisitObjCMethodDecl(clang::ObjCMethodDecl const*) + 580
9   com.apple.LLDB.framework      	0x000000010e9a8c0d swift::ClangImporter::Implementation::importDeclImpl(clang::NamedDecl const*, swift::importer::ImportNameVersion, bool&, bool&) + 861
10  com.apple.LLDB.framework      	0x000000010e9a9ce4 swift::ClangImporter::Implementation::importDeclAndCacheImpl(clang::NamedDecl const*, swift::importer::ImportNameVersion, bool, bool) + 532
11  com.apple.LLDB.framework      	0x000000010e9d6a75 bool llvm::function_ref<bool (swift::importer::ImportedName, swift::importer::ImportNameVersion)>::callback_fn<swift::ClangImporter::Implementation::insertMembersAndAlternates(clang::NamedDecl const*, llvm::SmallVectorImpl<swift::Decl*>&)::$_5>(long, swift::importer::ImportedName, swift::importer::ImportNameVersion) + 53
12  com.apple.LLDB.framework      	0x000000010e9e45cc swift::importer::NameImporter::forEachDistinctImportName(clang::NamedDecl const*, swift::importer::ImportNameVersion, llvm::function_ref<bool (swift::importer::ImportedName, swift::importer::ImportNameVersion)>) + 268
13  com.apple.LLDB.framework      	0x000000010e9ae824 swift::ClangImporter::Implementation::insertMembersAndAlternates(clang::NamedDecl const*, llvm::SmallVectorImpl<swift::Decl*>&) + 148
14  com.apple.LLDB.framework      	0x000000010e9ae6dd swift::ClangImporter::Implementation::collectMembersToAdd(clang::ObjCContainerDecl const*, swift::Decl*, swift::DeclContext*, llvm::SmallVectorImpl<swift::Decl*>&) + 157
15  com.apple.LLDB.framework      	0x000000010e9ae08a swift::ClangImporter::Implementation::loadAllMembersOfObjcContainer(swift::Decl*, clang::ObjCContainerDecl const*) + 330
16  com.apple.LLDB.framework      	0x000000010e9ade37 swift::ClangImporter::Implementation::loadAllMembers(swift::Decl*, unsigned long long) + 311
17  com.apple.LLDB.framework      	0x000000010ebfa192 swift::IterableDeclContext::loadAllMembers() const + 338
18  com.apple.LLDB.framework      	0x000000010e9a53ba swift::ClangImporter::Implementation::lookupTypeDeclDWARF(llvm::StringRef, swift::ClangTypeKind, llvm::function_ref<void (swift::TypeDecl*)>) + 330
19  com.apple.LLDB.framework      	0x000000010e992dcc swift::ClangImporter::lookupTypeDecl(llvm::StringRef, swift::ClangTypeKind, llvm::function_ref<void (swift::TypeDecl*)>) + 700
20  com.apple.LLDB.framework      	0x000000010ea75db7 swift::Demangle::ASTBuilder::createObjCClassType(llvm::StringRef) + 103
21  com.apple.LLDB.framework      	0x000000010db87a90 swift::Demangle::TypeDecoder<swift::Demangle::ASTBuilder>::decodeMangledType(swift::Demangle::Node*) + 13328
22  com.apple.LLDB.framework      	0x000000010db885ca swift::Demangle::TypeDecoder<swift::Demangle::ASTBuilder>::decodeMangledType(swift::Demangle::Node*) + 16202
23  com.apple.LLDB.framework      	0x000000010db885ca swift::Demangle::TypeDecoder<swift::Demangle::ASTBuilder>::decodeMangledType(swift::Demangle::Node*) + 16202
24  com.apple.LLDB.framework      	0x000000010db885ca swift::Demangle::TypeDecoder<swift::Demangle::ASTBuilder>::decodeMangledType(swift::Demangle::Node*) + 16202
25  com.apple.LLDB.framework      	0x000000010ea72757 swift::Demangle::getTypeForMangling(swift::ASTContext&, llvm::StringRef) + 183
26  com.apple.LLDB.framework      	0x000000010d91a172 lldb_private::SwiftASTContext::ReconstructType(lldb_private::ConstString, lldb_private::Status&) + 1250
27  com.apple.LLDB.framework      	0x000000010d8f52cc lldb_private::TypeSystemSwiftTypeRef::GetFullyUnqualifiedType(void*) + 76
28  com.apple.LLDB.framework      	0x000000010d48ea86 lldb_private::CompilerType::GetFullyUnqualifiedType() const + 38
29  com.apple.LLDB.framework      	0x000000010d3de48f lldb_private::FormatManager::GetPossibleMatches(lldb_private::ValueObject&, lldb_private::CompilerType, lldb::DynamicValueType, std::__1::vector<lldb_private::FormattersMatchCandidate, std::__1::allocator<lldb_private::FormattersMatchCandidate> >&, bool, bool, bool, bool) + 2847
30  com.apple.LLDB.framework      	0x000000010d3dd44f lldb_private::FormattersMatchData::GetMatchesVector() + 111
31  com.apple.LLDB.framework      	0x000000010d3ec8b9 void lldb_private::TypeCategoryMap::Get<std::__1::shared_ptr<lldb_private::TypeFormatImpl> >(lldb_private::FormattersMatchData&, std::__1::shared_ptr<lldb_private::TypeFormatImpl>&) + 665
32  com.apple.LLDB.framework      	0x000000010d3e1b5d std::__1::shared_ptr<lldb_private::TypeFormatImpl> lldb_private::FormatManager::GetCached<std::__1::shared_ptr<lldb_private::TypeFormatImpl> >(lldb_private::FormattersMatchData&) + 269
33  com.apple.LLDB.framework      	0x000000010d3dfc19 std::__1::shared_ptr<lldb_private::TypeFormatImpl> lldb_private::FormatManager::Get<std::__1::shared_ptr<lldb_private::TypeFormatImpl> >(lldb_private::ValueObject&, lldb::DynamicValueType) + 57
34  com.apple.LLDB.framework      	0x000000010d3dfbce lldb_private::FormatManager::GetFormat(lldb_private::ValueObject&, lldb::DynamicValueType) + 14
35  com.apple.LLDB.framework      	0x000000010d3daa93 lldb_private::DataVisualization::GetFormat(lldb_private::ValueObject&, lldb::DynamicValueType) + 51
36  com.apple.LLDB.framework      	0x000000010d3c33bb lldb_private::ValueObject::UpdateFormatsIfNeeded() + 171
37  com.apple.LLDB.framework      	0x000000010d3c9c25 lldb_private::ValueObject::CalculateSyntheticValue() + 85
38  com.apple.LLDB.framework      	0x000000010d3c5129 lldb_private::ValueObject::GetSyntheticValue() + 25
39  com.apple.LLDB.framework      	0x000000010d25664b ValueImpl::GetSP(lldb_private::ProcessRunLock::ProcessRunLocker&, std::__1::unique_lock<std::__1::recursive_mutex>&, lldb_private::Status&) + 571
40  com.apple.LLDB.framework      	0x000000010d23f7b4 lldb::SBValue::GetSP(ValueLocker&) const + 148
41  com.apple.LLDB.framework      	0x000000010d23fd26 lldb::SBValue::GetName() + 374
42  lldb-rpc-server               	0x00000001099dc154 rpc_server::_ZN4lldb7SBValue7GetNameEv::HandleRPCCall(rpc_common::Connection&, rpc_common::RPCStream&, rpc_common::RPCStream&) + 36
43  lldb-rpc-server               	0x00000001099df875 rpc_common::Connection::PrivateHandleRPCPacket(rpc_common::RPCPacket&, rpc_common::RPCPacket&, bool&) + 1525
44  lldb-rpc-server               	0x00000001099e39da Packets::ProcessPackets() + 954
45  lldb-rpc-server               	0x00000001099e358a Packets::ReadThread() + 314
46  lldb-rpc-server               	0x00000001099e3449 Packets::RunReadThread(void*) + 9
47  libsystem_pthread.dylib       	0x00007fff20555950 _pthread_start + 224
48  libsystem_pthread.dylib       	0x00007fff2055147b thread_start + 15

Binary images:

Binary Images:
...
0x10cfc2000 -  0x114d9dfff  com.apple.LLDB.framework (10.0.0git - 10.0.0git) <7A436C26-A525-3A40-92B1-350267483988> /Library/Developer/Toolchains/swift-5.5-DEVELOPMENT-SNAPSHOT-2021-08-24-a.xctoolchain/System/Library/PrivateFrameworks/LLDB.framework/Versions/A/LLDB

Don't know if there's something that I can try different on the build process, or if lldb is unable to find some artifact. Do you know if there's any check that I can do to guarantee that lldb has enough information to run normally?

Does that stack trace come from trying to print the description in the variable view as before?

Do you know if there's any check that I can do to guarantee that lldb has enough information to run normally?

I don't think so... (CC: @Adrian_Prantl to confirm if this is the case) If you could create a sample that reproduces the issue that would be great. You could also try capturing a reproducer so we could try to make sense of the issue.

Thank you for your attention :slight_smile:
Here's a sample project that reproduces the issue.
Just run make first_run, when Xcode is open just add a breakpoint at ViewController.swift:8 and try to run po self.someView at lldb

2 Likes

Just a follow up about this issue:

The problem was easy diagnosed by just running the (lldb) swift-healthcheck command which was introduced a while after this post. Some .swiftmodule was not been visible for LLDB.
Kudos for the feature, it's really useful.

Thank you guys.

1 Like