From 19c0fb5d57066e1bb0da68962b9570bcc9021ad1 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Thu, 4 Feb 2021 11:34:53 -0800 Subject: [PATCH] Avoid a false positive assertion error (NFC in NDEBUG) The try-to-interpret-objc-objects-as-swift patch triggers an assertion in the SwiftLanguageRuntime in pure Objective-C programs, which can be avoided by not calling GetDynamicTypeAndAddress() if no Swift language runtime has been initialized. --- .../lldb/Target/SwiftLanguageRuntime.h | 2 + .../Plugins/Language/Swift/SwiftLanguage.cpp | 56 +++++++++---------- lldb/source/Target/SwiftLanguageRuntime.cpp | 2 + 3 files changed, 32 insertions(+), 28 deletions(-) diff --git a/lldb/include/lldb/Target/SwiftLanguageRuntime.h b/lldb/include/lldb/Target/SwiftLanguageRuntime.h index 4411ca5898194..cea2a6026634f 100644 --- a/lldb/include/lldb/Target/SwiftLanguageRuntime.h +++ b/lldb/include/lldb/Target/SwiftLanguageRuntime.h @@ -123,6 +123,8 @@ class SwiftLanguageRuntime : public LanguageRuntime { void ModulesDidLoad(const ModuleList &module_list) override; + bool IsSwiftRuntimeInitialized(); + /// Mangling support. /// \{ /// Use these passthrough functions rather than calling into Swift directly, diff --git a/lldb/source/Plugins/Language/Swift/SwiftLanguage.cpp b/lldb/source/Plugins/Language/Swift/SwiftLanguage.cpp index c7d424e830e6d..0cc0ed0defe9b 100644 --- a/lldb/source/Plugins/Language/Swift/SwiftLanguage.cpp +++ b/lldb/source/Plugins/Language/Swift/SwiftLanguage.cpp @@ -890,34 +890,34 @@ std::vector SwiftLanguage::GetPossibleFormattersMatches( const bool check_cpp = false; const bool check_objc = false; bool canBeSwiftDynamic = - compiler_type.IsPossibleDynamicType(nullptr, check_cpp, check_objc) || - // Foundation (but really any library) may create new - // Objective-C classes at runtime and LLDB's ObjC runtime - // implementation doesn't yet get notified about this. As a - // workaround we try to interpret ObjC id pointers as Swift - // classes to make them available. - (compiler_type.GetCanonicalType().GetTypeClass() == - eTypeClassObjCObjectPointer); - - if (canBeSwiftDynamic) { - do { - lldb::ProcessSP process_sp = valobj.GetProcessSP(); - if (!process_sp) - break; - auto *runtime = SwiftLanguageRuntime::Get(process_sp); - if (runtime == nullptr) - break; - TypeAndOrName type_and_or_name; - Address address; - Value::ValueType value_type; - if (!runtime->GetDynamicTypeAndAddress( - valobj, use_dynamic, type_and_or_name, address, value_type)) - break; - if (ConstString name = type_and_or_name.GetName()) - result.push_back(name); - } while (false); - } - + compiler_type.IsPossibleDynamicType(nullptr, check_cpp, check_objc); + // Foundation (but really any library) may create new + // Objective-C classes at runtime and LLDB's ObjC runtime + // implementation doesn't yet get notified about this. As a + // workaround we try to interpret ObjC id pointers as Swift + // classes to make them available. + bool canBeObjCSwiftType = (compiler_type.GetCanonicalType().GetTypeClass() == + eTypeClassObjCObjectPointer); + + if (!canBeSwiftDynamic && !canBeObjCSwiftType) + return result; + lldb::ProcessSP process_sp = valobj.GetProcessSP(); + if (!process_sp) + return result; + auto *runtime = SwiftLanguageRuntime::Get(process_sp); + if (!runtime) + return result; + // If this condition fires, we're most likely in pure Objective-C program. + if (canBeObjCSwiftType && !runtime->IsSwiftRuntimeInitialized()) + return result; + TypeAndOrName type_and_or_name; + Address address; + Value::ValueType value_type; + if (!runtime->GetDynamicTypeAndAddress(valobj, use_dynamic, type_and_or_name, + address, value_type)) + return result; + if (ConstString name = type_and_or_name.GetName()) + result.push_back(name); return result; } diff --git a/lldb/source/Target/SwiftLanguageRuntime.cpp b/lldb/source/Target/SwiftLanguageRuntime.cpp index 3a65ffae8571d..bdf20a8f459ec 100644 --- a/lldb/source/Target/SwiftLanguageRuntime.cpp +++ b/lldb/source/Target/SwiftLanguageRuntime.cpp @@ -513,6 +513,8 @@ SwiftLanguageRuntime::SwiftLanguageRuntime(Process *process) m_stub = std::make_unique(*process); } +bool SwiftLanguageRuntime::IsSwiftRuntimeInitialized() { return (bool)m_impl; } + void SwiftLanguageRuntime::ModulesDidLoad(const ModuleList &module_list) { assert(m_process && "modules loaded without process"); if (m_impl) {