public inbox for gcc-bugs@sourceware.org help / color / mirror / Atom feed
* [Bug libstdc++/94540] New: stack overflow populating std::vector<very large type> @ 2020-04-09 13:03 redi at gcc dot gnu.org 2020-04-09 14:58 ` [Bug libstdc++/94540] " redi at gcc dot gnu.org ` (4 more replies) 0 siblings, 5 replies; 6+ messages in thread From: redi at gcc dot gnu.org @ 2020-04-09 13:03 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94540 Bug ID: 94540 Summary: stack overflow populating std::vector<very large type> Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: redi at gcc dot gnu.org Target Milestone: --- #include <vector> struct yooj_type { char data[20*1024*1024]; }; int main() { std::vector<yooj_type> v(1); } This dies with SIGSEGV due to a stack overflow, because a yooj_type temporary is created on the stack in <bits/stl_uninitialized.h>: template<> struct __uninitialized_default_1<true> { template<typename _ForwardIterator> static void __uninit_default(_ForwardIterator __first, _ForwardIterator __last) { typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; std::fill(__first, __last, _ValueType()); } }; We should either avoid using std::fill for large objects (for some arbitrary meaning of large) or we should construct the first object in place and then use that as the fill argument: --- a/libstdc++-v3/include/bits/stl_uninitialized.h +++ b/libstdc++-v3/include/bits/stl_uninitialized.h @@ -549,7 +549,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; - std::fill(__first, __last, _ValueType()); + if (__first == __last) + return; + + const _ValueType& __val + = *std::_Construct(std::__addressof(*__first)); + if (++__first != __last) + std::fill(__first, __last, __val); } }; @@ -585,7 +591,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; - return std::fill_n(__first, __n, _ValueType()); + if (__size_to_integer(__n) <= 0) + return __first; + + const _ValueType& __val + = *std::_Construct(std::__addressof(*__first)); + return std::fill_n(++__first, __size_to_integer(__n) - 1, __val); } }; I'm concerned this will confuse the optimisers, but haven't checked yet. ^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug libstdc++/94540] stack overflow populating std::vector<very large type> 2020-04-09 13:03 [Bug libstdc++/94540] New: stack overflow populating std::vector<very large type> redi at gcc dot gnu.org @ 2020-04-09 14:58 ` redi at gcc dot gnu.org 2020-06-17 21:50 ` cvs-commit at gcc dot gnu.org ` (3 subsequent siblings) 4 siblings, 0 replies; 6+ messages in thread From: redi at gcc dot gnu.org @ 2020-04-09 14:58 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94540 Jonathan Wakely <redi at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Last reconfirmed| |2020-04-09 Status|UNCONFIRMED |ASSIGNED Ever confirmed|0 |1 Assignee|unassigned at gcc dot gnu.org |redi at gcc dot gnu.org ^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug libstdc++/94540] stack overflow populating std::vector<very large type> 2020-04-09 13:03 [Bug libstdc++/94540] New: stack overflow populating std::vector<very large type> redi at gcc dot gnu.org 2020-04-09 14:58 ` [Bug libstdc++/94540] " redi at gcc dot gnu.org @ 2020-06-17 21:50 ` cvs-commit at gcc dot gnu.org 2020-06-17 21:52 ` redi at gcc dot gnu.org ` (2 subsequent siblings) 4 siblings, 0 replies; 6+ messages in thread From: cvs-commit at gcc dot gnu.org @ 2020-06-17 21:50 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94540 --- Comment #1 from CVS Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>: https://gcc.gnu.org/g:632183ddcc8f3aead8b4fc63c4ab59a42ef9ad00 commit r11-1464-g632183ddcc8f3aead8b4fc63c4ab59a42ef9ad00 Author: Jonathan Wakely <jwakely@redhat.com> Date: Wed Jun 17 22:49:06 2020 +0100 libstdc++: Avoid stack overflow in std::vector (PR 94540) The std::__uninitialized_default_n algorithm used by std::vector creates an initial object as a local variable then copies that into the destination range. If the object is too large for the stack this crashes. We should create the first object directly into the destination and then copy it from there. This doesn't fix the bug for C++98, because in that case the initial value is created as a default argument of the vector constructor i.e. in the user's code, not inside libstdc++. We can't prevent that. PR libstdc++/94540 * include/bits/stl_uninitialized.h (__uninitialized_default_1<true>): Construct the first value at *__first instead of on the stack. (__uninitialized_default_n_1<true>): Likewise. Improve comments on several of the non-standard algorithms. * testsuite/20_util/specialized_algorithms/uninitialized_default/94540.cc: New test. * testsuite/20_util/specialized_algorithms/uninitialized_default_n/94540.cc: New test. * testsuite/20_util/specialized_algorithms/uninitialized_value_construct/94540.cc: New test. * testsuite/20_util/specialized_algorithms/uninitialized_value_construct_n/94540.cc: New test. * testsuite/23_containers/vector/cons/94540.cc: New test. ^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug libstdc++/94540] stack overflow populating std::vector<very large type> 2020-04-09 13:03 [Bug libstdc++/94540] New: stack overflow populating std::vector<very large type> redi at gcc dot gnu.org 2020-04-09 14:58 ` [Bug libstdc++/94540] " redi at gcc dot gnu.org 2020-06-17 21:50 ` cvs-commit at gcc dot gnu.org @ 2020-06-17 21:52 ` redi at gcc dot gnu.org 2023-06-23 16:13 ` cvs-commit at gcc dot gnu.org 2023-06-23 16:19 ` redi at gcc dot gnu.org 4 siblings, 0 replies; 6+ messages in thread From: redi at gcc dot gnu.org @ 2020-06-17 21:52 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94540 Jonathan Wakely <redi at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Resolution|--- |FIXED Status|ASSIGNED |RESOLVED Target Milestone|--- |11.0 --- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> --- Fixed in master. ^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug libstdc++/94540] stack overflow populating std::vector<very large type> 2020-04-09 13:03 [Bug libstdc++/94540] New: stack overflow populating std::vector<very large type> redi at gcc dot gnu.org ` (2 preceding siblings ...) 2020-06-17 21:52 ` redi at gcc dot gnu.org @ 2023-06-23 16:13 ` cvs-commit at gcc dot gnu.org 2023-06-23 16:19 ` redi at gcc dot gnu.org 4 siblings, 0 replies; 6+ messages in thread From: cvs-commit at gcc dot gnu.org @ 2023-06-23 16:13 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94540 --- Comment #3 from CVS Commits <cvs-commit at gcc dot gnu.org> --- The releases/gcc-10 branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>: https://gcc.gnu.org/g:7dba69b5e9977408921c635681a0daa34b813e16 commit r10-11468-g7dba69b5e9977408921c635681a0daa34b813e16 Author: Jonathan Wakely <jwakely@redhat.com> Date: Wed Jun 17 22:49:06 2020 +0100 libstdc++: Avoid stack overflow in std::vector (PR 94540) The std::__uninitialized_default_n algorithm used by std::vector creates an initial object as a local variable then copies that into the destination range. If the object is too large for the stack this crashes. We should create the first object directly into the destination and then copy it from there. This doesn't fix the bug for C++98, because in that case the initial value is created as a default argument of the vector constructor i.e. in the user's code, not inside libstdc++. We can't prevent that. PR libstdc++/94540 * include/bits/stl_uninitialized.h (__uninitialized_default_1<true>): Construct the first value at *__first instead of on the stack. (__uninitialized_default_n_1<true>): Likewise. Improve comments on several of the non-standard algorithms. * testsuite/20_util/specialized_algorithms/uninitialized_default/94540.cc: New test. * testsuite/20_util/specialized_algorithms/uninitialized_default_n/94540.cc: New test. * testsuite/20_util/specialized_algorithms/uninitialized_value_construct/94540.cc: New test. * testsuite/20_util/specialized_algorithms/uninitialized_value_construct_n/94540.cc: New test. * testsuite/23_containers/vector/cons/94540.cc: New test. (cherry picked from commit 632183ddcc8f3aead8b4fc63c4ab59a42ef9ad00) ^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug libstdc++/94540] stack overflow populating std::vector<very large type> 2020-04-09 13:03 [Bug libstdc++/94540] New: stack overflow populating std::vector<very large type> redi at gcc dot gnu.org ` (3 preceding siblings ...) 2023-06-23 16:13 ` cvs-commit at gcc dot gnu.org @ 2023-06-23 16:19 ` redi at gcc dot gnu.org 4 siblings, 0 replies; 6+ messages in thread From: redi at gcc dot gnu.org @ 2023-06-23 16:19 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94540 Jonathan Wakely <redi at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Target Milestone|11.0 |10.5 --- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> --- Backported for 10.5 too. ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2023-06-23 16:19 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-04-09 13:03 [Bug libstdc++/94540] New: stack overflow populating std::vector<very large type> redi at gcc dot gnu.org 2020-04-09 14:58 ` [Bug libstdc++/94540] " redi at gcc dot gnu.org 2020-06-17 21:50 ` cvs-commit at gcc dot gnu.org 2020-06-17 21:52 ` redi at gcc dot gnu.org 2023-06-23 16:13 ` cvs-commit at gcc dot gnu.org 2023-06-23 16:19 ` redi 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).