Bug 30780

Summary: gdb: -Werror=stringop-overflow build failure with -D_GLIBCXX_ASSERTIONS
Product: gdb Reporter: Sam James <sam>
Component: buildAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED MOVED    
Severity: normal CC: arsen, tromey
Priority: P2    
Version: HEAD   
Target Milestone: ---   
See Also: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111073
Host: Target:
Build: Last reconfirmed:

Description Sam James 2023-08-18 10:00:10 UTC
```
$ gcc --version
gcc (Gentoo Hardened 13.2.1_p20230812 p7) 13.2.1 20230812
Copyright (C) 2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
```

```
make[2]: Entering directory '/home/sam/git/binutils-gdb/gdb'
g++ -x c++    -I. -I. -I./config -DLOCALEDIR="\"/usr/local/share/locale\"" -DHAVE_CONFIG_H -I./../include/opcode -I../bfd -I./../bfd -I./../include -I./../readline/readline/.. -I./../zlib  -I../libdecnumber -I./../libdecnumber  -I./../gnulib/import -I../gnulib/import -I./.. -I.. -I./../libbacktrace/ -I../libbacktrace/ -DTUI=1    -I/usr/include/python3.12 -I/usr/include/python3.12   -I./.. -pthread    -Wall -Wpointer-arith -Wno-unused -Wunused-value -Wunused-variable -Wunused-function -Wno-switch -Wno-char-subscripts -Wempty-body -Wunused-but-set-parameter -Wunused-but-set-variable -Wno-sign-compare -Wno-error=maybe-uninitialized -Wno-mismatched-tags -Wsuggest-override -Wimplicit-fallthrough=3 -Wduplicated-cond -Wshadow=local -Wdeprecated-copy -Wdeprecated-copy-dtor -Wredundant-move -Wmissing-declarations -Wstrict-null-sentinel -Wformat -Wformat-nonliteral -Werror -g -O2     -c -o infcall.o -MT infcall.o -MMD -MP -MF ./.deps/infcall.Tpo infcall.c
In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/hashtable_policy.h:36,
                 from /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/hashtable.h:35,
                 from /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/unordered_map.h:33,
                 from /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/unordered_map:41,
                 from /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/functional:63,
                 from ./../gdbsupport/ptid.h:35,
                 from ./../gdbsupport/common-defs.h:206,
                 from defs.h:26,
                 from infcall.c:20:
In static member function ‘static _Up* std::__copy_move<_IsMove, true, std::random_access_iterator_tag>::__copy_m(_Tp*, _Tp*, _Up*) [with _Tp = value*; _Up = value*; bool _IsMove = false]’,
    inlined from ‘_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false; _II = value**; _OI = value**]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/stl_algobase.h:506:30,
    inlined from ‘_OI std::__copy_move_a1(_II, _II, _OI) [with bool _IsMove = false; _II = value**; _OI = value**]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/stl_algobase.h:533:42,
    inlined from ‘_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false; _II = value**; _OI = value**]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/stl_algobase.h:540:31,
    inlined from ‘_OI std::copy(_II, _II, _OI) [with _II = value**; _OI = value**]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/stl_algobase.h:633:7,
    inlined from ‘static _ForwardIterator std::__uninitialized_copy<true>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = value**; _ForwardIterator = value**]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/stl_uninitialized.h:147:27,
    inlined from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = value**; _ForwardIterator = value**]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/stl_uninitialized.h:185:15,
    inlined from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, allocator<_Tp>&) [with _InputIterator = value**; _ForwardIterator = value**; _Tp = value*]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/stl_uninitialized.h:373:37,
    inlined from ‘void std::vector<_Tp, _Alloc>::_M_range_insert(iterator, _ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with _ForwardIterator = value**; _Tp = value*; _Alloc = std::allocator<value*>]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/vector.tcc:814:38,
    inlined from ‘std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::insert(const_iterator, _InputIterator, _InputIterator) [with _InputIterator = value**; <template-parameter-2-2> = void; _Tp = value*; _Alloc = std::allocator<value*>]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/stl_vector.h:1483:19,
    inlined from ‘value* call_function_by_hand_dummy(value*, type*, gdb::array_view<value*>, void (*)(void*, int), void*)’ at infcall.c:1239:23:
/usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/stl_algobase.h:437:30: error: ‘void* __builtin_memmove(void*, const void*, long unsigned int)’ writing between 9 and 9223372036854775800 bytes into a region of size 0 overflows the destination [-Werror=stringop-overflow=]
  437 |             __builtin_memmove(__result, __first, sizeof(_Tp) * _Num);
      |             ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/x86_64-pc-linux-gnu/bits/c++allocator.h:33,
                 from /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/allocator.h:46,
                 from /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/alloc_traits.h:39,
                 from /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/ext/alloc_traits.h:34,
                 from /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/hashtable_policy.h:39:
In member function ‘_Tp* std::__new_allocator<_Tp>::allocate(size_type, const void*) [with _Tp = value*]’,
    inlined from ‘static _Tp* std::allocator_traits<std::allocator<_Tp1> >::allocate(allocator_type&, size_type) [with _Tp = value*]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/alloc_traits.h:482:28,
    inlined from ‘std::_Vector_base<_Tp, _Alloc>::pointer std::_Vector_base<_Tp, _Alloc>::_M_allocate(std::size_t) [with _Tp = value*; _Alloc = std::allocator<value*>]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/stl_vector.h:378:33,
    inlined from ‘std::_Vector_base<_Tp, _Alloc>::pointer std::_Vector_base<_Tp, _Alloc>::_M_allocate(std::size_t) [with _Tp = value*; _Alloc = std::allocator<value*>]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/stl_vector.h:375:7,
    inlined from ‘void std::vector<_Tp, _Alloc>::_M_range_insert(iterator, _ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with _ForwardIterator = value**; _Tp = value*; _Alloc = std::allocator<value*>]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/vector.tcc:805:40,
    inlined from ‘std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::insert(const_iterator, _InputIterator, _InputIterator) [with _InputIterator = value**; <template-parameter-2-2> = void; _Tp = value*; _Alloc = std::allocator<value*>]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/stl_vector.h:1483:19,
    inlined from ‘value* call_function_by_hand_dummy(value*, type*, gdb::array_view<value*>, void (*)(void*, int), void*)’ at infcall.c:1239:23:
/usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/new_allocator.h:147:55: note: at offset [-9223372036854775808, -1] into destination object of size [8, 9223372036854775800] allocated by ‘operator new’
  147 |         return static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__n * sizeof(_Tp)));
      |                                                       ^
cc1plus: all warnings being treated as errors
make[2]: *** [Makefile:1924: infcall.o] Error 1
make[2]: Leaving directory '/home/sam/git/binutils-gdb/gdb'
make[1]: *** [Makefile:13766: all-gdb] Error 2
make[1]: Leaving directory '/home/sam/git/binutils-gdb'
make: *** [Makefile:1021: all] Error 2
```
Comment 1 Arsen Arsenović 2023-08-18 10:10:36 UTC
this might be a gcc bug.  it resembles various other stringop-overflow bugs.  a good hint is that it happens inside stl_vector.h.  jonathan already (re)verified that the function in question is correct before the release of 13 (as we ran into this while testing libstdc++), at least IIRC
Comment 2 Tom Tromey 2023-08-18 13:46:36 UTC
(In reply to Arsen Arsenović from comment #1)
> this might be a gcc bug. 

    inlined from ‘value* call_function_by_hand_dummy(value*, type*, gdb::array_view<value*>, void (*)(void*, int), void*)’ at infcall.c:1239:23:

Looking at the code I see:

      /* Add the new argument to the front of the argument list.  */
      new_args.reserve (args.size ());
      new_args.push_back
	(value_from_pointer (lookup_pointer_type (values_type), struct_addr));
      new_args.insert (new_args.end (), args.begin (), args.end ());

To me this looks like an off-by-one in the reserve call.
At the same time, that should be irrelevant because insert
ought to grow the vector anyway.

So I tend to agree that it is a compiler problem.
Comment 3 Tom Tromey 2023-08-18 14:05:11 UTC
I sent a patch for the reserve thing.
Comment 4 Sourceware Commits 2023-08-18 19:07:26 UTC
The master branch has been updated by Tom Tromey <tromey@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=28bb48114db4de4ba0a72940af1c30728b6e82f2

commit 28bb48114db4de4ba0a72940af1c30728b6e82f2
Author: Tom Tromey <tromey@adacore.com>
Date:   Fri Aug 18 07:55:30 2023 -0600

    Fix off-by-one in call to vector::reserve
    
    While looking at a bug, I noticed what I think is an off-by-one
    mistake in a call to vector::reserve.  This code:
    
          new_args.reserve (args.size ());
          new_args.push_back
            (value_from_pointer (lookup_pointer_type (values_type), struct_addr));
          new_args.insert (new_args.end (), args.begin (), args.end ());
    
    ... reserves 'size()' entries, but then proceeds to push one extra
    one.
    
    This shouldn't have any really bad effects, as insert will grow the
    vector.  Still, it seems better to use the correct size if we're going
    to bother calling reserve.
    
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30780
    Reviewed-by: John Baldwin <jhb@FreeBSD.org>
Comment 5 Sam James 2023-08-19 06:49:45 UTC
Thank you both. Filed w/ gcc at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111073.
Comment 6 Tom Tromey 2023-08-28 13:49:56 UTC
I'm closing this as it is a compiler problem.