AK: Use of uninitialized memory in HashTable
Found by running Ladybird in valgrind and opening https://linus.dev/
Reproduces every time.
cc @kleinesfilmroellchen @Hendiadyoin1
==148160== Use of uninitialised value of size 8
==148160== at 0x69E963F: AK::HashTable<AK::HashMap<AK::Span<unsigned int>, AK::RefPtr<Gfx::Bitmap>, AK::Traits<AK::Span<unsigned int> >, false>::Entry, AK::HashMap<AK::Span<unsigned int>, AK::RefPtr<Gfx::Bitmap>, AK::Traits<AK::Span<unsigned int> >, false>::EntryTraits, false>::try_lookup_for_writing(AK::HashMap<AK::Span<unsigned int>, AK::RefPtr<Gfx::Bitmap>, AK::Traits<AK::Span<unsigned int> >, false>::Entry const&) (HashTable.h:675)
==148160== by 0x69E938E: lookup_for_writing (HashTable.h:691)
==148160== by 0x69E938E: insert_during_rehash (HashTable.h:446)
==148160== by 0x69E938E: AK::HashTable<AK::HashMap<AK::Span<unsigned int>, AK::RefPtr<Gfx::Bitmap>, AK::Traits<AK::Span<unsigned int> >, false>::Entry, AK::HashMap<AK::Span<unsigned int>, AK::RefPtr<Gfx::Bitmap>, AK::Traits<AK::Span<unsigned int> >, false>::EntryTraits, false>::try_rehash(unsigned long) (HashTable.h:502)
==148160== by 0x69E9513: AK::HashTable<AK::HashMap<AK::Span<unsigned int>, AK::RefPtr<Gfx::Bitmap>, AK::Traits<AK::Span<unsigned int> >, false>::Entry, AK::HashMap<AK::Span<unsigned int>, AK::RefPtr<Gfx::Bitmap>, AK::Traits<AK::Span<unsigned int> >, false>::EntryTraits, false>::try_lookup_for_writing(AK::HashMap<AK::Span<unsigned int>, AK::RefPtr<Gfx::Bitmap>, AK::Traits<AK::Span<unsigned int> >, false>::Entry const&) (HashTable.h:669)
==148160== by 0x69E85C2: try_set<AK::HashMap<AK::Span<unsigned int>, AK::RefPtr<Gfx::Bitmap> >::Entry> (HashTable.h:311)
==148160== by 0x69E85C2: set<> (HashTable.h:340)
==148160== by 0x69E85C2: set (HashMap.h:52)
==148160== by 0x69E85C2: Gfx::Emoji::emoji_for_code_points(AK::Span<unsigned int> const&) [clone .part.0] (Emoji.cpp:37)
==148160== by 0x69E8994: Gfx::Emoji::emoji_for_code_point_iterator(AK::Utf8CodePointIterator&) (Emoji.cpp:69)
==148160== by 0x69CA92A: Gfx::Painter::draw_glyph_or_emoji(Gfx::Point<int> const&, AK::Utf8CodePointIterator&, Gfx::Font const&, Gfx::Color) (Painter.cpp:1383)
==148160== by 0x69CAAE7: Gfx::Painter::draw_text_run(Gfx::Point<float> const&, AK::Utf8View const&, Gfx::Font const&, Gfx::Color) (Painter.cpp:2407)
==148160== by 0x4DE24F9: paint_text_fragment (PaintableBox.cpp:431)
==148160== by 0x4DE24F9: Web::Painting::PaintableWithLines::paint(Web::PaintContext&, Web::Painting::PaintPhase) const (PaintableBox.cpp:516)
==148160== by 0x4DEAA62: paint_node (StackingContext.cpp:27)
==148160== by 0x4DEAA62: operator()<Web::Layout::Node> (StackingContext.cpp:111)
==148160== by 0x4DEAA62: for_each_child<Web::Painting::StackingContext::paint_descendants(Web::PaintContext&, Web::Layout::Node&, Web::Painting::StackingContext::StackingContextPaintPhase) const::<lambda(auto:36&)> > (TreeNode.h:332)
==148160== by 0x4DEAA62: Web::Painting::StackingContext::paint_descendants(Web::PaintContext&, Web::Layout::Node&, Web::Painting::StackingContext::StackingContextPaintPhase) const (StackingContext.cpp:76)
==148160== by 0x4DEAA75: operator()<Web::Layout::Node> (StackingContext.cpp:112)
==148160== by 0x4DEAA75: for_each_child<Web::Painting::StackingContext::paint_descendants(Web::PaintContext&, Web::Layout::Node&, Web::Painting::StackingContext::StackingContextPaintPhase) const::<lambda(auto:36&)> > (TreeNode.h:332)
==148160== by 0x4DEAA75: Web::Painting::StackingContext::paint_descendants(Web::PaintContext&, Web::Layout::Node&, Web::Painting::StackingContext::StackingContextPaintPhase) const (StackingContext.cpp:76)
==148160== by 0x4DEAA75: operator()<Web::Layout::Node> (StackingContext.cpp:112)
==148160== by 0x4DEAA75: for_each_child<Web::Painting::StackingContext::paint_descendants(Web::PaintContext&, Web::Layout::Node&, Web::Painting::StackingContext::StackingContextPaintPhase) const::<lambda(auto:36&)> > (TreeNode.h:332)
==148160== by 0x4DEAA75: Web::Painting::StackingContext::paint_descendants(Web::PaintContext&, Web::Layout::Node&, Web::Painting::StackingContext::StackingContextPaintPhase) const (StackingContext.cpp:76)
==148160== by 0x4DEAA75: operator()<Web::Layout::Node> (StackingContext.cpp:112)
==148160== by 0x4DEAA75: for_each_child<Web::Painting::StackingContext::paint_descendants(Web::PaintContext&, Web::Layout::Node&, Web::Painting::StackingContext::StackingContextPaintPhase) const::<lambda(auto:36&)> > (TreeNode.h:332)
==148160== by 0x4DEAA75: Web::Painting::StackingContext::paint_descendants(Web::PaintContext&, Web::Layout::Node&, Web::Painting::StackingContext::StackingContextPaintPhase) const (StackingContext.cpp:76)
The emojis on Linus's site sometimes render wrong, which is most likely related to this bug.
OK on my machine it shows an error above, with the same back-trace, just two lines above the bug highlighted here So
for (;;) {
auto& bucket = m_buckets[hash % m_capacity]; // -> Conditional jump or move depends on uninitialised value(s)
if (is_used_bucket(bucket.state) && TraitsForT::equals(*bucket.slot(), value)) // -> Use of uninitialised value of size 8
return &bucket;
The error shown and all errors below that (there are a lot) come from the fact that valgrind thinks that m_buckets contains at least one uninitialized value. At this point m_buckets should be freshly allocated by calloc, which memsets the allocated memory to 0 (because we are in a rehash), So either valgrind does not know this or we get unitialized data from somewhere else, but the latter one should have been called out by valgrind as well.
So my guess is that valgrind is oblivious to calloc, which is unlikely...