From 11aad7c3eab3e76e4588757accd32f76517f289f Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Fri, 7 Mar 2025 12:55:34 -0800 Subject: [PATCH 1/2] [lldb] Resolve Swift-implemented Objective-C classes using Swift runtime if the Objective-C runtime fails. This is a minimally invasive patch for the swift/release/6.1 branch to fix a problem with some versions of the Objective-C runtime. If an Objective-C class is lazy, the Objective-C runtie may not have materialized class metadata for it. However, if the class is actually implemented in Swift, we can still resolve it using the Swift runtime. We should probably also add the same logic to the Objective-C runtime, but I don't want risk adding an inifinite recursion this late in the release. --- .../Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp index fc011501c0a86..40f22dfe02d5d 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp @@ -1831,7 +1831,8 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Class( }); return found; } - return false; + // Fall through. Swift-implemented Objective-C types may still + // be resolvable through the Swift class metadata. } Log *log(GetLog(LLDBLog::Types)); // Scope reflection_ctx to minimize its lock scope. From 09fdf2b5d1691eaf034f0159dc5f337c0cfb7092 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Fri, 7 Mar 2025 17:18:08 -0800 Subject: [PATCH 2/2] WIP --- ...ftLanguageRuntimeDynamicTypeResolution.cpp | 55 ++++++++++++++----- 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp index 40f22dfe02d5d..8a77d7c8341ba 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp @@ -1799,15 +1799,28 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Class( if (!error.Success()) return false; + bool is_clang_type = false; auto tss = class_type.GetTypeSystem().dyn_cast_or_null(); + if (!tss) { + is_clang_type = true; + auto module_sp = in_value.GetModule(); + auto type_system_or_err = + module_sp->GetTypeSystemForLanguage(lldb::eLanguageTypeSwift); + if (!type_system_or_err) { + llvm::consumeError(type_system_or_err.takeError()); + return false; + } + auto ts_sp = *type_system_or_err; + tss = llvm::cast(ts_sp.get())->GetTypeSystemSwiftTypeRef(); + } if (!tss) return false; + address.SetRawAddress(instance_ptr); auto ts = tss->GetTypeSystemSwiftTypeRef(); if (!ts) return false; - // Ask the Objective-C runtime about Objective-C types. - if (tss->IsImportedType(class_type.GetOpaqueQualType(), nullptr)) + auto resolve_objc = [&]() { if (auto *objc_runtime = SwiftLanguageRuntime::GetObjCRuntime(GetProcess())) { Value::ValueType value_type; @@ -1831,12 +1844,12 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Class( }); return found; } - // Fall through. Swift-implemented Objective-C types may still - // be resolvable through the Swift class metadata. } - Log *log(GetLog(LLDBLog::Types)); - // Scope reflection_ctx to minimize its lock scope. - { + return false; + }; + + auto resolve_swift = [&]() { + // Scope reflection_ctx to minimize its lock scope. ThreadSafeReflectionContext reflection_ctx = GetReflectionContext(); if (!reflection_ctx) return false; @@ -1859,9 +1872,19 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Class( swift::Demangle::Demangler dem; swift::Demangle::NodePointer node = typeref->getDemangling(dem); CompilerType dynamic_type = ts->RemangleAsType(dem, node); - LLDB_LOG(log, "dynamic type of instance_ptr {0:x} is {1}", instance_ptr, + LLDB_LOG(GetLog(LLDBLog::Types), + "dynamic type of instance_ptr {0:x} is {1}", instance_ptr, class_type.GetMangledTypeName()); class_type_or_name.SetCompilerType(dynamic_type); + return true; + }; + + if (!resolve_swift()) { + // Ask the Objective-C runtime about Objective-C types. + if (is_clang_type || !tss->IsImportedType(class_type.GetOpaqueQualType(), nullptr)) + if (resolve_objc()) + return true; + return false; } #ifndef NDEBUG @@ -2711,21 +2734,27 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress( return false; LLDB_SCOPED_TIMER(); + CompilerType val_type(in_value.GetCompilerType()); + Value::ValueType static_value_type = Value::ValueType::Invalid; // Try to import a Clang type into Swift. - if (in_value.GetObjectRuntimeLanguage() == eLanguageTypeObjC) - return GetDynamicTypeAndAddress_ClangType( - in_value, use_dynamic, class_type_or_name, address, value_type); + if (in_value.GetObjectRuntimeLanguage() == eLanguageTypeObjC) { + if (GetDynamicTypeAndAddress_ClangType( + in_value, use_dynamic, class_type_or_name, address, value_type)) + return true; + else + return GetDynamicTypeAndAddress_Class(in_value, val_type, use_dynamic, + class_type_or_name, address, + static_value_type); + } if (!CouldHaveDynamicValue(in_value)) return false; - CompilerType val_type(in_value.GetCompilerType()); Flags type_info(val_type.GetTypeInfo()); if (!type_info.AnySet(eTypeIsSwift)) return false; - Value::ValueType static_value_type = Value::ValueType::Invalid; bool success = false; bool is_indirect_enum_case = IsIndirectEnumCase(in_value); // Type kinds with instance metadata don't need generic type resolution.