File tree Expand file tree Collapse file tree
test/threads/thread/constr Expand file tree Collapse file tree Original file line number Diff line number Diff line change 2626#include < boost/config.hpp>
2727
2828unsigned throw_one = 0xFFFF ;
29+ unsigned operator_new_recursion_level = 0u ;
30+
31+ struct operator_new_recursion_counter
32+ {
33+ operator_new_recursion_counter () BOOST_NOEXCEPT_OR_NOTHROW
34+ {
35+ ++operator_new_recursion_level;
36+ }
37+ ~operator_new_recursion_counter () BOOST_NOEXCEPT_OR_NOTHROW
38+ {
39+ --operator_new_recursion_level;
40+ }
41+ };
2942
3043#if defined _GLIBCXX_THROW
3144void * operator new (std::size_t s) _GLIBCXX_THROW (std::bad_alloc)
@@ -34,10 +47,22 @@ void* operator new(std::size_t s)
3447#endif
3548{
3649 // std::cout << __FILE__ << ":" << __LINE__ << std::endl;
37- if (throw_one == 0 ) throw std::bad_alloc ();
38- --throw_one;
50+ // Throwing an exception may recursively call operator new. If we're throwing std::bad_alloc,
51+ // this may cause infinite recursion and a crash. So only throw if we're at the top recursion level.
52+ operator_new_recursion_counter auto_counter;
53+ if (operator_new_recursion_level == 1u )
54+ {
55+ if (throw_one == 0 ) throw std::bad_alloc ();
56+ --throw_one;
57+ }
3958 void * p = std::malloc (s);
40- if (!p) throw std::bad_alloc ();
59+ if (!p)
60+ {
61+ if (operator_new_recursion_level == 1u )
62+ throw std::bad_alloc ();
63+ else
64+ std::abort ();
65+ }
4166 return p;
4267}
4368
Original file line number Diff line number Diff line change 2626#include < boost/config.hpp>
2727
2828unsigned throw_one = 0xFFFF ;
29+ unsigned operator_new_recursion_level = 0u ;
30+
31+ struct operator_new_recursion_counter
32+ {
33+ operator_new_recursion_counter () BOOST_NOEXCEPT_OR_NOTHROW
34+ {
35+ ++operator_new_recursion_level;
36+ }
37+ ~operator_new_recursion_counter () BOOST_NOEXCEPT_OR_NOTHROW
38+ {
39+ --operator_new_recursion_level;
40+ }
41+ };
2942
3043#if defined _GLIBCXX_THROW
3144void * operator new (std::size_t s) _GLIBCXX_THROW (std::bad_alloc)
@@ -34,10 +47,22 @@ void* operator new(std::size_t s)
3447#endif
3548{
3649 // std::cout << __FILE__ << ":" << __LINE__ << std::endl;
37- if (throw_one == 0 ) throw std::bad_alloc ();
38- --throw_one;
50+ // Throwing an exception may recursively call operator new. If we're throwing std::bad_alloc,
51+ // this may cause infinite recursion and a crash. So only throw if we're at the top recursion level.
52+ operator_new_recursion_counter auto_counter;
53+ if (operator_new_recursion_level == 1u )
54+ {
55+ if (throw_one == 0 ) throw std::bad_alloc ();
56+ --throw_one;
57+ }
3958 void * p = std::malloc (s);
40- if (!p) throw std::bad_alloc ();
59+ if (!p)
60+ {
61+ if (operator_new_recursion_level == 1u )
62+ throw std::bad_alloc ();
63+ else
64+ std::abort ();
65+ }
4166 return p;
4267}
4368
Original file line number Diff line number Diff line change 2828#if ! defined BOOST_NO_CXX11_LAMBDAS
2929
3030unsigned throw_one = 0xFFFF ;
31+ unsigned operator_new_recursion_level = 0u ;
32+
33+ struct operator_new_recursion_counter
34+ {
35+ operator_new_recursion_counter () BOOST_NOEXCEPT_OR_NOTHROW
36+ {
37+ ++operator_new_recursion_level;
38+ }
39+ ~operator_new_recursion_counter () BOOST_NOEXCEPT_OR_NOTHROW
40+ {
41+ --operator_new_recursion_level;
42+ }
43+ };
3144
3245#if defined _GLIBCXX_THROW
3346void * operator new (std::size_t s) _GLIBCXX_THROW (std::bad_alloc)
3447#else
3548void * operator new (std::size_t s)
3649#endif
3750{
38- if (throw_one == 0 ) throw std::bad_alloc ();
39- --throw_one;
51+ // Throwing an exception may recursively call operator new. If we're throwing std::bad_alloc,
52+ // this may cause infinite recursion and a crash. So only throw if we're at the top recursion level.
53+ operator_new_recursion_counter auto_counter;
54+ if (operator_new_recursion_level == 1u )
55+ {
56+ if (throw_one == 0 ) throw std::bad_alloc ();
57+ --throw_one;
58+ }
4059 void * p = std::malloc (s);
41- if (!p) throw std::bad_alloc ();
60+ if (!p)
61+ {
62+ if (operator_new_recursion_level == 1u )
63+ throw std::bad_alloc ();
64+ else
65+ std::abort ();
66+ }
4267 return p;
4368}
4469
You can’t perform that action at this time.
0 commit comments