https://github.com/JDevlieghere updated https://github.com/llvm/llvm-project/pull/145396
>From 1da01acdb21fd7d7a58de8d19175479394f727d2 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jo...@devlieghere.com> Date: Mon, 23 Jun 2025 14:26:03 -0500 Subject: [PATCH 1/2] [lldb] Defend against infinite recursion in GetClassDescriptor We defend against a direct cycle where a base class ValueObject is its own parent, but not against a longer base cycle. This cycle requires that some value's Type includes a base class, and that base class is in a class hierarchy that cycles back to the original base class. I wrote a test case that creates a cycle in the class hierarchy by dynamically overwriting the superclass of an object, but I can't reproduce the crash. I can't think of any other way to make a real object that behaves that way. Maybe is a type system problem in making up the type for whatever type we're trying to ingest here. While unsatisfying, without a reproducer this is the best we can do for now. rdar://140293233 --- .../AppleObjCRuntime/AppleObjCRuntimeV2.cpp | 21 +++++++++++++------ .../AppleObjCRuntime/AppleObjCRuntimeV2.h | 5 +++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp index e459cb281793a..4fcdebe5bac62 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp @@ -1505,15 +1505,24 @@ AppleObjCRuntimeV2::GetClassDescriptorFromISA(ObjCISA isa) { ObjCLanguageRuntime::ClassDescriptorSP AppleObjCRuntimeV2::GetClassDescriptor(ValueObject &valobj) { + ValueObjectSet seen; + return GetClassDescriptorImpl(valobj, seen); +} + +ObjCLanguageRuntime::ClassDescriptorSP +AppleObjCRuntimeV2::GetClassDescriptorImpl(ValueObject &valobj, + ValueObjectSet &seen) { + seen.insert(&valobj); + ClassDescriptorSP objc_class_sp; if (valobj.IsBaseClass()) { ValueObject *parent = valobj.GetParent(); - // if I am my own parent, bail out of here fast.. - if (parent && parent != &valobj) { - ClassDescriptorSP parent_descriptor_sp = GetClassDescriptor(*parent); - if (parent_descriptor_sp) - return parent_descriptor_sp->GetSuperclass(); - } + // Fail if there's a cycle in our parent chain. + if (!parent || seen.count(parent)) + return nullptr; + if (ClassDescriptorSP parent_descriptor_sp = + GetClassDescriptorImpl(*parent, seen)) + return parent_descriptor_sp->GetSuperclass(); return nullptr; } // if we get an invalid VO (which might still happen when playing around with diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h index 79840f9be79b3..e5dba5bddf936 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h @@ -20,6 +20,7 @@ #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" #include "llvm/ADT/BitVector.h" +#include "llvm/ADT/SmallSet.h" class RemoteNXMapTable; @@ -421,6 +422,10 @@ class AppleObjCRuntimeV2 : public AppleObjCRuntime { lldb::addr_t GetISAHashTablePointer(); + using ValueObjectSet = llvm::SmallSet<ValueObject *, 8>; + ClassDescriptorSP GetClassDescriptorImpl(ValueObject &valobj, + ValueObjectSet &seen); + /// Update the generation count of realized classes. This is not an exact /// count but rather a value that is incremented when new classes are realized /// or destroyed. Unlike the count in gdb_objc_realized_classes, it will >From 69bb4e713ebbde210bc52abe51753dc82402f509 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jo...@devlieghere.com> Date: Tue, 24 Jun 2025 10:25:20 -0700 Subject: [PATCH 2/2] Use llvm::SmallPtrSet --- .../LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h index e5dba5bddf936..b99bda2f7e259 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h @@ -422,7 +422,7 @@ class AppleObjCRuntimeV2 : public AppleObjCRuntime { lldb::addr_t GetISAHashTablePointer(); - using ValueObjectSet = llvm::SmallSet<ValueObject *, 8>; + using ValueObjectSet = llvm::SmallPtrSet<ValueObject *, 8>; ClassDescriptorSP GetClassDescriptorImpl(ValueObject &valobj, ValueObjectSet &seen); _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits