svl/source/items/poolitem.cxx |   13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

New commits:
commit 79ac262c926ea2845a5ed50d7abe5e9572fbdfc6
Author:     Stephan Bergmann <[email protected]>
AuthorDate: Wed Nov 8 11:02:33 2023 +0100
Commit:     Stephan Bergmann <[email protected]>
CommitDate: Wed Nov 8 22:50:10 2023 +0100

    Avoid initialization-order-fiasco in DBG_UTIL code
    
    ...as reported by <https://ci.libreoffice.org/job/lo_ubsan/2973/> during 
e.g.
    Gallery_backgrounds, when initializing the global variable
    
    > const Cell OBJ_CELL_NONE;
    
    at svx/source/dialog/framelinkarray.cxx:281,
    
    > ==519895==ERROR: AddressSanitizer: initialization-order-fiasco on address 
0x7fb3dc3e5570 at pc 0x7fb3daee1c56 bp 0x7ffe54584480 sp 0x7ffe54584478
    > READ of size 8 at 0x7fb3dc3e5570 thread T0
    >     #0 0x7fb3daee1c55 in std::_Hashtable<SfxPoolItem const*, SfxPoolItem 
const*, std::allocator<SfxPoolItem const*>, std::__detail::_Identity, 
std::equal_to<SfxPoolItem const*>, std::hash<SfxPoolItem const*>, 
std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, 
std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, 
true, true> >::bucket_count() const 
/opt/rh/gcc-toolset-12/root/usr/lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/hashtable.h:673:16
    >     #1 0x7fb3daee1648 in std::__cxx1998::unordered_set<SfxPoolItem 
const*, std::hash<SfxPoolItem const*>, std::equal_to<SfxPoolItem const*>, 
std::allocator<SfxPoolItem const*> >::bucket_count() const 
/opt/rh/gcc-toolset-12/root/usr/lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/unordered_set.h:755:21
    >     #2 0x7fb3daeb1088 in std::__debug::unordered_set<SfxPoolItem const*, 
std::hash<SfxPoolItem const*>, std::equal_to<SfxPoolItem const*>, 
std::allocator<SfxPoolItem const*> >::insert(SfxPoolItem const*&&) 
/opt/rh/gcc-toolset-12/root/usr/lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/debug/unordered_set:369:35
    >     #3 0x7fb3db01987c in SfxPoolItem::SfxPoolItem(unsigned short) 
/svl/source/items/poolitem.cxx:506:28
    >     #4 0x7fb3cb2fddb4 in svx::frame::(anonymous namespace)::Cell::Cell() 
/svx/source/dialog/framelinkarray.cxx:204:5
    >     #5 0x7fb3cafa3b6f in __cxx_global_var_init.1 
/svx/source/dialog/framelinkarray.cxx:281:12
    >     #6 0x7fb3cafa3ba9 in _GLOBAL__sub_I_framelinkarray.cxx 
/svx/source/dialog/framelinkarray.cxx
    >     #7 0x7fb3e6821f19 in call_init.part.0 
/usr/src/debug/glibc-2.28-225.el8_8.6.x86_64/elf/dl-init.c:72:3
    >     #8 0x7fb3e6822019 in call_init 
/usr/src/debug/glibc-2.28-225.el8_8.6.x86_64/elf/dl-init.c:118:11
    >     #9 0x7fb3e6822019 in _dl_init 
/usr/src/debug/glibc-2.28-225.el8_8.6.x86_64/elf/dl-init.c:119:5
    >     #10 0x7fb3e6836cb9  (/lib64/ld-linux-x86-64.so.2+0x1dcb9)
    >
    > 0x7fb3dc3e5570 is located 48 bytes inside of global variable 
'incarnatedSfxPoolItems' defined in 
'/home/tdf/lode/jenkins/workspace/lo_ubsan/svl/source/items/poolitem.cxx:473:47'
 (0x7fb3dc3e5540) of size 96
    >   registered at:
    >     #0 0x43c078 in __asan_register_globals.part.0 
/home/tdf/lode/packages/llvm-llvmorg-12.0.1.src/compiler-rt/lib/asan/asan_globals.cpp:360:3
    >     #1 0x7fb3db01e7cb in asan.module_ctor 
(/instdir/program/libsvllo.so+0xb3c7cb)
    
    Change-Id: I490fb232e0944f18c49b734c621e1bf0c318baff
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159120
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <[email protected]>

diff --git a/svl/source/items/poolitem.cxx b/svl/source/items/poolitem.cxx
index 94ce9ceb2965..49990079367c 100644
--- a/svl/source/items/poolitem.cxx
+++ b/svl/source/items/poolitem.cxx
@@ -470,11 +470,16 @@ static size_t nAllocatedSfxPoolItemCount(0);
 static size_t nUsedSfxPoolItemCount(0);
 size_t getAllocatedSfxPoolItemCount() { return nAllocatedSfxPoolItemCount; }
 size_t getUsedSfxPoolItemCount() { return nUsedSfxPoolItemCount; }
-static std::unordered_set<const SfxPoolItem*> incarnatedSfxPoolItems;
+static std::unordered_set<const SfxPoolItem*>& incarnatedSfxPoolItems()
+{
+    // Deferred instantiation to avoid initialization-order-fiasco:
+    static std::unordered_set<const SfxPoolItem*> items;
+    return items;
+}
 void listAllocatedSfxPoolItems()
 {
     SAL_INFO("svl.items", "ITEM: List of still allocated SfxPoolItems:");
-    for (const auto& rCandidate : incarnatedSfxPoolItems)
+    for (const auto& rCandidate : incarnatedSfxPoolItems())
     {
         SAL_INFO("svl.items", "  ITEM: WhichID: " << rCandidate->Which() << "  
SerialNumber: "
                                                   << 
rCandidate->getSerialNumber()
@@ -503,7 +508,7 @@ SfxPoolItem::SfxPoolItem(sal_uInt16 const nWhich)
 #ifdef DBG_UTIL
     nAllocatedSfxPoolItemCount++;
     nUsedSfxPoolItemCount++;
-    incarnatedSfxPoolItems.insert(this);
+    incarnatedSfxPoolItems().insert(this);
 #endif
     assert(nWhich <= SHRT_MAX);
 }
@@ -512,7 +517,7 @@ SfxPoolItem::~SfxPoolItem()
 {
 #ifdef DBG_UTIL
     nAllocatedSfxPoolItemCount--;
-    incarnatedSfxPoolItems.erase(this);
+    incarnatedSfxPoolItems().erase(this);
     m_bDeleted = true;
 #endif
     assert((m_nRefCount == 0 || m_nRefCount > SFX_ITEMS_MAXREF) && "destroying 
item in use");

Reply via email to