From 5f1bd9e57120d5b6be0fbdaacfcbcea1a465c6a9 Mon Sep 17 00:00:00 2001 From: Nerixyz Date: Thu, 31 Jul 2025 12:29:05 +0200 Subject: [PATCH 1/2] [LLDB] Add setting for native PDB reader --- .../NativePDB/SymbolFileNativePDB.cpp | 4 + .../Plugins/SymbolFile/PDB/CMakeLists.txt | 12 ++ .../Plugins/SymbolFile/PDB/SymbolFilePDB.cpp | 138 ++++++++++++++---- .../Plugins/SymbolFile/PDB/SymbolFilePDB.h | 2 + .../SymbolFile/PDB/SymbolFilePDBProperties.td | 13 ++ .../Shell/SymbolFile/PDB/native-setting.cpp | 52 +++++++ 6 files changed, 194 insertions(+), 27 deletions(-) create mode 100644 lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDBProperties.td create mode 100644 lldb/test/Shell/SymbolFile/PDB/native-setting.cpp diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index 20d8c1acf9c42..2afe4dd12f7d5 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -11,6 +11,7 @@ #include "Plugins/ExpressionParser/Clang/ClangUtil.h" #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" #include "Plugins/ObjectFile/PDB/ObjectFilePDB.h" +#include "Plugins/SymbolFile/PDB/SymbolFilePDB.h" #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" @@ -298,6 +299,9 @@ llvm::StringRef SymbolFileNativePDB::GetPluginDescriptionStatic() { } SymbolFile *SymbolFileNativePDB::CreateInstance(ObjectFileSP objfile_sp) { + if (!SymbolFilePDB::UseNativePDB()) + return nullptr; + return new SymbolFileNativePDB(std::move(objfile_sp)); } diff --git a/lldb/source/Plugins/SymbolFile/PDB/CMakeLists.txt b/lldb/source/Plugins/SymbolFile/PDB/CMakeLists.txt index 64590d7977b1f..c1cc3cd13a96f 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/CMakeLists.txt +++ b/lldb/source/Plugins/SymbolFile/PDB/CMakeLists.txt @@ -1,3 +1,11 @@ +lldb_tablegen(SymbolFilePDBProperties.inc -gen-lldb-property-defs + SOURCE SymbolFilePDBProperties.td + TARGET LLDBPluginSymbolFilePDBPropertiesGen) + +lldb_tablegen(SymbolFilePDBPropertiesEnum.inc -gen-lldb-property-enum-defs + SOURCE SymbolFilePDBProperties.td + TARGET LLDBPluginSymbolFilePDBPropertiesEnumGen) + add_lldb_library(lldbPluginSymbolFilePDB PLUGIN PDBASTParser.cpp PDBLocationToDWARFExpression.cpp @@ -16,3 +24,7 @@ add_lldb_library(lldbPluginSymbolFilePDB PLUGIN clangAST clangLex ) + +add_dependencies(lldbPluginSymbolFilePDB + LLDBPluginSymbolFilePDBPropertiesGen + LLDBPluginSymbolFilePDBPropertiesEnumGen) diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp index 96519ae0b3157..954e92c9a4460 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -71,6 +71,93 @@ LLDB_PLUGIN_DEFINE(SymbolFilePDB) char SymbolFilePDB::ID; namespace { + +enum UseNativePDBReader { + eUseNativePDBReaderDefault, + eUseNativePDBReaderOn, + eUseNativePDBReaderOff, +}; + +constexpr OptionEnumValueElement g_native_pdb_reader_enums[] = { + { + eUseNativePDBReaderDefault, + "default", + "Use DIA PDB reader unless LLDB_USE_NATIVE_PDB_READER environment " + "variable is set", + }, + { + eUseNativePDBReaderOn, + "on", + "Use native PDB reader", + }, + { + eUseNativePDBReaderOff, + "off", + "Use DIA PDB reader", + }, +}; + +#define LLDB_PROPERTIES_symbolfilepdb +#include "SymbolFilePDBProperties.inc" + +enum { +#define LLDB_PROPERTIES_symbolfilepdb +#include "SymbolFilePDBPropertiesEnum.inc" +}; + +#if LLVM_ENABLE_DIA_SDK && defined(_WIN32) +bool ShouldUseNativeReaderByDefault() { + static bool g_use_native_by_default = true; + + static llvm::once_flag g_initialize; + llvm::call_once(g_initialize, [] { + llvm::StringRef env_value = ::getenv("LLDB_USE_NATIVE_PDB_READER"); + if (!env_value.equals_insensitive("on") && + !env_value.equals_insensitive("yes") && + !env_value.equals_insensitive("1") && + !env_value.equals_insensitive("true")) + g_use_native_by_default = false; + }); + + return g_use_native_by_default; +} +#endif + +class PluginProperties : public Properties { +public: + static llvm::StringRef GetSettingName() { + return SymbolFilePDB::GetPluginNameStatic(); + } + + PluginProperties() { + m_collection_sp = std::make_shared(GetSettingName()); + m_collection_sp->Initialize(g_symbolfilepdb_properties); + } + + bool UseNativeReader() const { +#if LLVM_ENABLE_DIA_SDK && defined(_WIN32) + auto value = GetPropertyAtIndexAs( + ePropertyUseNativeReader, eUseNativePDBReaderDefault); + switch (value) { + case eUseNativePDBReaderOn: + return true; + case eUseNativePDBReaderOff: + return false; + default: + case eUseNativePDBReaderDefault: + return ShouldUseNativeReaderByDefault(); + } +#else + return true; +#endif + } +}; + +PluginProperties &GetGlobalPluginProperties() { + static PluginProperties g_settings; + return g_settings; +} + lldb::LanguageType TranslateLanguage(PDB_Lang lang) { switch (lang) { case PDB_Lang::Cpp: @@ -97,39 +184,33 @@ bool ShouldAddLine(uint32_t requested_line, uint32_t actual_line, } } // namespace -static bool ShouldUseNativeReader() { -#if defined(_WIN32) -#if LLVM_ENABLE_DIA_SDK - llvm::StringRef use_native = ::getenv("LLDB_USE_NATIVE_PDB_READER"); - if (!use_native.equals_insensitive("on") && - !use_native.equals_insensitive("yes") && - !use_native.equals_insensitive("1") && - !use_native.equals_insensitive("true")) - return false; -#endif -#endif - return true; -} - void SymbolFilePDB::Initialize() { - if (ShouldUseNativeReader()) { - npdb::SymbolFileNativePDB::Initialize(); - } else { - PluginManager::RegisterPlugin(GetPluginNameStatic(), - GetPluginDescriptionStatic(), CreateInstance, - DebuggerInitialize); - } + // Initialize both but check in CreateInstance for the desired plugin + npdb::SymbolFileNativePDB::Initialize(); + + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), CreateInstance, + DebuggerInitialize); } void SymbolFilePDB::Terminate() { - if (ShouldUseNativeReader()) { - npdb::SymbolFileNativePDB::Terminate(); - } else { - PluginManager::UnregisterPlugin(CreateInstance); - } + npdb::SymbolFileNativePDB::Terminate(); + + PluginManager::UnregisterPlugin(CreateInstance); +} + +bool SymbolFilePDB::UseNativePDB() { + return GetGlobalPluginProperties().UseNativeReader(); } -void SymbolFilePDB::DebuggerInitialize(lldb_private::Debugger &debugger) {} +void SymbolFilePDB::DebuggerInitialize(lldb_private::Debugger &debugger) { + if (!PluginManager::GetSettingForSymbolFilePlugin( + debugger, PluginProperties::GetSettingName())) { + PluginManager::CreateSettingForSymbolFilePlugin( + debugger, GetGlobalPluginProperties().GetValueProperties(), + "Properties for the PDB symbol-file plug-in.", true); + } +} llvm::StringRef SymbolFilePDB::GetPluginDescriptionStatic() { return "Microsoft PDB debug symbol file reader."; @@ -137,6 +218,9 @@ llvm::StringRef SymbolFilePDB::GetPluginDescriptionStatic() { lldb_private::SymbolFile * SymbolFilePDB::CreateInstance(ObjectFileSP objfile_sp) { + if (UseNativePDB()) + return nullptr; + return new SymbolFilePDB(std::move(objfile_sp)); } diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h index c0b25b6ee4055..e6560813ce75e 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -49,6 +49,8 @@ class SymbolFilePDB : public lldb_private::SymbolFileCommon { static lldb_private::SymbolFile * CreateInstance(lldb::ObjectFileSP objfile_sp); + static bool UseNativePDB(); + // Constructors and Destructors SymbolFilePDB(lldb::ObjectFileSP objfile_sp); diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDBProperties.td b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDBProperties.td new file mode 100644 index 0000000000000..a6d902d49abdb --- /dev/null +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDBProperties.td @@ -0,0 +1,13 @@ +include "../../../../include/lldb/Core/PropertiesBase.td" + +let Definition = "symbolfilepdb" in { + def UseNativeReader: Property<"use-native-reader", "Enum">, + Global, + DefaultEnumValue<"eUseNativePDBReaderDefault">, + EnumValues<"OptionEnumValues(g_native_pdb_reader_enums)">, + Desc<"When 'on', use the native PDB reader based on LLVM's PDB support as opposed to the reader using Microsoft's DIA SDK. " + "On Windows, the default is controlled by the LLDB_USE_NATIVE_PDB_READER environment variable. " + "If this is set, then the native reader is used. " + "Note that the setting value will always have priority and that it needs to be set before a target is created. " + "On other platforms, the native reader is always used.">; +} diff --git a/lldb/test/Shell/SymbolFile/PDB/native-setting.cpp b/lldb/test/Shell/SymbolFile/PDB/native-setting.cpp new file mode 100644 index 0000000000000..c4629431ae1a5 --- /dev/null +++ b/lldb/test/Shell/SymbolFile/PDB/native-setting.cpp @@ -0,0 +1,52 @@ +// REQUIRES: target-windows + +// Test plugin.symbol-file.pdb.use-native-reader setting +// RUN: %build -o %t.exe -- %s +// RUN: env LLDB_USE_NATIVE_PDB_READER=0 %lldb %t.exe -o 'target modules dump symfile' | FileCheck --check-prefix=ENV0 %s +// RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb %t.exe -o 'target modules dump symfile' | FileCheck --check-prefix=ENV1 %s +// RUN: env LLDB_USE_NATIVE_PDB_READER=0 %lldb \ +// RUN: -o 'settings set plugin.symbol-file.pdb.use-native-reader off' \ +// RUN: -o 'target create %t.exe' \ +// RUN: -o 'target modules dump symfile' \ +// RUN: | FileCheck --check-prefix=ENV0-SET0 %s +// RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb \ +// RUN: -o 'settings set plugin.symbol-file.pdb.use-native-reader off' \ +// RUN: -o 'target create %t.exe' \ +// RUN: -o 'target modules dump symfile' \ +// RUN: | FileCheck --check-prefix=ENV1-SET0 %s +// RUN: env LLDB_USE_NATIVE_PDB_READER=0 %lldb \ +// RUN: -o 'settings set plugin.symbol-file.pdb.use-native-reader on' \ +// RUN: -o 'target create %t.exe' \ +// RUN: -o 'target modules dump symfile' \ +// RUN: | FileCheck --check-prefix=ENV0-SET1 %s +// RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb \ +// RUN: -o 'settings set plugin.symbol-file.pdb.use-native-reader on' \ +// RUN: -o 'target create %t.exe' \ +// RUN: -o 'target modules dump symfile' \ +// RUN: | FileCheck --check-prefix=ENV1-SET1 %s + +// ENV0: (lldb) target modules dump symfile +// ENV0: Dumping debug symbols for 1 modules. +// ENV0: SymbolFile pdb + +// ENV1: (lldb) target modules dump symfile +// ENV1: Dumping debug symbols for 1 modules. +// ENV1: SymbolFile native-pdb + +// ENV0-SET0: (lldb) target modules dump symfile +// ENV0-SET0: Dumping debug symbols for 1 modules. +// ENV0-SET0: SymbolFile pdb + +// ENV1-SET0: (lldb) target modules dump symfile +// ENV1-SET0: Dumping debug symbols for 1 modules. +// ENV1-SET0: SymbolFile pdb + +// ENV0-SET1: (lldb) target modules dump symfile +// ENV0-SET1: Dumping debug symbols for 1 modules. +// ENV0-SET1: SymbolFile native-pdb + +// ENV1-SET1: (lldb) target modules dump symfile +// ENV1-SET1: Dumping debug symbols for 1 modules. +// ENV1-SET1: SymbolFile native-pdb + +int main() {} From ed90dc238a898d167eec092360aa0afbb760bdf0 Mon Sep 17 00:00:00 2001 From: Nerixyz Date: Fri, 1 Aug 2025 12:13:09 +0200 Subject: [PATCH 2/2] refactor: use reader enum over boolean for native plugin --- .../Plugins/SymbolFile/PDB/SymbolFilePDB.cpp | 34 +++++++-------- .../SymbolFile/PDB/SymbolFilePDBProperties.td | 17 ++++---- .../Shell/SymbolFile/PDB/native-setting.cpp | 42 +++++++++---------- 3 files changed, 47 insertions(+), 46 deletions(-) diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp index 954e92c9a4460..2f0b6539445fb 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -72,28 +72,28 @@ char SymbolFilePDB::ID; namespace { -enum UseNativePDBReader { - eUseNativePDBReaderDefault, - eUseNativePDBReaderOn, - eUseNativePDBReaderOff, +enum PDBReader { + ePDBReaderDefault, + ePDBReaderDIA, + ePDBReaderNative, }; -constexpr OptionEnumValueElement g_native_pdb_reader_enums[] = { +constexpr OptionEnumValueElement g_pdb_reader_enums[] = { { - eUseNativePDBReaderDefault, + ePDBReaderDefault, "default", "Use DIA PDB reader unless LLDB_USE_NATIVE_PDB_READER environment " "variable is set", }, { - eUseNativePDBReaderOn, - "on", - "Use native PDB reader", + ePDBReaderDIA, + "dia", + "Use DIA PDB reader", }, { - eUseNativePDBReaderOff, - "off", - "Use DIA PDB reader", + ePDBReaderNative, + "native", + "Use native PDB reader", }, }; @@ -136,15 +136,15 @@ class PluginProperties : public Properties { bool UseNativeReader() const { #if LLVM_ENABLE_DIA_SDK && defined(_WIN32) - auto value = GetPropertyAtIndexAs( - ePropertyUseNativeReader, eUseNativePDBReaderDefault); + auto value = + GetPropertyAtIndexAs(ePropertyReader, ePDBReaderDefault); switch (value) { - case eUseNativePDBReaderOn: + case ePDBReaderNative: return true; - case eUseNativePDBReaderOff: + case ePDBReaderDIA: return false; default: - case eUseNativePDBReaderDefault: + case ePDBReaderDefault: return ShouldUseNativeReaderByDefault(); } #else diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDBProperties.td b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDBProperties.td index a6d902d49abdb..35875def046a5 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDBProperties.td +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDBProperties.td @@ -1,13 +1,14 @@ include "../../../../include/lldb/Core/PropertiesBase.td" let Definition = "symbolfilepdb" in { - def UseNativeReader: Property<"use-native-reader", "Enum">, + def Reader: Property<"reader", "Enum">, Global, - DefaultEnumValue<"eUseNativePDBReaderDefault">, - EnumValues<"OptionEnumValues(g_native_pdb_reader_enums)">, - Desc<"When 'on', use the native PDB reader based on LLVM's PDB support as opposed to the reader using Microsoft's DIA SDK. " - "On Windows, the default is controlled by the LLDB_USE_NATIVE_PDB_READER environment variable. " - "If this is set, then the native reader is used. " - "Note that the setting value will always have priority and that it needs to be set before a target is created. " - "On other platforms, the native reader is always used.">; + DefaultEnumValue<"ePDBReaderDefault">, + EnumValues<"OptionEnumValues(g_pdb_reader_enums)">, + Desc<"Selects the reader for PDB symbol files. " + "The native PDB reader that uses LLVM's PDB support is always available (value: 'native'). " + "Secondly, the DIA PDB reader is only available if LLVM was comppiled with Microsoft's DIA SDK on Windows (value: 'DIA'). " + "By default, the DIA PDB reader is used if available. " + "The LLDB_USE_NATIVE_PDB_READER environment variable can be used to switch to the native reader when this setting has the default value. " + "Otherwise, the setting always has priority.">; } diff --git a/lldb/test/Shell/SymbolFile/PDB/native-setting.cpp b/lldb/test/Shell/SymbolFile/PDB/native-setting.cpp index c4629431ae1a5..ce188e75553c7 100644 --- a/lldb/test/Shell/SymbolFile/PDB/native-setting.cpp +++ b/lldb/test/Shell/SymbolFile/PDB/native-setting.cpp @@ -1,29 +1,29 @@ // REQUIRES: target-windows -// Test plugin.symbol-file.pdb.use-native-reader setting +// Test plugin.symbol-file.pdb.reader setting // RUN: %build -o %t.exe -- %s // RUN: env LLDB_USE_NATIVE_PDB_READER=0 %lldb %t.exe -o 'target modules dump symfile' | FileCheck --check-prefix=ENV0 %s // RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb %t.exe -o 'target modules dump symfile' | FileCheck --check-prefix=ENV1 %s // RUN: env LLDB_USE_NATIVE_PDB_READER=0 %lldb \ -// RUN: -o 'settings set plugin.symbol-file.pdb.use-native-reader off' \ +// RUN: -o 'settings set plugin.symbol-file.pdb.reader dia' \ // RUN: -o 'target create %t.exe' \ // RUN: -o 'target modules dump symfile' \ -// RUN: | FileCheck --check-prefix=ENV0-SET0 %s +// RUN: | FileCheck --check-prefix=ENV0-SET-DIA %s // RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb \ -// RUN: -o 'settings set plugin.symbol-file.pdb.use-native-reader off' \ +// RUN: -o 'settings set plugin.symbol-file.pdb.reader dia' \ // RUN: -o 'target create %t.exe' \ // RUN: -o 'target modules dump symfile' \ -// RUN: | FileCheck --check-prefix=ENV1-SET0 %s +// RUN: | FileCheck --check-prefix=ENV1-SET-DIA %s // RUN: env LLDB_USE_NATIVE_PDB_READER=0 %lldb \ -// RUN: -o 'settings set plugin.symbol-file.pdb.use-native-reader on' \ +// RUN: -o 'settings set plugin.symbol-file.pdb.reader native' \ // RUN: -o 'target create %t.exe' \ // RUN: -o 'target modules dump symfile' \ -// RUN: | FileCheck --check-prefix=ENV0-SET1 %s +// RUN: | FileCheck --check-prefix=ENV0-SET-NATIVE %s // RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb \ -// RUN: -o 'settings set plugin.symbol-file.pdb.use-native-reader on' \ +// RUN: -o 'settings set plugin.symbol-file.pdb.reader native' \ // RUN: -o 'target create %t.exe' \ // RUN: -o 'target modules dump symfile' \ -// RUN: | FileCheck --check-prefix=ENV1-SET1 %s +// RUN: | FileCheck --check-prefix=ENV1-SET-NATIVE %s // ENV0: (lldb) target modules dump symfile // ENV0: Dumping debug symbols for 1 modules. @@ -33,20 +33,20 @@ // ENV1: Dumping debug symbols for 1 modules. // ENV1: SymbolFile native-pdb -// ENV0-SET0: (lldb) target modules dump symfile -// ENV0-SET0: Dumping debug symbols for 1 modules. -// ENV0-SET0: SymbolFile pdb +// ENV0-SET-DIA: (lldb) target modules dump symfile +// ENV0-SET-DIA: Dumping debug symbols for 1 modules. +// ENV0-SET-DIA: SymbolFile pdb -// ENV1-SET0: (lldb) target modules dump symfile -// ENV1-SET0: Dumping debug symbols for 1 modules. -// ENV1-SET0: SymbolFile pdb +// ENV1-SET-DIA: (lldb) target modules dump symfile +// ENV1-SET-DIA: Dumping debug symbols for 1 modules. +// ENV1-SET-DIA: SymbolFile pdb -// ENV0-SET1: (lldb) target modules dump symfile -// ENV0-SET1: Dumping debug symbols for 1 modules. -// ENV0-SET1: SymbolFile native-pdb +// ENV0-SET-NATIVE: (lldb) target modules dump symfile +// ENV0-SET-NATIVE: Dumping debug symbols for 1 modules. +// ENV0-SET-NATIVE: SymbolFile native-pdb -// ENV1-SET1: (lldb) target modules dump symfile -// ENV1-SET1: Dumping debug symbols for 1 modules. -// ENV1-SET1: SymbolFile native-pdb +// ENV1-SET-NATIVE: (lldb) target modules dump symfile +// ENV1-SET-NATIVE: Dumping debug symbols for 1 modules. +// ENV1-SET-NATIVE: SymbolFile native-pdb int main() {}