On 05/07/17 20:00 +0100, Jonathan Wakely wrote:
We can probably do similar annotations for std::deque, so that partially filled pages are annotated. I also have a patch for shared_ptr so that objects created by make_shared can be marked as invalid after they're destroyed.
This is the make_shared annotation patch. This allows ASan to give an error for: auto p = std::make_shared<int>(); std::weak_ptr<int> w = p; int* pi = p.get(); p = nullptr; return *pi; The error isn't ideal, because ASan thinks we're using a container, because that's what the annotations are intended for: ==4525==ERROR: AddressSanitizer: container-overflow
commit d0478d9fbd17b9e9d165b4893f784ae897531713 Author: Jonathan Wakely <jwak...@redhat.com> Date: Tue Jun 27 13:31:12 2017 +0100 Add AddressSanitizer annotations to std::make_shared * include/bits/shared_ptr_base.h [_GLIBCXX_SANITIZE_STD_ALLOCATOR] (__asan_annotate): Add. (_Sp_counted_ptr_inplace::_M_dispose): Call __asan_annotate. diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index 7e6766b..a720018 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -57,6 +57,12 @@ #include <bits/stl_function.h> #include <ext/aligned_buffer.h> +#if _GLIBCXX_SANITIZE_STD_ALLOCATOR +extern "C" void +__sanitizer_annotate_contiguous_container(const void*, const void*, + const void*, const void*); +#endif + namespace std _GLIBCXX_VISIBILITY(default) { #if !__cpp_rtti @@ -522,6 +528,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif }; +#if _GLIBCXX_SANITIZE_STD_ALLOCATOR + template<typename _Tp> + inline void + __asan_annotate(const void* __beg, const void* __mid, const void* __end, + const allocator<_Tp>&) + { __sanitizer_annotate_contiguous_container(__beg, __end, __end, __mid); } + + template<typename _Alloc> + inline void + __asan_annotate(const void*, const void*, const void*, const _Alloc&) + { } +#endif + template<typename _Tp, typename _Alloc, _Lock_policy _Lp> class _Sp_counted_ptr_inplace final : public _Sp_counted_base<_Lp> { @@ -556,6 +575,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_dispose() noexcept { allocator_traits<_Alloc>::destroy(_M_impl._M_alloc(), _M_ptr()); +#if _GLIBCXX_SANITIZE_STD_ALLOCATOR + __asan_annotate(this, &_M_impl._M_storage, this + 1, _M_impl._M_alloc()); +#endif } // Override because the allocator needs to know the dynamic type