public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libstdc++/109889] New: [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026
@ 2023-05-17 11:10 redi at gcc dot gnu.org
  2023-05-17 11:17 ` [Bug libstdc++/109889] " redi at gcc dot gnu.org
                   ` (13 more replies)
  0 siblings, 14 replies; 15+ messages in thread
From: redi at gcc dot gnu.org @ 2023-05-17 11:10 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109889

            Bug ID: 109889
           Summary: [13/14 Regression] Segfault in __run_exit_handlers
                    since r13-5309-gc3c6c307792026
           Product: gcc
           Version: 14.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: redi at gcc dot gnu.org
  Target Milestone: ---
            Target: powerpc64le-unknown-linux-gnu

Created attachment 55099
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55099&action=edit
Gzipped preprocessed source

I'm seeing test failures on powerpc64le when using -D_GLIBCXX_DEBUG, which
started with r13-5309-gc3c6c307792026. I don't see anything wrong with that
library change, so if I'm not missing something silly, then it might be a
latent compiler bug that was revealed by reducing the amount of code run in the
library.

The attached preprocessed source crashes when built with -O2
-ffunction-sections -Wl,--gc-sections

It runs OK with -fno-lifetime-dse or with -fsanitize=undefined or if either of
-ffunction-sections or -Wl,--gc-sections is removed.


At the crash GDB shows:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff765b7cc in __run_exit_handlers (status=<optimized out>, 
    listp=0x7ffff7860ad0 <__exit_funcs>, 
    run_list_atexit=run_list_atexit@entry=true, 
    run_dtors=run_dtors@entry=true) at exit.c:62
62                __exit_funcs_done = true;                                   
─── Assembly ─────────────────────────────────────────────────────────────────
 0x00007ffff765b7b8  __run_exit_handlers+600 std     r9,0(r24)
 0x00007ffff765b7bc  __run_exit_handlers+604 bne     0x7ffff765b8d8
<__run_exit_handlers+888>
 0x00007ffff765b7c0  __run_exit_handlers+608 li      r10,1
 0x00007ffff765b7c4  __run_exit_handlers+612 nop
 0x00007ffff765b7c8  __run_exit_handlers+616 li      r9,0
 0x00007ffff765b7cc  __run_exit_handlers+620 stb     r10,-18040(r2)
 0x00007ffff765b7d0  __run_exit_handlers+624 lwsync
 0x00007ffff765b7d4  __run_exit_handlers+628 lwarx   r10,0,r31
 0x00007ffff765b7d8  __run_exit_handlers+632 stwcx.  r9,0,r31
 0x00007ffff765b7dc  __run_exit_handlers+636 bne-    0x7ffff765b7d4
<__run_exit_handlers+628>
─── Registers ────────────────────────────────────────────────────────────────
             r0 0x00007ffff765b700              r1 0x00007fffffffe8b0
             r2 0x0000000000000000              r3 0x0000000000000000
             r4 0x0000000000000000              r5 0x0000000000000000
             r6 0x0000000000000000              r7 0x0000000000000000
             r8 0x0000000000000000              r9 0x0000000000000000
            r10 0x0000000000000001             r11 0x0000000000002000
            r12 0x00007ffff7a30960             r13 0x00007ffff7ffc320
            r14 0x0000000000000000             r15 0x0000000000000000
            r16 0x0000000000000000             r17 0x0000000000000000
            r18 0x0000000000000000             r19 0x0000000000000000
            r20 0x0000000000000000             r21 0x0000000000000000
            r22 0x0000000000000000             r23 0x0000000000000001
            r24 0x00007ffff7860ad0             r25 0x0000000000000000
            r26 0x0000000000000000             r27 0x00007ffff7862468
            r28 0x0000000000000001             r29 0x0000000000000000
            r30 0x00007ffff7862458             r31 0x00007ffff7862868
             pc 0x00007ffff765b7cc             msr 0x900000000000d033
             cr 0x24002422                      lr 0x00007ffff765b700
            ctr 0x0000000000000000             xer 0x000000dd        
          fpscr 0x0000000000000000            vscr 0x00000000        
         vrsave 0xffffffff                     ppr 0x000c000000000000
           dscr 0x0000000000000010             tar 0x0000000000000000
          mmcr0 0x0000000000000000           mmcr2 0x0000000000000000
           siar 0x0000000000000000            sdar 0x0000000000000000
           sier 0x0000000000000000         orig_r3 0x00007ffff765b61c
           trap 0x0000000000000380
─── Source ───────────────────────────────────────────────────────────────────
 57  
 58        if (cur == NULL)
 59      {
 60        /* Exit processing complete.  We will not allow any more
 61           atexit/on_exit registrations.  */
 62        __exit_funcs_done = true;
 63        break;
 64      }
 65  
 66        while (cur->idx > 0)
─── Stack ────────────────────────────────────────────────────────────────────
[0] from 0x00007ffff765b7cc in __run_exit_handlers+620 at exit.c:62
[1] from 0x00007ffff765b948 in __GI_exit+40 at exit.c:143
[2] from 0x00007ffff7637fb8 in __libc_start_call_main+168 at
../sysdeps/nptl/libc_start_call_main.h:74
[3] from 0x00007ffff76381ec in generic_start_main+252 at
../csu/libc-start.c:381
[4] from 0x00007ffff76381ec in __libc_start_main_impl+428 at
../sysdeps/unix/sysv/linux/powerpc/libc-start.c:109
[5] from 0x0000000000000000
─── Threads ──────────────────────────────────────────────────────────────────
[1] id 3179009 name a.out from 0x00007ffff765b7cc in __run_exit_handlers+620 at
exit.c:62
─── Variables ────────────────────────────────────────────────────────────────
arg status = <optimized out>, listp = 0x7ffff7860ad0 <__exit_funcs>: Cannot
access memory at address 0x0, run_list_atexit = true, run_dtors = true
loc cur = <optimized out>



The preprocessed source was generated from the libstdc++ testsuite like so:

$ $GCC/bin/g++ -O2
~/src/gcc/libstdc++-v3/testsuite/ext/throw_allocator/check_deallocate_null.cc
-I ~/src/gcc/libstdc++-v3/testsuite/util/ -ffunction-sections -Wl,--gc-sections
-D_GLIBCXX_DEBUG -Wl,-rpath,$GCC/lib64 -save-temps -v  && ./a.out
Using built-in specs.
COLLECT_GCC=/tmp/usr/local/bin/g++
COLLECT_LTO_WRAPPER=/tmp/usr/local/bin/../libexec/gcc/powerpc64le-unknown-linux-gnu/14.0.0/lto-wrapper
Target: powerpc64le-unknown-linux-gnu
Configured with: /home/test/src/gcc/configure --enable-languages=c++,c
--disable-nls --without-isl --disable-libitm --disable-libssp --disable-libgomp
--disable-libvtv --disable-libcc1 --disable-libsanitizer
--disable-libstdcxx-pch --disable-bootstrap
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 14.0.0 20230516 (experimental) (GCC) 
COLLECT_GCC_OPTIONS='-O2' '-I'
'/home/test/src/gcc/libstdc++-v3/testsuite/util/' '-ffunction-sections' '-D'
'_GLIBCXX_DEBUG' '-save-temps' '-v' '-shared-libgcc' '-dumpdir' 'a-'
 /tmp/usr/local/bin/../libexec/gcc/powerpc64le-unknown-linux-gnu/14.0.0/cc1plus
-E -quiet -v -I /home/test/src/gcc/libstdc++-v3/testsuite/util/ -iprefix
/tmp/usr/local/bin/../lib/gcc/powerpc64le-unknown-linux-gnu/14.0.0/
-D_GNU_SOURCE -D _GLIBCXX_DEBUG
/home/test/src/gcc/libstdc++-v3/testsuite/ext/throw_allocator/check_deallocate_null.cc
-ffunction-sections -O2 -fpch-preprocess -o a-check_deallocate_null.ii
ignoring nonexistent directory
"/tmp/usr/local/bin/../lib/gcc/powerpc64le-unknown-linux-gnu/14.0.0/../../../../powerpc64le-unknown-linux-gnu/include"
ignoring duplicate directory
"/tmp/usr/local/bin/../lib/gcc/../../lib/gcc/powerpc64le-unknown-linux-gnu/14.0.0/../../../../include/c++/14.0.0"
ignoring duplicate directory
"/tmp/usr/local/bin/../lib/gcc/../../lib/gcc/powerpc64le-unknown-linux-gnu/14.0.0/../../../../include/c++/14.0.0/powerpc64le-unknown-linux-gnu"
ignoring duplicate directory
"/tmp/usr/local/bin/../lib/gcc/../../lib/gcc/powerpc64le-unknown-linux-gnu/14.0.0/../../../../include/c++/14.0.0/backward"
ignoring duplicate directory
"/tmp/usr/local/bin/../lib/gcc/../../lib/gcc/powerpc64le-unknown-linux-gnu/14.0.0/include"
ignoring duplicate directory
"/tmp/usr/local/bin/../lib/gcc/../../lib/gcc/powerpc64le-unknown-linux-gnu/14.0.0/include-fixed"
ignoring nonexistent directory
"/tmp/usr/local/bin/../lib/gcc/../../lib/gcc/powerpc64le-unknown-linux-gnu/14.0.0/../../../../powerpc64le-unknown-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /home/test/src/gcc/libstdc++-v3/testsuite/util/

/tmp/usr/local/bin/../lib/gcc/powerpc64le-unknown-linux-gnu/14.0.0/../../../../include/c++/14.0.0

/tmp/usr/local/bin/../lib/gcc/powerpc64le-unknown-linux-gnu/14.0.0/../../../../include/c++/14.0.0/powerpc64le-unknown-linux-gnu

/tmp/usr/local/bin/../lib/gcc/powerpc64le-unknown-linux-gnu/14.0.0/../../../../include/c++/14.0.0/backward
 /tmp/usr/local/bin/../lib/gcc/powerpc64le-unknown-linux-gnu/14.0.0/include

/tmp/usr/local/bin/../lib/gcc/powerpc64le-unknown-linux-gnu/14.0.0/include-fixed
 /usr/local/include
 /usr/include
End of search list.
COLLECT_GCC_OPTIONS='-O2' '-I'
'/home/test/src/gcc/libstdc++-v3/testsuite/util/' '-ffunction-sections' '-D'
'_GLIBCXX_DEBUG' '-save-temps' '-v' '-shared-libgcc' '-dumpdir' 'a-'
 /tmp/usr/local/bin/../libexec/gcc/powerpc64le-unknown-linux-gnu/14.0.0/cc1plus
-fpreprocessed a-check_deallocate_null.ii -quiet -dumpdir a- -dumpbase
check_deallocate_null.cc -dumpbase-ext .cc -O2 -version -ffunction-sections -o
a-check_deallocate_null.s
GNU C++17 (GCC) version 14.0.0 20230516 (experimental)
(powerpc64le-unknown-linux-gnu)
        compiled by GNU C version 12.3.1 20230508 (Red Hat 12.3.1-1), GMP
version 6.2.1, MPFR version 4.1.0-p13, MPC version 1.2.1, isl version none
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
Compiler executable checksum: 5613d942ec03ccc046b8b073d0c66526
COLLECT_GCC_OPTIONS='-O2' '-I'
'/home/test/src/gcc/libstdc++-v3/testsuite/util/' '-ffunction-sections' '-D'
'_GLIBCXX_DEBUG' '-save-temps' '-v' '-shared-libgcc' '-dumpdir' 'a-'
 as -v -I /home/test/src/gcc/libstdc++-v3/testsuite/util/ -a64 -mpower8
-mlittle -o a-check_deallocate_null.o a-check_deallocate_null.s
GNU assembler version 2.38 (ppc64le-redhat-linux) using BFD version version
2.38-27.fc37
COMPILER_PATH=/tmp/usr/local/bin/../libexec/gcc/powerpc64le-unknown-linux-gnu/14.0.0/:/tmp/usr/local/bin/../libexec/gcc/
LIBRARY_PATH=/tmp/usr/local/bin/../lib/gcc/powerpc64le-unknown-linux-gnu/14.0.0/:/tmp/usr/local/bin/../lib/gcc/:/tmp/usr/local/bin/../lib/gcc/powerpc64le-unknown-linux-gnu/14.0.0/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/tmp/usr/local/bin/../lib/gcc/powerpc64le-unknown-linux-gnu/14.0.0/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-O2' '-I'
'/home/test/src/gcc/libstdc++-v3/testsuite/util/' '-ffunction-sections' '-D'
'_GLIBCXX_DEBUG' '-save-temps' '-v' '-shared-libgcc' '-dumpdir' 'a.'

/tmp/usr/local/bin/../libexec/gcc/powerpc64le-unknown-linux-gnu/14.0.0/collect2
-plugin
/tmp/usr/local/bin/../libexec/gcc/powerpc64le-unknown-linux-gnu/14.0.0/liblto_plugin.so
-plugin-opt=/tmp/usr/local/bin/../libexec/gcc/powerpc64le-unknown-linux-gnu/14.0.0/lto-wrapper
-plugin-opt=-fresolution=a.res -plugin-opt=-pass-through=-lgcc_s
-plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc
-plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc
--eh-frame-hdr -V -m elf64lppc -dynamic-linker /lib64/ld64.so.2
/lib/../lib64/crt1.o /lib/../lib64/crti.o
/tmp/usr/local/bin/../lib/gcc/powerpc64le-unknown-linux-gnu/14.0.0/crtbegin.o
-L/tmp/usr/local/bin/../lib/gcc/powerpc64le-unknown-linux-gnu/14.0.0
-L/tmp/usr/local/bin/../lib/gcc
-L/tmp/usr/local/bin/../lib/gcc/powerpc64le-unknown-linux-gnu/14.0.0/../../../../lib64
-L/lib/../lib64 -L/usr/lib/../lib64
-L/tmp/usr/local/bin/../lib/gcc/powerpc64le-unknown-linux-gnu/14.0.0/../../..
a-check_deallocate_null.o --gc-sections -rpath /tmp/usr/local/lib64 -lstdc++
-lm -lgcc_s -lgcc -lc -lgcc_s -lgcc
/tmp/usr/local/bin/../lib/gcc/powerpc64le-unknown-linux-gnu/14.0.0/crtend.o
/lib/../lib64/crtn.o
GNU ld version 2.38-27.fc37
  Supported emulations:
   elf64lppc
   elf32lppc
   elf32lppclinux
   elf32lppcsim
   elf64ppc
   elf32ppc
   elf32ppclinux
   elf32ppcsim
   elf32_spu
   i386pep
   i386pe
   elf64bpf
COLLECT_GCC_OPTIONS='-O2' '-I'
'/home/test/src/gcc/libstdc++-v3/testsuite/util/' '-ffunction-sections' '-D'
'_GLIBCXX_DEBUG' '-save-temps' '-v' '-shared-libgcc' '-dumpdir' 'a.'
Segmentation fault (core dumped)


I see this on power 9 fedora 37 (glibc-2.36) but not on power 8 centos 7.9
(glibc-2.17).

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Bug libstdc++/109889] [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026
  2023-05-17 11:10 [Bug libstdc++/109889] New: [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026 redi at gcc dot gnu.org
@ 2023-05-17 11:17 ` redi at gcc dot gnu.org
  2023-05-17 11:25 ` jakub at gcc dot gnu.org
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: redi at gcc dot gnu.org @ 2023-05-17 11:17 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109889

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Tulio found out that __gnu_debug::_Safe_iterator_base::_M_reset() is
overwriting the stack where r2 (TOC pointer) was saved by __run_exit_handlers()
(at address 0x00007fffffffe8e8). This function was called with the wrong
address of the object.

He was able to track this value back from
__gnu_debug::_Safe_sequence_base::_M_detach_all() at debug.cc:325

p *this
$1 = {
  _M_iterators = 0x7fffffffe8e8,
  _M_const_iterators = 0x0,
  _M_version = 1
}

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Bug libstdc++/109889] [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026
  2023-05-17 11:10 [Bug libstdc++/109889] New: [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026 redi at gcc dot gnu.org
  2023-05-17 11:17 ` [Bug libstdc++/109889] " redi at gcc dot gnu.org
@ 2023-05-17 11:25 ` jakub at gcc dot gnu.org
  2023-05-17 11:26 ` redi at gcc dot gnu.org
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: jakub at gcc dot gnu.org @ 2023-05-17 11:25 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109889

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
r2 is the toc pointer, so having it 0 is weird.
Looking at glibc-2.36-10.fc37 (not sure if you are using a different one), I
see
000000000005b560 <__run_exit_handlers>:
   5b560:       21 00 4c 3c     addis   r2,r12,33
   5b564:       a0 b9 42 38     addi    r2,r2,-18016
...
   5b5a8:       18 00 41 f8     std     r2,24(r1)
so wonder what x/1gx $r1+24 is.  Most likely some call from that function
didn't restore r2 properly?
Though, I believe in PowerPC ELFv2 it is the caller's responsibility to restore
it
and that is why it has the nops after bl (in case the call is guaranteed to be
into code with the same TOC) and ld r2,24(r1) otherwise.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Bug libstdc++/109889] [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026
  2023-05-17 11:10 [Bug libstdc++/109889] New: [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026 redi at gcc dot gnu.org
  2023-05-17 11:17 ` [Bug libstdc++/109889] " redi at gcc dot gnu.org
  2023-05-17 11:25 ` jakub at gcc dot gnu.org
@ 2023-05-17 11:26 ` redi at gcc dot gnu.org
  2023-05-17 11:30 ` redi at gcc dot gnu.org
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: redi at gcc dot gnu.org @ 2023-05-17 11:26 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109889

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
I wonder if we have a static destructor ordering problem.

The libstdc++  test code uses a local static std::map, which will be
constructed on first use and destroyed on exit. When built with
-D_GLIBCXX_DEBUG that is a __gnu_debug::map which uses checked iterators, so
keeps a list of all constructed iterators. On destruction that map locks a
mutex, which is another local static, and .

Since r13-6282-gd70f49e98245f8 the mutexes are created in a char buffer and
never destroyed:

    // Use a static buffer, so that the mutexes are not destructed
    // before potential users (or at all)
    static __attribute__ ((aligned(__alignof__(M))))
      char buffer[(sizeof (M)) * (mask + 1)];
    static M *m = new (buffer) M[mask + 1];
    return m[i];

But something could be wrong with lifetimes of those statics, causing an
invalid 'this' pointer to be used somewhere.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Bug libstdc++/109889] [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026
  2023-05-17 11:10 [Bug libstdc++/109889] New: [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026 redi at gcc dot gnu.org
                   ` (2 preceding siblings ...)
  2023-05-17 11:26 ` redi at gcc dot gnu.org
@ 2023-05-17 11:30 ` redi at gcc dot gnu.org
  2023-05-17 15:04 ` tuliom at ascii dot art.br
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: redi at gcc dot gnu.org @ 2023-05-17 11:30 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109889

--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Jakub Jelinek from comment #2)
> r2 is the toc pointer, so having it 0 is weird.
> Looking at glibc-2.36-10.fc37 (not sure if you are using a different one), I

glibc-2.36-9.fc37.ppc64le

> see
> 000000000005b560 <__run_exit_handlers>:
>    5b560:       21 00 4c 3c     addis   r2,r12,33
>    5b564:       a0 b9 42 38     addi    r2,r2,-18016
> ...
>    5b5a8:       18 00 41 f8     std     r2,24(r1)
> so wonder what x/1gx $r1+24 is.

(gdb) x/1gx $r1+24
0x7fffffffe8d8: 0x0000000000000000

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Bug libstdc++/109889] [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026
  2023-05-17 11:10 [Bug libstdc++/109889] New: [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026 redi at gcc dot gnu.org
                   ` (3 preceding siblings ...)
  2023-05-17 11:30 ` redi at gcc dot gnu.org
@ 2023-05-17 15:04 ` tuliom at ascii dot art.br
  2023-05-17 15:10 ` tuliom at ascii dot art.br
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: tuliom at ascii dot art.br @ 2023-05-17 15:04 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109889

--- Comment #5 from Tulio Magno Quites Machado Filho <tuliom at ascii dot art.br> ---
(In reply to Jonathan Wakely from comment #3)
> I wonder if we have a static destructor ordering problem.

I'm afraid the issue is happening earlier, when these iterators are being
initialized.
Look at this backtrace taken during initialization:

#0  0x00007ffff7b536e4 in __gnu_debug::_Safe_sequence_base::_M_attach_single
(this=0x100414c8 <__gnu_cxx::annotate_base::map_alloc()::_S_map>, 
    __it=0x7fffffffe8f8, __constant=false) at
/home/test/src/gcc/libstdc++-v3/src/c++11/debug.cc:396
#1  0x00007ffff7b5376c in __gnu_debug::_Safe_sequence_base::_M_attach
(this=0x100414c8 <__gnu_cxx::annotate_base::map_alloc()::_S_map>, 
    __it=0x7fffffffe8f8, __constant=false) at
/home/test/src/gcc/libstdc++-v3/src/c++11/debug.cc:383
#2  0x00007ffff7b53cd8 in __gnu_debug::_Safe_iterator_base::_M_attach
(this=0x7fffffffe8f8, 
    __seq=0x100414c8 <__gnu_cxx::annotate_base::map_alloc()::_S_map>,
__constant=false) at /home/test/src/gcc/libstdc++-v3/src/c++11/debug.cc:430
#3  0x0000000010012244 in __gnu_debug::_Safe_iterator_base::_Safe_iterator_base
(__constant=false, 
    __seq=0x100414c8 <__gnu_cxx::annotate_base::map_alloc()::_S_map>,
this=<optimized out>)
    at /home/test/gcc-14/include/c++/14.0.0/debug/safe_base.h:91
#4  __gnu_debug::_Safe_iterator<std::_Rb_tree_iterator<std::pair<void* const,
std::pair<unsigned long, unsigned long> > >, std::__debug::map<void*,
std::pair<unsigned long, unsigned long>, std::less<void*>,
std::allocator<std::pair<void* const, std::pair<unsigned long, unsigned long> >
> >, std::forward_iterator_tag>::_Safe_iterator (__seq=0x100414c8
<__gnu_cxx::annotate_base::map_alloc()::_S_map>, __i=..., this=0x7fffffffe8f0)
    at /home/test/gcc-14/include/c++/14.0.0/debug/safe_iterator.h:162
#5  __gnu_debug::_Safe_iterator<std::_Rb_tree_iterator<std::pair<void* const,
std::pair<unsigned long, unsigned long> > >, std::__debug::map<void*,
std::pair<unsigned long, unsigned long>, std::less<void*>,
std::allocator<std::pair<void* const, std::pair<unsigned long, unsigned long> >
> >, std::bidirectional_iterator_tag>::_Safe_iterator (__seq=0x100414c8
<__gnu_cxx::annotate_base::map_alloc()::_S_map>, __i=..., this=0x7fffffffe8f0)
    at /home/test/gcc-14/include/c++/14.0.0/debug/safe_iterator.h:539
#6  std::__debug::map<void*, std::pair<unsigned long, unsigned long>,
std::less<void*>, std::allocator<std::pair<void* const, std::pair<unsigned
long, unsigned long> > > >::find (__x=<synthetic pointer>: 0x0, this=0x100414c8
<__gnu_cxx::annotate_base::map_alloc()::_S_map>)
    at /home/test/gcc-14/include/c++/14.0.0/debug/map.h:583
#7  __gnu_cxx::annotate_base::check_allocated (this=<optimized out>, size=4,
p=0x0)
    at /home/test/gcc-14/include/c++/14.0.0/ext/throw_allocator.h:177
#8  __gnu_cxx::annotate_base::erase (p=p@entry=0x0, size=size@entry=4,
this=<optimized out>)
    at /home/test/gcc-14/include/c++/14.0.0/ext/throw_allocator.h:146
#9  0x0000000010010474 in __gnu_cxx::throw_allocator_base<int,
__gnu_cxx::random_condition>::deallocate (this=<synthetic pointer>, __n=1, 
    __p=0x0) at /home/test/gcc-14/include/c++/14.0.0/ext/throw_allocator.h:888
#10 __gnu_test::check_deallocate_null<__gnu_cxx::throw_allocator_random<int> >
()
    at /home/test/src/gcc/libstdc++-v3/testsuite/util/testsuite_allocator.h:255
#11 main () at
/home/test/src/gcc/libstdc++-v3/testsuite/ext/throw_allocator/check_deallocate_null.cc:30

Frame #2 references 0x7fffffffe8f8, which is part of the stack. Frame #5 is
also referencing an object in the stack.
After these functions return, these objects shouldn't be used anymore.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Bug libstdc++/109889] [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026
  2023-05-17 11:10 [Bug libstdc++/109889] New: [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026 redi at gcc dot gnu.org
                   ` (4 preceding siblings ...)
  2023-05-17 15:04 ` tuliom at ascii dot art.br
@ 2023-05-17 15:10 ` tuliom at ascii dot art.br
  2023-05-17 15:50 ` redi at gcc dot gnu.org
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: tuliom at ascii dot art.br @ 2023-05-17 15:10 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109889

--- Comment #6 from Tulio Magno Quites Machado Filho <tuliom at ascii dot art.br> ---
Let me elaborate my previous comment...
When initializing the object at 0x100414c8, one of its members points to an
address in the stack (0x7fffffffe8f8).
All these functions return and when __run_exit_handlers() is called, the
address 0x7fffffffe8f8 is used to save the TOC pointer (r2) before calling the
destructors of the library.
The destructors manipulate the object at 0x100414c8, zeroing all its members,
including the address where the TOC pointer was saved.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Bug libstdc++/109889] [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026
  2023-05-17 11:10 [Bug libstdc++/109889] New: [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026 redi at gcc dot gnu.org
                   ` (5 preceding siblings ...)
  2023-05-17 15:10 ` tuliom at ascii dot art.br
@ 2023-05-17 15:50 ` redi at gcc dot gnu.org
  2023-05-17 15:57 ` redi at gcc dot gnu.org
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: redi at gcc dot gnu.org @ 2023-05-17 15:50 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109889

--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> ---
When the function returns the iterator's destructor should detach itself from
the sequence's list of iterators, so that it doesn't outlive the stack frame
containing the iterator.

The commit that caused the regression included this change:

        _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
                              _M_message(__msg_bad_inc)
                              ._M_iterator(*this, "this"));
-       _Safe_iterator __ret = *this;
+       _Safe_iterator __ret(*this, _Unchecked());
        ++*this;
        return __ret;
       }

Maybe this affects how/when the __ret object gets destroyed, so it fails to
detach itself.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Bug libstdc++/109889] [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026
  2023-05-17 11:10 [Bug libstdc++/109889] New: [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026 redi at gcc dot gnu.org
                   ` (6 preceding siblings ...)
  2023-05-17 15:50 ` redi at gcc dot gnu.org
@ 2023-05-17 15:57 ` redi at gcc dot gnu.org
  2023-05-17 15:58 ` redi at gcc dot gnu.org
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: redi at gcc dot gnu.org @ 2023-05-17 15:57 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109889

--- Comment #8 from Jonathan Wakely <redi at gcc dot gnu.org> ---
With -std=c++14 there's no crash, with -std=c++17, so that confirms it's
something related to copy elision.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Bug libstdc++/109889] [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026
  2023-05-17 11:10 [Bug libstdc++/109889] New: [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026 redi at gcc dot gnu.org
                   ` (7 preceding siblings ...)
  2023-05-17 15:57 ` redi at gcc dot gnu.org
@ 2023-05-17 15:58 ` redi at gcc dot gnu.org
  2023-05-17 15:59 ` redi at gcc dot gnu.org
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: redi at gcc dot gnu.org @ 2023-05-17 15:58 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109889

--- Comment #9 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Jonathan Wakely from comment #8)
> With -std=c++14 there's no crash, with -std=c++17,

Should have said "only with -std=c++17" (and later, of course).

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Bug libstdc++/109889] [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026
  2023-05-17 11:10 [Bug libstdc++/109889] New: [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026 redi at gcc dot gnu.org
                   ` (8 preceding siblings ...)
  2023-05-17 15:58 ` redi at gcc dot gnu.org
@ 2023-05-17 15:59 ` redi at gcc dot gnu.org
  2023-05-17 19:38 ` rguenth at gcc dot gnu.org
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: redi at gcc dot gnu.org @ 2023-05-17 15:59 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109889

--- Comment #10 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Jonathan Wakely from comment #9)
> Should have said "only with -std=c++17" (and later, of course).

Actually, that's wrong, *only* with C++17, not earlier *or* later.

So the further changes to elision rules after C++17 changed the behaviour
again.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Bug libstdc++/109889] [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026
  2023-05-17 11:10 [Bug libstdc++/109889] New: [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026 redi at gcc dot gnu.org
                   ` (9 preceding siblings ...)
  2023-05-17 15:59 ` redi at gcc dot gnu.org
@ 2023-05-17 19:38 ` rguenth at gcc dot gnu.org
  2023-05-19 12:49 ` redi at gcc dot gnu.org
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: rguenth at gcc dot gnu.org @ 2023-05-17 19:38 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109889

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P3                          |P2
   Target Milestone|---                         |13.2

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Bug libstdc++/109889] [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026
  2023-05-17 11:10 [Bug libstdc++/109889] New: [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026 redi at gcc dot gnu.org
                   ` (10 preceding siblings ...)
  2023-05-17 19:38 ` rguenth at gcc dot gnu.org
@ 2023-05-19 12:49 ` redi at gcc dot gnu.org
  2023-05-24 12:04 ` redi at gcc dot gnu.org
  2023-07-27  9:26 ` rguenth at gcc dot gnu.org
  13 siblings, 0 replies; 15+ messages in thread
From: redi at gcc dot gnu.org @ 2023-05-19 12:49 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109889

--- Comment #11 from Jonathan Wakely <redi at gcc dot gnu.org> ---
The test looks like this:

#include <ext/throw_allocator.h>
#include <testsuite_allocator.h>

int main()
{ 
  typedef int value_type;
  typedef __gnu_cxx::throw_allocator_random<value_type> allocator_type;

  try { __gnu_test::check_deallocate_null<allocator_type>(); }
  catch (std::logic_error&)
    {
      // Should throw logic_error to catch null erase.
    }

  return 0;
}


Where check_deallocate_null does:

  template<typename Alloc>
    bool
    check_deallocate_null()
    {
      // Let's not core here...
      Alloc a;
      a.deallocate(0, 1);
      a.deallocate(0, 10);
      return true;
    }


The first call to deallocate results in a call to:

    // See if a particular address and allocation size has been saved.
    inline map_alloc_type::iterator
    check_allocated(void* p, size_t size)
    {
      map_alloc_type::iterator found = map_alloc().find(p);
      if (found == map_alloc().end())
        {
          std::string error("annotate_base::check_allocated by value "
                            "null erase!\n");
          log_to_string(error, make_entry(p, size));
          std::__throw_logic_error(error.c_str());
        }


This creates a debug mode iterator (found) and attaches it to the list of
iterators for the  static map created here:

    static map_alloc_type&
    map_alloc()
    {
      static map_alloc_type _S_map;
      return _S_map;
    }

The call to map_alloc().end() then creates a second iterator, which is attached
to the list, and then detached when it goes out of scope.

Then we throw an exception, which is caught in main() and we return from
main().

The first iterator, found, was not destroyed, and so was not detached from the
list of active iterators. When the map gets destroyed it detaches the iterator
and calls its _M_reset() member to note that the iterator is now invalid
(because the map it refers to no logner exists). But that iterator only existed
on the stack of check_allocated, and calling _M_reset() on that stack address
corrupts the stack.

The found iterator should have been destroyed when the exception was thrown and
the stack was unwound.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Bug libstdc++/109889] [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026
  2023-05-17 11:10 [Bug libstdc++/109889] New: [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026 redi at gcc dot gnu.org
                   ` (11 preceding siblings ...)
  2023-05-19 12:49 ` redi at gcc dot gnu.org
@ 2023-05-24 12:04 ` redi at gcc dot gnu.org
  2023-07-27  9:26 ` rguenth at gcc dot gnu.org
  13 siblings, 0 replies; 15+ messages in thread
From: redi at gcc dot gnu.org @ 2023-05-24 12:04 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109889

--- Comment #12 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Jonathan Wakely from comment #0)
> I see this on power 9 fedora 37 (glibc-2.36) but not on power 8 centos 7.9
> (glibc-2.17).

Also seen on power 9 rhel 9 (glibc-2.34-60.el9.ppc64le)

Not reproduced on Fedora 38 (glibc-2.37-4.fc38.ppc64le) for power 8 or power 9.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Bug libstdc++/109889] [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026
  2023-05-17 11:10 [Bug libstdc++/109889] New: [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026 redi at gcc dot gnu.org
                   ` (12 preceding siblings ...)
  2023-05-24 12:04 ` redi at gcc dot gnu.org
@ 2023-07-27  9:26 ` rguenth at gcc dot gnu.org
  13 siblings, 0 replies; 15+ messages in thread
From: rguenth at gcc dot gnu.org @ 2023-07-27  9:26 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109889

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Target Milestone|13.2                        |13.3

--- Comment #13 from Richard Biener <rguenth at gcc dot gnu.org> ---
GCC 13.2 is being released, retargeting bugs to GCC 13.3.

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2023-07-27  9:26 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-17 11:10 [Bug libstdc++/109889] New: [13/14 Regression] Segfault in __run_exit_handlers since r13-5309-gc3c6c307792026 redi at gcc dot gnu.org
2023-05-17 11:17 ` [Bug libstdc++/109889] " redi at gcc dot gnu.org
2023-05-17 11:25 ` jakub at gcc dot gnu.org
2023-05-17 11:26 ` redi at gcc dot gnu.org
2023-05-17 11:30 ` redi at gcc dot gnu.org
2023-05-17 15:04 ` tuliom at ascii dot art.br
2023-05-17 15:10 ` tuliom at ascii dot art.br
2023-05-17 15:50 ` redi at gcc dot gnu.org
2023-05-17 15:57 ` redi at gcc dot gnu.org
2023-05-17 15:58 ` redi at gcc dot gnu.org
2023-05-17 15:59 ` redi at gcc dot gnu.org
2023-05-17 19:38 ` rguenth at gcc dot gnu.org
2023-05-19 12:49 ` redi at gcc dot gnu.org
2023-05-24 12:04 ` redi at gcc dot gnu.org
2023-07-27  9:26 ` rguenth at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).