diff options
author | Alex Shlyapnikov <alekseys@google.com> | 2017-06-28 21:58:57 +0000 |
---|---|---|
committer | Alex Shlyapnikov <alekseys@google.com> | 2017-06-28 21:58:57 +0000 |
commit | 7ea9c79f1e0f9c588e61a638e5354a45b239876c (patch) | |
tree | 6ba2d9f476a34b347519d46264de9b70c639cc7c /lib/tsan/rtl/tsan_new_delete.cc | |
parent | 59b78d964b68f9e8c4fe540e759ead35dc35e240 (diff) |
[Sanitizers] Operator new() interceptors always die on allocation error
Summary:
Operator new interceptors behavior is now controlled by their nothrow
property as well as by allocator_may_return_null flag value:
- allocator_may_return_null=* + new() - die on allocation error
- allocator_may_return_null=0 + new(nothrow) - die on allocation error
- allocator_may_return_null=1 + new(nothrow) - return null
Ideally new() should throw std::bad_alloc exception, but that is not
trivial to achieve, hence TODO.
Reviewers: eugenis
Subscribers: kubamracek, llvm-commits
Differential Revision: https://reviews.llvm.org/D34731
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@306604 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/tsan/rtl/tsan_new_delete.cc')
-rw-r--r-- | lib/tsan/rtl/tsan_new_delete.cc | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/lib/tsan/rtl/tsan_new_delete.cc b/lib/tsan/rtl/tsan_new_delete.cc index b6478bb08..4d03145c1 100644 --- a/lib/tsan/rtl/tsan_new_delete.cc +++ b/lib/tsan/rtl/tsan_new_delete.cc @@ -12,6 +12,7 @@ // Interceptors for operators new and delete. //===----------------------------------------------------------------------===// #include "interception/interception.h" +#include "sanitizer_common/sanitizer_allocator.h" #include "sanitizer_common/sanitizer_internal_defs.h" #include "tsan_interceptors.h" @@ -24,13 +25,15 @@ struct nothrow_t {}; DECLARE_REAL(void *, malloc, uptr size) DECLARE_REAL(void, free, void *ptr) -#define OPERATOR_NEW_BODY(mangled_name) \ +// TODO(alekseys): throw std::bad_alloc instead of dying on OOM. +#define OPERATOR_NEW_BODY(mangled_name, nothrow) \ if (cur_thread()->in_symbolizer) \ return InternalAlloc(size); \ void *p = 0; \ { \ SCOPED_INTERCEPTOR_RAW(mangled_name, size); \ p = user_alloc(thr, pc, size); \ + if (!nothrow && UNLIKELY(!p)) DieOnFailure::OnOOM(); \ } \ invoke_malloc_hook(p, size); \ return p; @@ -38,25 +41,25 @@ DECLARE_REAL(void, free, void *ptr) SANITIZER_INTERFACE_ATTRIBUTE void *operator new(__sanitizer::uptr size); void *operator new(__sanitizer::uptr size) { - OPERATOR_NEW_BODY(_Znwm); + OPERATOR_NEW_BODY(_Znwm, false /*nothrow*/); } SANITIZER_INTERFACE_ATTRIBUTE void *operator new[](__sanitizer::uptr size); void *operator new[](__sanitizer::uptr size) { - OPERATOR_NEW_BODY(_Znam); + OPERATOR_NEW_BODY(_Znam, false /*nothrow*/); } SANITIZER_INTERFACE_ATTRIBUTE void *operator new(__sanitizer::uptr size, std::nothrow_t const&); void *operator new(__sanitizer::uptr size, std::nothrow_t const&) { - OPERATOR_NEW_BODY(_ZnwmRKSt9nothrow_t); + OPERATOR_NEW_BODY(_ZnwmRKSt9nothrow_t, true /*nothrow*/); } SANITIZER_INTERFACE_ATTRIBUTE void *operator new[](__sanitizer::uptr size, std::nothrow_t const&); void *operator new[](__sanitizer::uptr size, std::nothrow_t const&) { - OPERATOR_NEW_BODY(_ZnamRKSt9nothrow_t); + OPERATOR_NEW_BODY(_ZnamRKSt9nothrow_t, true /*nothrow*/); } #define OPERATOR_DELETE_BODY(mangled_name) \ |