[Lldb-commits] [lldb] 659a48f - Detect against invalid variant index for LibStdC++ std::variant data formatters (#69253)
via lldb-commits
lldb-commits at lists.llvm.org
Tue Oct 17 17:26:09 PDT 2023
Author: jeffreytan81
Date: 2023-10-17T17:26:05-07:00
New Revision: 659a48f25a96b7072b44d372c47385a2608f8671
URL: https://github.com/llvm/llvm-project/commit/659a48f25a96b7072b44d372c47385a2608f8671
DIFF: https://github.com/llvm/llvm-project/commit/659a48f25a96b7072b44d372c47385a2608f8671.diff
LOG: Detect against invalid variant index for LibStdC++ std::variant data formatters (#69253)
https://github.com/llvm/llvm-project/pull/68012/files added new data
formatters for LibStdC++ std::variant.
However, this formatter can crash if std::variant's index field has
invalid value (exceeds the number of template arguments).
This can happen if the current IP stops at a place std::variant is not
initialized yet.
This patch fixes the crash by ensuring the index is a valid value.
---------
Co-authored-by: jeffreytan81 <jeffreytan at fb.com>
Added:
Modified:
lldb/examples/synthetic/gnu_libstdcpp.py
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/variant/TestDataFormatterLibStdcxxVariant.py
Removed:
################################################################################
diff --git a/lldb/examples/synthetic/gnu_libstdcpp.py b/lldb/examples/synthetic/gnu_libstdcpp.py
index 29c926167fb440c..f778065aaca3771 100644
--- a/lldb/examples/synthetic/gnu_libstdcpp.py
+++ b/lldb/examples/synthetic/gnu_libstdcpp.py
@@ -914,6 +914,11 @@ def get_variant_npos_value(index_byte_size):
if index == npos_value:
return " No Value"
+ # Invalid index can happen when the variant is not initialized yet.
+ template_arg_count = data_obj.GetType().GetNumberOfTemplateArguments()
+ if index >= template_arg_count:
+ return " <Invalid>"
+
active_type = data_obj.GetType().GetTemplateArgumentType(index)
return f" Active Type = {active_type.GetDisplayTypeName()} "
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index f1353db2631ddc6..0b8edbb75eb9aee 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -7182,6 +7182,9 @@ GetNthTemplateArgument(const clang::ClassTemplateSpecializationDecl *decl,
// Note that 'idx' counts from the beginning of all template arguments
// (including the ones preceding the parameter pack).
const auto &pack = args[last_idx];
+ if (idx >= pack.pack_size())
+ return nullptr;
+
const size_t pack_idx = idx - last_idx;
assert(pack_idx < pack.pack_size() && "parameter pack index out-of-bounds");
return &pack.pack_elements()[pack_idx];
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/variant/TestDataFormatterLibStdcxxVariant.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/variant/TestDataFormatterLibStdcxxVariant.py
index 96a9c8d30c45b00..ba1641888b6f30f 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/variant/TestDataFormatterLibStdcxxVariant.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/variant/TestDataFormatterLibStdcxxVariant.py
@@ -71,3 +71,29 @@ def test_with_run_command(self):
substrs=["v_many_types_no_value = No Value"],
)
"""
+
+ @add_test_categories(["libstdcxx"])
+ def test_invalid_variant_index(self):
+ """Test LibStdC++ data formatter for std::variant with invalid index."""
+ self.build()
+
+ (self.target, self.process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
+ self, "// break here", lldb.SBFileSpec("main.cpp", False)
+ )
+
+ lldbutil.continue_to_breakpoint(self.process, bkpt)
+
+ self.expect(
+ "frame variable v1",
+ substrs=["v1 = Active Type = int {", "Value = 12", "}"],
+ )
+
+ var_v1 = thread.frames[0].FindVariable("v1")
+ var_v1_raw_obj = var_v1.GetNonSyntheticValue()
+ index_obj = var_v1_raw_obj.GetChildMemberWithName("_M_index")
+ self.assertTrue(index_obj and index_obj.IsValid())
+
+ INVALID_INDEX = "100"
+ index_obj.SetValueFromCString(INVALID_INDEX)
+
+ self.expect("frame variable v1", substrs=["v1 = <Invalid>"])
More information about the lldb-commits
mailing list