diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2023-11-08 11:02:33 +0100 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2023-11-08 22:50:10 +0100 |
commit | 79ac262c926ea2845a5ed50d7abe5e9572fbdfc6 (patch) | |
tree | a370a98302aee8ac941f75f4f8db907447a6d451 /svl | |
parent | 4726801b3f4fb26373a0cbcb3c0e437449fa3baa (diff) |
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 <sbergman@redhat.com>
Diffstat (limited to 'svl')
-rw-r--r-- | svl/source/items/poolitem.cxx | 13 |
1 files changed, 9 insertions, 4 deletions
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"); |