https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108288
Bug ID: 108288 Summary: Deadlock when using -fno-elide-constructor + -D_GLIBCXX_DEBUG=1 + -std=c++11 Product: gcc Version: 12.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: simon.marchi at polymtl dot ca Target Milestone: --- I built GDB with -fno-elide-constructor in order to chase / prove a bug in some move constructor (which would get elided otherwise, hiding the problem). I also used -D_GLIBCXX_DEBUG=1 and -std=c++11, I think it's important here. This results in a deadlock in GDB, when trying to run a simple program: (top-gdb) bt 15 #0 futex_wait (private=0, expected=2, futex_word=0x7ffff6e35f80 <__gnu_internal::get_mutex(unsigned char)::m>) at ../sysdeps/nptl/futex-internal.h:146 #1 __GI___lll_lock_wait (futex=futex@entry=0x7ffff6e35f80 <__gnu_internal::get_mutex(unsigned char)::m>, private=0) at lowlevellock.c:49 #2 0x00007ffff69bac12 in lll_mutex_lock_optimized (mutex=0x7ffff6e35f80 <__gnu_internal::get_mutex(unsigned char)::m>) at pthread_mutex_lock.c:48 #3 ___pthread_mutex_lock (mutex=0x7ffff6e35f80 <__gnu_internal::get_mutex(unsigned char)::m>) at pthread_mutex_lock.c:93 #4 0x00007ffff6cd2518 in __gthread_mutex_lock (__mutex=0x7ffff6e35f80 <__gnu_internal::get_mutex(unsigned char)::m>) at /usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:749#5 __gnu_cxx::__mutex::lock (this=0x7ffff6e35f80 <__gnu_internal::get_mutex(unsigned char)::m>) at /usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/ext/concurrence.h:149 #6 __gnu_cxx::__scoped_lock::__scoped_lock (__name=..., this=<synthetic pointer>) at /usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/ext/concurrence.h:241 #7 __gnu_debug::_Safe_iterator_base::_M_detach (this=0x7fffffffa5a8) at /usr/src/debug/gcc/libstdc++-v3/src/c++11/debug.cc:408 #8 0x0000555557fd1608 in __gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<other_sections const**, std::__cxx1998::vector<other_sections const*, std::allocator<other_sections const*> > >, std::__debug::vector<other_sections const*, std::allocator<other_sections const*> >, std::forward_iterator_tag>::_Safe_iterator (this=0x7fffffffaab0, __x=...) at /usr/include/c++/12.2.0/debug/safe_iterator.h:201 #9 0x0000555557fcf919 in __gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<other_sections const**, std::__cxx1998::vector<other_sections const*, std::allocator<other_sections const*> > >, std::__debug::vector<other_sections const*, std::allocator<other_sections const*> >, std::bidirectional_iterator_tag>::_Safe_iterator (this=0x7fffffffaab0) at /usr/include/c++/12.2.0/debug/safe_iterator.h:550 #10 0x0000555557fcf93f in __gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<other_sections const**, std::__cxx1998::vector<other_sections const*, std::allocator<other_sections const*> > >, std::__debug::vector<other_sections const*, std::allocator<other_sections const*> >, std::random_access_iterator_tag>::_Safe_iterator (this=0x7fffffffaab0) at /usr/include/c++/12.2.0/debug/safe_iterator.h:699 #11 0x0000555557fd2734 in __gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<other_sections const**, std::__cxx1998::vector<other_sections const*, std::allocator<other_sections const*> > >, std::__debug::vector<other_sections const*, std::allocator<other_sections const*> >, std::random_access_iterator_tag>::operator++ (this=0x7fffffffa7e0) at /usr/include/c++/12.2.0/debug/safe_iterator.h:764 #12 0x0000555557fa6341 in addr_info_make_relative (addrs=0x7fffffffb8f0, abfd=0x6120000ebfc0) at /home/simark/src/binutils-gdb/gdb/symfile.c:551 #13 0x0000555557fa8cee in syms_from_objfile_1 (objfile=0x614000007e40, addrs=0x7fffffffb8f0, add_flags=...) at /home/simark/src/binutils-gdb/gdb/symfile.c:957 #14 0x0000555557fa9106 in syms_from_objfile (objfile=0x614000007e40, addrs=0x7fffffffb8f0, add_flags=...) at /home/simark/src/binutils-gdb/gdb/symfile.c:985 (More stack frames follow...) My theory is: - frame #11 has acquired the lock at 0x7ffff6e35f80: (top-gdb) frame 11 #11 0x0000555557fd2734 in __gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<other_sections const**, std::__cxx1998::vector<other_sections const*, std::allocator<other_sections const*> > >, std::__debug::vector<other_sections const*, std::allocator<other_sections const*> >, std::random_access_iterator_tag>::operator++ (this=0x7fffffffa7e0) at /usr/include/c++/12.2.0/debug/safe_iterator.h:764 764 _Attach_single()); (top-gdb) print __l._M_device $12 = (__gnu_cxx::__scoped_lock::__mutex_type &) @0x7ffff6e35f80: { - frame #7 is trying to acquire the same lock: (top-gdb) frame 7 #7 __gnu_debug::_Safe_iterator_base::_M_detach (this=0x7fffffffa5a8) at /usr/src/debug/gcc/libstdc++-v3/src/c++11/debug.cc:408 408 /usr/src/debug/gcc/libstdc++-v3/src/c++11/debug.cc: Bad file descriptor. (top-gdb) frame 6 #6 __gnu_cxx::__scoped_lock::__scoped_lock (__name=..., this=<synthetic pointer>) at /usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/ext/concurrence.h:241 241 /usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/ext/concurrence.h: Bad file descriptor. (top-gdb) p __name $13 = (__gnu_cxx::__scoped_lock::__mutex_type &) @0x7ffff6e35f80: { - This isn't normally seen because the move construction of _Safe_iterator (frame 10) would normally get elided.