This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: [RFC] Exception-friendly ASan annotations of std::string
- From: Jonathan Wakely <jwakely at redhat dot com>
- To: Ivan Baravy <i dot baravy at samsung dot com>
- Cc: libstdc++ <libstdc++ at gcc dot gnu dot org>
- Date: Mon, 12 Jun 2017 11:11:35 +0100
- Subject: Re: [RFC] Exception-friendly ASan annotations of std::string
- Authentication-results: sourceware.org; auth=none
- Authentication-results: ext-mx02.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com
- Authentication-results: ext-mx02.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=jwakely at redhat dot com
- Dkim-filter: OpenDKIM Filter v2.11.0 mx1.redhat.com E94A78FCE5
- Dmarc-filter: OpenDMARC Filter v1.3.2 mx1.redhat.com E94A78FCE5
- References: <CGME20170609204341eucas1p11a3fb28ac002a94a72b0fc7e2745b7df@eucas1p1.samsung.com> <bff6958c-0646-e2cd-ab8a-fc7069f6fd35@samsung.com>
On 09/06/17 23:43 +0300, Ivan Baravy wrote:
Hello,
I'm working on address sanitization of standard containers. The aim is
to detect and report accesses between size and capacity. The issue I
faced is related to std::length_error and std::bad_alloc exceptions. I
can get std::bad_alloc via huge fill insert into std::string. ASan adds
a memory overhead (internal structures) to user allocations and, when
enabled, it intercepts memory-related functions, failed allocations of
vital structures make it terminate the process. Thus it looks like
pointless for ASan annotations to be friendly to std::length_error and
std::bad_alloc exceptions.
So my question is if it's acceptable to not consider std::length_error
and std::bad_alloc in address sanitization design?
I'm not sure if I understand the question, sorry.
ASan makes failed allocations call terminate, so you'll never get
std::bad_alloc from operator new, is that right?
But what does that have to do with std::length_error?
And you could still std::get bad_alloc from custom allocators, for
example the following throws std::bad_alloc without ever attempting to
allocate memory using operator new, or malloc:
#include <string>
#include <memory>
char buf[1024];
char* last = buf;
template<class T>
struct Alloc {
using value_type = T;
Alloc() { }
template<typename U> Alloc(const Alloc<U>&) { }
T* allocate(std::size_t n) {
void* p = last;
if (std::size_t(-1) / sizeof(T) > n)
throw std::bad_alloc();
n *= sizeof(T);
std::size_t space = 1024 - (last - buf);
if (!std::align(alignof(T), n, p, space))
throw std::bad_alloc();
last = (char*)p + n;
return (T*)p;
}
void deallocate(T* p, std::size_t n) {
n *= sizeof(T);
char* pc = (char*)p;
if (last == pc + n)
last = pc;
}
template<typename U> bool operator==(Alloc<U>) const { return true; }
template<typename U> bool operator!=(Alloc<U>) const { return false; }
};
int main()
{
std::basic_string<char, std::char_traits<char>, Alloc<char>> s(1025, 'a');
}