Author: Adrian Prantl Date: 2019-12-10T15:53:40-08:00 New Revision: 62a6d9770450f93a2dcdf04710a73341af2f54fa
URL: https://github.com/llvm/llvm-project/commit/62a6d9770450f93a2dcdf04710a73341af2f54fa DIFF: https://github.com/llvm/llvm-project/commit/62a6d9770450f93a2dcdf04710a73341af2f54fa.diff LOG: Do not cache hardcoded formats in FormatManager The cache in FormatCache uses only a type name as key. The hardcoded formats, synthetic children, etc inspect an entire ValueObject to determine their eligibility, which isn't modelled in the cache. This leads to bugs such as the one in this patch (where two similarly named types in different files have different hardcoded summary providers). The problem is exaggerated in the Swift language plugin due to the language's dynamic nature. rdar://problem/57756763 Differential Revision: https://reviews.llvm.org/D71233 Added: lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-caching/Makefile lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-caching/TestDataFormatterCaching.py lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-caching/a.c lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-caching/b.c Modified: lldb/include/lldb/DataFormatters/FormatManager.h lldb/source/DataFormatters/FormatManager.cpp Removed: ################################################################################ diff --git a/lldb/include/lldb/DataFormatters/FormatManager.h b/lldb/include/lldb/DataFormatters/FormatManager.h index dffba1f93987..c57b8c8c64a9 100644 --- a/lldb/include/lldb/DataFormatters/FormatManager.h +++ b/lldb/include/lldb/DataFormatters/FormatManager.h @@ -209,7 +209,8 @@ class FormatManager : public IFormatChangeListener { ConstString m_vectortypes_category_name; template <typename ImplSP> - ImplSP GetCached(ValueObject &valobj, lldb::DynamicValueType use_dynamic); + ImplSP Get(ValueObject &valobj, lldb::DynamicValueType use_dynamic); + template <typename ImplSP> ImplSP GetCached(FormattersMatchData &match_data); template <typename ImplSP> ImplSP GetHardcoded(FormattersMatchData &); TypeCategoryMap &GetCategories() { return m_categories_map; } diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-caching/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-caching/Makefile new file mode 100644 index 000000000000..224ecc3c2f55 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-caching/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := a.c b.c + +include Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-caching/TestDataFormatterCaching.py b/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-caching/TestDataFormatterCaching.py new file mode 100644 index 000000000000..8b906506a5b6 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-caching/TestDataFormatterCaching.py @@ -0,0 +1,27 @@ +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +import lldbsuite.test.lldbutil as lldbutil + + +class TestDataFormatterCaching(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + TestBase.setUp(self) + + def test_with_run_command(self): + """ + Test that hardcoded summary formatter matches aren't improperly cached. + """ + self.build() + target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( + self, 'break here', lldb.SBFileSpec('a.c')) + valobj = self.frame().FindVariable('f') + self.assertEqual(valobj.GetValue(), '4') + bkpt_b = target.BreakpointCreateBySourceRegex('break here', + lldb.SBFileSpec('b.c')) + lldbutil.continue_to_breakpoint(process, bkpt_b) + valobj = self.frame().FindVariable('f4') + self.assertEqual(valobj.GetSummary(), '(1, 2, 3, 4)') diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-caching/a.c b/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-caching/a.c new file mode 100644 index 000000000000..ab0b6f5bd5e0 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-caching/a.c @@ -0,0 +1,7 @@ +typedef float float4; + +int main() { + float4 f = 4.0f; + // break here + return a(); +} diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-caching/b.c b/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-caching/b.c new file mode 100644 index 000000000000..0d37c54aa339 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-caching/b.c @@ -0,0 +1,8 @@ +typedef float float4 __attribute__((ext_vector_type(4))); +void stop() {} +int a() { + float4 f4 = {1, 2, 3, 4}; + // break here + stop(); + return 0; +} diff --git a/lldb/source/DataFormatters/FormatManager.cpp b/lldb/source/DataFormatters/FormatManager.cpp index c8ddbd455943..db15a7f7a4cc 100644 --- a/lldb/source/DataFormatters/FormatManager.cpp +++ b/lldb/source/DataFormatters/FormatManager.cpp @@ -622,11 +622,21 @@ ImplSP FormatManager::GetHardcoded(FormattersMatchData &match_data) { return retval_sp; } -template <typename ImplSP> ImplSP -FormatManager::GetCached(ValueObject &valobj, - lldb::DynamicValueType use_dynamic) { - ImplSP retval_sp; +template <typename ImplSP> +ImplSP FormatManager::Get(ValueObject &valobj, + lldb::DynamicValueType use_dynamic) { FormattersMatchData match_data(valobj, use_dynamic); + if (ImplSP retval_sp = GetCached<ImplSP>(match_data)) + return retval_sp; + + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS)); + LLDB_LOGF(log, "[%s] Search failed. Giving hardcoded a chance.", __FUNCTION__); + return GetHardcoded<ImplSP>(match_data); +} + +template <typename ImplSP> +ImplSP FormatManager::GetCached(FormattersMatchData &match_data) { + ImplSP retval_sp; Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS)); if (match_data.GetTypeForCache()) { LLDB_LOGF(log, "\n\n[%s] Looking into cache for type %s", __FUNCTION__, @@ -659,10 +669,6 @@ FormatManager::GetCached(ValueObject &valobj, return retval_sp; } } - if (!retval_sp) { - LLDB_LOGF(log, "[%s] Search failed. Giving hardcoded a chance.", __FUNCTION__); - retval_sp = GetHardcoded<ImplSP>(match_data); - } if (match_data.GetTypeForCache() && (!retval_sp || !retval_sp->NonCacheable())) { LLDB_LOGF(log, "[%s] Caching %p for type %s", __FUNCTION__, @@ -678,25 +684,25 @@ FormatManager::GetCached(ValueObject &valobj, lldb::TypeFormatImplSP FormatManager::GetFormat(ValueObject &valobj, lldb::DynamicValueType use_dynamic) { - return GetCached<lldb::TypeFormatImplSP>(valobj, use_dynamic); + return Get<lldb::TypeFormatImplSP>(valobj, use_dynamic); } lldb::TypeSummaryImplSP FormatManager::GetSummaryFormat(ValueObject &valobj, lldb::DynamicValueType use_dynamic) { - return GetCached<lldb::TypeSummaryImplSP>(valobj, use_dynamic); + return Get<lldb::TypeSummaryImplSP>(valobj, use_dynamic); } lldb::SyntheticChildrenSP FormatManager::GetSyntheticChildren(ValueObject &valobj, lldb::DynamicValueType use_dynamic) { - return GetCached<lldb::SyntheticChildrenSP>(valobj, use_dynamic); + return Get<lldb::SyntheticChildrenSP>(valobj, use_dynamic); } lldb::TypeValidatorImplSP FormatManager::GetValidator(ValueObject &valobj, lldb::DynamicValueType use_dynamic) { - return GetCached<lldb::TypeValidatorImplSP>(valobj, use_dynamic); + return Get<lldb::TypeValidatorImplSP>(valobj, use_dynamic); } FormatManager::FormatManager() _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits