Users sometimes complain that asan's operator new is not fully standard-compliant
when it comes to handling out of memory situation.
In particular:
- new-nothrow does not return 0 by default (it does with ASAN_OPTIONS=allocator_may_return_null=1)
- new does not throw std::bad_alloc
- either variant does not call new_handler
Implementing these features appears to be surprisingly difficult.
The implementation of asan's operator new resides in asan/asan_new_delete.cc
http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_new_delete.cc?view=markup
asan's new/delete is essentially a user replacement of these operators.
This has a side effect: a user can not replace new/delete with his own variants,
(this is undefined behavior: http://en.cppreference.com/w/cpp/memory/new/operator_new)
Throwing exceptions from asan/asan_new_delete.cc is currently not possible because
we build the entire run-time w/o exceptions.
We can overcome this by having special flags for asan/asan_new_delete.cc.
Then there is a problem of linking with c++ lib.
asan run-time does not depend on c++ run-time and can be used with pure C w/o linking
c++.
We probably may overcome this my splitting asan_new_delete.cc into a separate library
asan-rt-cxx that will be linked in asan mode only for C++ programs.
Calling new_handler from asan's operator new would be possible in c++11, where
std::get_new_handler() is present, but we can't rely on this yet
(libstdc++ in gcc 4.8.2 does not have std::get_new_handler).
And again, the same problem with linking with c++ lib.
We can also simply remove our new/delete interceptors.
This will route new/delete to the standard c++ library and will solve the problem completely
(assuming new/delete call malloc/free),
but we will lose the ability to detect new/free and new[]/delete mismatch bugs.
So, the possible plan is:
- split asan run-time, moving asan/asan_new_delete.cc into a separate library and link
it only when libstdc++/libc++ is linked.
- make our operator new() throw bad_alloc
- declare std::get_new_handler() as weak and if it is present, handle the new_handler
case.
OMG, that sounds so hard, and for very little outcome.
I am tempted to leave it as is unless we find an easier route.
Better implementation ideas are welcome.
Originally reported on Google Code with ID 295
Reported by
konstantin.s.serebryanyon 2014-04-15 12:00:10