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
