Author: Vladimir Gorsunov
Date: 2026-01-28T17:18:09+01:00
New Revision: c3d4375729e5f3c83d97a788a4d0d7853dae1fae

URL: 
https://github.com/llvm/llvm-project/commit/c3d4375729e5f3c83d97a788a4d0d7853dae1fae
DIFF: 
https://github.com/llvm/llvm-project/commit/c3d4375729e5f3c83d97a788a4d0d7853dae1fae.diff

LOG: [lldb][NativePDB] Fix crash in debugger when PDB has bad type index value 
(#166455)

Fix crash when an inline site record in the PDB file contains type index
which is out of bounds

Added: 
    lldb/test/Shell/SymbolFile/NativePDB/invalid-inlinee-not-in-ipi.yaml

Modified: 
    lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilderClang.cpp
    lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
    lldb/test/Shell/SymbolFile/NativePDB/lit.local.cfg
    llvm/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h
    llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilderClang.cpp 
b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilderClang.cpp
index af95581bc3e51..3b2be30a60a27 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilderClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilderClang.cpp
@@ -996,15 +996,18 @@ PdbAstBuilderClang::CreateFunctionDeclFromId(PdbTypeSymId 
func_tid,
   SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
       m_clang.GetSymbolFile()->GetBackingSymbolFile());
   PdbIndex &index = pdb->GetIndex();
-  CVType func_cvt = index.ipi().getType(func_tid.index);
+  std::optional<CVType> func_cvt =
+      index.ipi().typeCollection().tryGetType(func_tid.index);
+  if (!func_cvt)
+    return nullptr;
   llvm::StringRef func_name;
   TypeIndex func_ti;
   clang::DeclContext *parent = nullptr;
-  switch (func_cvt.kind()) {
+  switch (func_cvt->kind()) {
   case LF_MFUNC_ID: {
     MemberFuncIdRecord mfr;
     cantFail(
-        TypeDeserializer::deserializeAs<MemberFuncIdRecord>(func_cvt, mfr));
+        TypeDeserializer::deserializeAs<MemberFuncIdRecord>(*func_cvt, mfr));
     func_name = mfr.getName();
     func_ti = mfr.getFunctionType();
     PdbTypeSymId class_type_id(mfr.ClassType, false);
@@ -1013,7 +1016,7 @@ PdbAstBuilderClang::CreateFunctionDeclFromId(PdbTypeSymId 
func_tid,
   }
   case LF_FUNC_ID: {
     FuncIdRecord fir;
-    cantFail(TypeDeserializer::deserializeAs<FuncIdRecord>(func_cvt, fir));
+    cantFail(TypeDeserializer::deserializeAs<FuncIdRecord>(*func_cvt, fir));
     func_name = fir.getName();
     func_ti = fir.getFunctionType();
     parent = FromCompilerDeclContext(GetTranslationUnitDecl());
@@ -1504,7 +1507,9 @@ 
PdbAstBuilderClang::ToCompilerDeclContext(clang::DeclContext *context) {
 }
 
 clang::Decl *PdbAstBuilderClang::FromCompilerDecl(CompilerDecl decl) {
-  return ClangUtil::GetDecl(decl);
+  if (decl.GetTypeSystem() != nullptr)
+    return ClangUtil::GetDecl(decl);
+  return nullptr;
 }
 
 clang::DeclContext *

diff  --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp 
b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index 328539b54fc1d..7e39af7d32e2f 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -1757,19 +1757,23 @@ void 
SymbolFileNativePDB::ParseInlineSite(PdbCompilandSymId id,
   }
 
   // Get the inlined function name.
-  CVType inlinee_cvt = m_index->ipi().getType(inline_site.Inlinee);
   std::string inlinee_name;
-  if (inlinee_cvt.kind() == LF_MFUNC_ID) {
+  llvm::Expected<CVType> inlinee_cvt =
+      m_index->ipi().typeCollection().getTypeOrError(inline_site.Inlinee);
+  if (!inlinee_cvt) {
+    inlinee_name = "[error reading function name: " +
+                   llvm::toString(inlinee_cvt.takeError()) + "]";
+  } else if (inlinee_cvt->kind() == LF_MFUNC_ID) {
     MemberFuncIdRecord mfr;
     cantFail(
-        TypeDeserializer::deserializeAs<MemberFuncIdRecord>(inlinee_cvt, mfr));
+        TypeDeserializer::deserializeAs<MemberFuncIdRecord>(*inlinee_cvt, 
mfr));
     LazyRandomTypeCollection &types = m_index->tpi().typeCollection();
     inlinee_name.append(std::string(types.getTypeName(mfr.ClassType)));
     inlinee_name.append("::");
     inlinee_name.append(mfr.getName().str());
-  } else if (inlinee_cvt.kind() == LF_FUNC_ID) {
+  } else if (inlinee_cvt->kind() == LF_FUNC_ID) {
     FuncIdRecord fir;
-    cantFail(TypeDeserializer::deserializeAs<FuncIdRecord>(inlinee_cvt, fir));
+    cantFail(TypeDeserializer::deserializeAs<FuncIdRecord>(*inlinee_cvt, fir));
     TypeIndex parent_idx = fir.getParentScope();
     if (!parent_idx.isNoneType()) {
       LazyRandomTypeCollection &ids = m_index->ipi().typeCollection();

diff  --git 
a/lldb/test/Shell/SymbolFile/NativePDB/invalid-inlinee-not-in-ipi.yaml 
b/lldb/test/Shell/SymbolFile/NativePDB/invalid-inlinee-not-in-ipi.yaml
new file mode 100755
index 0000000000000..4253574729182
--- /dev/null
+++ b/lldb/test/Shell/SymbolFile/NativePDB/invalid-inlinee-not-in-ipi.yaml
@@ -0,0 +1,300 @@
+# RUN: llvm-pdbutil yaml2pdb %s --pdb=%t
+# RUN: lldb-test symbols %t | FileCheck %s
+
+# CHECK:  CompileUnit
+# CHECK:    Function{{.*}}, demangled = main,
+# CHECK-NEXT:    Block{{.*}}
+# CHECK-NEXT:      Variable{{.*}}, name = "argc", type = {{.*}} (int), scope = 
parameter
+# CHECK-NEXT:      Variable{{.*}}, name = "argv", type = {{.*}} (char **), 
scope = parameter
+# CHECK-NEXT:      Block{{.*}}, parent = {{.*}}, name = "[error reading 
function name: Type index too high (2147418112)]", decl = 
inline_sites_live.cpp:14
+# CHECK-NEXT:        Variable{{.*}}, name = "param", type = {{.*}} (int), 
scope = parameter
+# CHECK-NEXT:        Variable{{.*}}, name = "local", type = {{.*}} (int), 
scope = local
+---
+MSF:
+  SuperBlock:
+    FreeBlockMap:    2
+    NumBlocks:       18
+    NumDirectoryBytes: 116
+    BlockMapAddr:    3
+  NumDirectoryBlocks: 1
+  DirectoryBlocks: [ 17 ]
+  NumStreams:      15
+  FileSize:        73728
+IpiStream:
+  Records:
+    - Kind:            LF_FUNC_ID
+      FuncId:
+        ParentScope:     0
+        FunctionType:    0x1001
+        Name:            foo
+    - Kind:            LF_FUNC_ID
+      FuncId:
+        ParentScope:     0
+        FunctionType:    4100
+        Name:            main
+    - Kind:            LF_BUILDINFO
+      BuildInfo:
+        ArgIndices:      [ 4098, 4101, 4099, 4100, 4102 ]
+TpiStream:
+  Records:
+    - Kind:            LF_ARGLIST
+      ArgList:
+        ArgIndices:      [ 116 ]
+    - Kind:            LF_PROCEDURE
+      Procedure:
+        ReturnType:      3
+        CallConv:        NearC
+        Options:         [ None ]
+        ParameterCount:  1
+        ArgumentList:    4096
+    - Kind:            LF_POINTER
+      Pointer:
+        ReferentType:    1648
+        Attrs:           65548
+    - Kind:            LF_ARGLIST
+      ArgList:
+        ArgIndices:      [ 116, 4098 ]
+    - Kind:            LF_PROCEDURE
+      Procedure:
+        ReturnType:      116
+        CallConv:        NearC
+        Options:         [ None ]
+        ParameterCount:  2
+        ArgumentList:    4099
+DbiStream:
+  BuildNumber:     36363
+  Flags:           0
+  MachineType:     Amd64
+  Modules:
+    - Module:          
'C:\Users\johannes\AppData\Local\Temp\inline_sites_live-2a62f2.o'
+      SourceFiles:
+        - 
'F:\Dev\llvm-project\lldb\test\Shell\SymbolFile\NativePDB\inline_sites_live.cpp'
+      Subsections:
+        - !InlineeLines
+          HasExtraFiles:   false
+          Sites:
+            - FileName:        
'F:\Dev\llvm-project\lldb\test\Shell\SymbolFile\NativePDB\inline_sites_live.cpp'
+              LineNum:         14
+              Inlinee:         0x7FFF0000 # An index that is not in IPI 
stream, also present in "Records"
+        - !Lines
+          CodeSize:        17
+          Flags:           [  ]
+          RelocOffset:     0
+          RelocSegment:    1
+          Blocks:
+            - FileName:        
'F:\Dev\llvm-project\lldb\test\Shell\SymbolFile\NativePDB\inline_sites_live.cpp'
+              Lines:
+                - Offset:          0
+                  LineStart:       14
+                  IsStatement:     false
+                  EndDelta:        0
+                - Offset:          5
+                  LineStart:       15
+                  IsStatement:     false
+                  EndDelta:        0
+                - Offset:          15
+                  LineStart:       19
+                  IsStatement:     false
+                  EndDelta:        0
+              Columns:         []
+        - !FileChecksums
+          Checksums:
+            - FileName:        
'F:\Dev\llvm-project\lldb\test\Shell\SymbolFile\NativePDB\inline_sites_live.cpp'
+              Kind:            MD5
+              Checksum:        856E65504B68E2EF155921DFCCB753CE
+      Modi:
+        Records:
+          - Kind:            S_OBJNAME
+            ObjNameSym:
+              Signature:       0
+              ObjectName:      
'C:\Users\johannes\AppData\Local\Temp\inline_sites_live-2a62f2.o'
+          - Kind:            S_COMPILE3
+            Compile3Sym:
+              Flags:           [  ]
+              Machine:         X64
+              FrontendMajor:   19
+              FrontendMinor:   1
+              FrontendBuild:   5
+              FrontendQFE:     0
+              BackendMajor:    19015
+              BackendMinor:    0
+              BackendBuild:    0
+              BackendQFE:      0
+              Version:         clang version 19.1.5
+          - Kind:            S_GPROC32
+            ProcSym:
+              PtrEnd:          264
+              CodeSize:        17
+              DbgStart:        0
+              DbgEnd:          0
+              FunctionType:    4097
+              Segment:         1
+              Flags:           [ HasOptimizedDebugInfo ]
+              DisplayName:     foo
+          - Kind:            S_FRAMEPROC
+            FrameProcSym:
+              TotalFrameBytes: 8
+              PaddingFrameBytes: 0
+              OffsetToPadding: 0
+              BytesOfCalleeSavedRegisters: 0
+              OffsetOfExceptionHandler: 0
+              SectionIdOfExceptionHandler: 0
+              Flags:           [ SafeBuffers ]
+          - Kind:            S_LOCAL
+            LocalSym:
+              Type:            116
+              Flags:           [ IsParameter ]
+              VarName:         param
+          - Kind:            S_DEFRANGE_FRAMEPOINTER_REL
+            DefRangeFramePointerRelSym:
+              Offset:          4
+              Range:
+                OffsetStart:     5
+                ISectStart:      1
+                Range:           12
+              Gaps:            []
+          - Kind:            S_LOCAL
+            LocalSym:
+              Type:            116
+              Flags:           [  ]
+              VarName:         local
+          - Kind:            S_DEFRANGE_FRAMEPOINTER_REL
+            DefRangeFramePointerRelSym:
+              Offset:          0
+              Range:
+                OffsetStart:     5
+                ISectStart:      1
+                Range:           12
+              Gaps:            []
+          - Kind:            S_END
+            ScopeEndSym:     {}
+          - Kind:            S_GPROC32
+            ProcSym:
+              PtrEnd:          512
+              CodeSize:        39
+              DbgStart:        0
+              DbgEnd:          0
+              FunctionType:    4100
+              Offset:          32
+              Segment:         1
+              Flags:           [ IsNoInline, HasOptimizedDebugInfo ]
+              DisplayName:     main
+          - Kind:            S_FRAMEPROC
+            FrameProcSym:
+              TotalFrameBytes: 24
+              PaddingFrameBytes: 0
+              OffsetToPadding: 0
+              BytesOfCalleeSavedRegisters: 0
+              OffsetOfExceptionHandler: 0
+              SectionIdOfExceptionHandler: 0
+              Flags:           [ SafeBuffers ]
+          - Kind:            S_INLINEES
+            CallerSym:
+              FuncID:          [ 4096 ]
+          - Kind:            S_LOCAL
+            LocalSym:
+              Type:            116
+              Flags:           [ IsParameter ]
+              VarName:         argc
+          - Kind:            S_DEFRANGE_FRAMEPOINTER_REL
+            DefRangeFramePointerRelSym:
+              Offset:          4
+              Range:
+                OffsetStart:     45
+                ISectStart:      1
+                Range:           26
+              Gaps:            []
+          - Kind:            S_LOCAL
+            LocalSym:
+              Type:            4098
+              Flags:           [ IsParameter ]
+              VarName:         argv
+          - Kind:            S_DEFRANGE_FRAMEPOINTER_REL
+            DefRangeFramePointerRelSym:
+              Offset:          8
+              Range:
+                OffsetStart:     45
+                ISectStart:      1
+                Range:           26
+              Gaps:            []
+          - Kind:            S_INLINESITE
+            InlineSiteSym:
+              PtrParent:       268
+              PtrEnd:          508
+              Inlinee:         0x7FFF0000 # An index which is not in IPI 
stream, also present in "InlineeLines"
+              AnnotationData:  [ 6, 2, 3, 21, 4, 11, 0, 0 ]
+          - Kind:            S_LOCAL
+            LocalSym:
+              Type:            116
+              Flags:           [ IsParameter ]
+              VarName:         param
+          - Kind:            S_DEFRANGE_FRAMEPOINTER_REL
+            DefRangeFramePointerRelSym:
+              Offset:          20
+              Range:
+                OffsetStart:     53
+                ISectStart:      1
+                Range:           11
+              Gaps:            []
+          - Kind:            S_LOCAL
+            LocalSym:
+              Type:            116
+              Flags:           [  ]
+              VarName:         local
+          - Kind:            S_DEFRANGE_FRAMEPOINTER_REL
+            DefRangeFramePointerRelSym:
+              Offset:          16
+              Range:
+                OffsetStart:     53
+                ISectStart:      1
+                Range:           11
+              Gaps:            []
+          - Kind:            S_INLINESITE_END
+            ScopeEndSym:     {}
+          - Kind:            S_END
+            ScopeEndSym:     {}
+  SectionHeaders:
+    - Name:            .text
+      VirtualSize:     71
+      VirtualAddress:  4096
+      SizeOfRawData:   512
+      PointerToRawData: 1024
+      PointerToRelocations: 0
+      PointerToLinenumbers: 0
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      Characteristics: 1610612768
+    - Name:            .rdata
+      VirtualSize:     100
+      VirtualAddress:  8192
+      SizeOfRawData:   512
+      PointerToRawData: 1536
+      PointerToRelocations: 0
+      PointerToLinenumbers: 0
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      Characteristics: 1073741888
+    - Name:            .pdata
+      VirtualSize:     24
+      VirtualAddress:  12288
+      SizeOfRawData:   512
+      PointerToRawData: 2048
+      PointerToRelocations: 0
+      PointerToLinenumbers: 0
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      Characteristics: 1073741888
+PublicsStream:
+  Records:
+    - Kind:            S_PUB32
+      PublicSym32:
+        Flags:           [ Function ]
+        Offset:          32
+        Segment:         1
+        Name:            main
+    - Kind:            S_PUB32
+      PublicSym32:
+        Flags:           [ Function ]
+        Segment:         1
+        Name:            '?foo@@YAXH@Z'
+...

diff  --git a/lldb/test/Shell/SymbolFile/NativePDB/lit.local.cfg 
b/lldb/test/Shell/SymbolFile/NativePDB/lit.local.cfg
index 02bc504eea55c..e24875fdad5d4 100644
--- a/lldb/test/Shell/SymbolFile/NativePDB/lit.local.cfg
+++ b/lldb/test/Shell/SymbolFile/NativePDB/lit.local.cfg
@@ -1 +1,2 @@
 config.environment["LLDB_USE_NATIVE_PDB_READER"] = "1"
+config.suffixes = ['.cpp', '.ll', '.s', '.test', '.yaml']

diff  --git a/llvm/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h 
b/llvm/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h
index 5b23ac9f862a0..da18339b8662b 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h
@@ -70,7 +70,7 @@ class LLVM_ABI LazyRandomTypeCollection : public 
TypeCollection {
   uint32_t getOffsetOfType(TypeIndex Index);
 
   std::optional<CVType> tryGetType(TypeIndex Index);
-
+  llvm::Expected<CVType> getTypeOrError(TypeIndex Index);
   CVType getType(TypeIndex Index) override;
   StringRef getTypeName(TypeIndex Index) override;
   bool contains(TypeIndex Index) override;

diff  --git a/llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp 
b/llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp
index 23ab5344df1ed..0b36c5085c086 100644
--- a/llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp
+++ b/llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp
@@ -93,20 +93,25 @@ CVType LazyRandomTypeCollection::getType(TypeIndex Index) {
   return Records[Index.toArrayIndex()].Type;
 }
 
-std::optional<CVType> LazyRandomTypeCollection::tryGetType(TypeIndex Index) {
+llvm::Expected<CVType>
+LazyRandomTypeCollection::getTypeOrError(TypeIndex Index) {
   if (Index.isSimple())
-    return std::nullopt;
+    return llvm::createStringError("Type index too low (%d)", 
Index.getIndex());
 
   if (auto EC = ensureTypeExists(Index)) {
-    consumeError(std::move(EC));
-    return std::nullopt;
+    return EC;
   }
 
   if (!contains(Index))
-    return std::nullopt;
+    return llvm::createStringError("Type index too high (%d)",
+                                   Index.getIndex());
   return Records[Index.toArrayIndex()].Type;
 }
 
+std::optional<CVType> LazyRandomTypeCollection::tryGetType(TypeIndex Index) {
+  return llvm::expectedToOptional(getTypeOrError(Index));
+}
+
 StringRef LazyRandomTypeCollection::getTypeName(TypeIndex Index) {
   if (Index.isNoneType() || Index.isSimple())
     return TypeIndex::simpleTypeName(Index);


        
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to