This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: [RFC] std::vector and std::string ASan annotations design
- From: Jonathan Wakely <jwakely at redhat dot com>
- To: Ivan Baravy <i dot baravy at samsung dot com>
- Cc: libstdc++ at gcc dot gnu dot org, "'Maksim Ostapenko'" <m dot ostapenko at samsung dot com>
- Date: Tue, 24 Jan 2017 18:03:19 +0000
- Subject: Re: [RFC] std::vector and std::string ASan annotations design
- Authentication-results: sourceware.org; auth=none
- References: <CGME20170124171405eucas1p2e0cac2c1cc388e57f403857cf79cd24f@eucas1p2.samsung.com> <a916c77a-342d-7121-871c-9b45f4060111@samsung.com>
On 24/01/17 20:14 +0300, Ivan Baravy wrote:
Hello,
libc++ has a feature of ASan annotations inside std::vector [1,2] and
std::string [3]. These make it possible to detect container overflows,
i.e. accesses between its size and capacity. I also noticed similar
approach to libstdc++ [4], unfinished though. I really like the idea
to have this feature in libstdc++ and I prepared patches providing the
annotations mostly based on libc++ code. However, while this
development I faced a design issue I want to discuss with you.
In libc++, all the string's API functions are defined in corresponding
header file. This allows ASan annotations to be placed there (and only
there) and thus not affect dso binary. In libstdc++, instead,
basic_string.h has both definitions and declarations of public API
functions. Therefore I had to put some ASan annotations into
basic_string.tcc file which becomes a part of libstdc++ binary.
basic_string.tcc is also a header file, which file the definitions are
in makes no difference, everything is defined in a header.
The difference from libc++ is that we decalre explicit instantiations
in the header file, at the end of <bits/basic_string.tcc>. Those
explicit instantiations are defined in the libstdc++ binary. Because
they are declared in the header the compile doesn't bother doing
explicit instantiations for most functions of basic_string, and links
to the instantiations in the binary.
As a result,
- Sanitized applications require sanitized libstdc++ to run, and vice
versa;
- Sanitized libstdc++ requires all applications and libraries using
std::string to be sanitized.
The only solution I see for now is to move definitions into
basic_string.h in libc++ manner. However this is not acceptable for
upstream, I assume, which is my aim. Could you suggest a better
solution or give me any pointers on the issue?
Have a look at how Debug Mode works for std::string.
If _GLIBCXX_EXTERN_TEMPLATE == -1 then the explicit instantiations
for std::string, std::wstring etc. wil not be declared, so the
compiler will implicitly instantiate the member functions in the user
code, so annotations in those functions will be used.
So the simplest solution is probably to edit include/bits/c++config so
that when __SANITIZE_ADDRESS__ is defined the _GLIBCXX_EXTERN_TEMPLATE
macro gets defined to -1 instead of defined to 1.