Skip to content

Commit e7e4e4a

Browse files
committed
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 (cherry picked from commit 62a6d97)
1 parent 7a42039 commit e7e4e4a

File tree

6 files changed

+65
-13
lines changed

6 files changed

+65
-13
lines changed

lldb/include/lldb/DataFormatters/FormatManager.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,8 @@ class FormatManager : public IFormatChangeListener {
222222
ConstString m_runtime_synths_category_name;
223223

224224
template <typename ImplSP>
225-
ImplSP GetCached(ValueObject &valobj, lldb::DynamicValueType use_dynamic);
225+
ImplSP Get(ValueObject &valobj, lldb::DynamicValueType use_dynamic);
226+
template <typename ImplSP> ImplSP GetCached(FormattersMatchData &match_data);
226227
template <typename ImplSP> ImplSP GetHardcoded(FormattersMatchData &);
227228

228229
TypeCategoryMap &GetCategories() { return m_categories_map; }
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
C_SOURCES := a.c b.c
2+
3+
include Makefile.rules
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import lldb
2+
from lldbsuite.test.lldbtest import *
3+
from lldbsuite.test.decorators import *
4+
import lldbsuite.test.lldbutil as lldbutil
5+
6+
7+
class TestDataFormatterCaching(TestBase):
8+
9+
mydir = TestBase.compute_mydir(__file__)
10+
11+
def setUp(self):
12+
TestBase.setUp(self)
13+
14+
def test_with_run_command(self):
15+
"""
16+
Test that hardcoded summary formatter matches aren't improperly cached.
17+
"""
18+
self.build()
19+
target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
20+
self, 'break here', lldb.SBFileSpec('a.c'))
21+
valobj = self.frame().FindVariable('f')
22+
self.assertEqual(valobj.GetValue(), '4')
23+
bkpt_b = target.BreakpointCreateBySourceRegex('break here',
24+
lldb.SBFileSpec('b.c'))
25+
lldbutil.continue_to_breakpoint(process, bkpt_b)
26+
valobj = self.frame().FindVariable('f4')
27+
self.assertEqual(valobj.GetSummary(), '(1, 2, 3, 4)')
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
typedef float float4;
2+
3+
int main() {
4+
float4 f = 4.0f;
5+
// break here
6+
return a();
7+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
typedef float float4 __attribute__((ext_vector_type(4)));
2+
void stop() {}
3+
int a() {
4+
float4 f4 = {1, 2, 3, 4};
5+
// break here
6+
stop();
7+
return 0;
8+
}

lldb/source/DataFormatters/FormatManager.cpp

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -634,11 +634,21 @@ ImplSP FormatManager::GetHardcoded(FormattersMatchData &match_data) {
634634
return retval_sp;
635635
}
636636

637-
template <typename ImplSP> ImplSP
638-
FormatManager::GetCached(ValueObject &valobj,
639-
lldb::DynamicValueType use_dynamic) {
640-
ImplSP retval_sp;
637+
template <typename ImplSP>
638+
ImplSP FormatManager::Get(ValueObject &valobj,
639+
lldb::DynamicValueType use_dynamic) {
641640
FormattersMatchData match_data(valobj, use_dynamic);
641+
if (ImplSP retval_sp = GetCached<ImplSP>(match_data))
642+
return retval_sp;
643+
644+
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
645+
LLDB_LOGF(log, "[%s] Search failed. Giving hardcoded a chance.", __FUNCTION__);
646+
return GetHardcoded<ImplSP>(match_data);
647+
}
648+
649+
template <typename ImplSP>
650+
ImplSP FormatManager::GetCached(FormattersMatchData &match_data) {
651+
ImplSP retval_sp;
642652
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
643653
if (match_data.GetTypeForCache()) {
644654
LLDB_LOGF(log, "\n\n[%s] Looking into cache for type %s", __FUNCTION__,
@@ -671,10 +681,6 @@ FormatManager::GetCached(ValueObject &valobj,
671681
return retval_sp;
672682
}
673683
}
674-
if (!retval_sp) {
675-
LLDB_LOGF(log, "[%s] Search failed. Giving hardcoded a chance.", __FUNCTION__);
676-
retval_sp = GetHardcoded<ImplSP>(match_data);
677-
}
678684

679685
if (match_data.GetTypeForCache() && (!retval_sp || !retval_sp->NonCacheable())) {
680686
LLDB_LOGF(log, "[%s] Caching %p for type %s", __FUNCTION__,
@@ -690,25 +696,25 @@ FormatManager::GetCached(ValueObject &valobj,
690696
lldb::TypeFormatImplSP
691697
FormatManager::GetFormat(ValueObject &valobj,
692698
lldb::DynamicValueType use_dynamic) {
693-
return GetCached<lldb::TypeFormatImplSP>(valobj, use_dynamic);
699+
return Get<lldb::TypeFormatImplSP>(valobj, use_dynamic);
694700
}
695701

696702
lldb::TypeSummaryImplSP
697703
FormatManager::GetSummaryFormat(ValueObject &valobj,
698704
lldb::DynamicValueType use_dynamic) {
699-
return GetCached<lldb::TypeSummaryImplSP>(valobj, use_dynamic);
705+
return Get<lldb::TypeSummaryImplSP>(valobj, use_dynamic);
700706
}
701707

702708
lldb::SyntheticChildrenSP
703709
FormatManager::GetSyntheticChildren(ValueObject &valobj,
704710
lldb::DynamicValueType use_dynamic) {
705-
return GetCached<lldb::SyntheticChildrenSP>(valobj, use_dynamic);
711+
return Get<lldb::SyntheticChildrenSP>(valobj, use_dynamic);
706712
}
707713

708714
lldb::TypeValidatorImplSP
709715
FormatManager::GetValidator(ValueObject &valobj,
710716
lldb::DynamicValueType use_dynamic) {
711-
return GetCached<lldb::TypeValidatorImplSP>(valobj, use_dynamic);
717+
return Get<lldb::TypeValidatorImplSP>(valobj, use_dynamic);
712718
}
713719

714720
FormatManager::FormatManager()

0 commit comments

Comments
 (0)