This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: libstdc++: ODR violation when using std::regex with and without -D_GLIBCXX_DEBUG
- From: Jonathan Wakely <jwakely dot gcc at gmail dot com>
- To: "libstdc++" <libstdc++ at gcc dot gnu dot org>
- Cc: Stephan Bergmann <sbergman at redhat dot com>, "gcc at gcc dot gnu dot org" <gcc at gcc dot gnu dot org>
- Date: Tue, 8 May 2018 16:17:59 +0100
- Subject: Re: libstdc++: ODR violation when using std::regex with and without -D_GLIBCXX_DEBUG
- References: <0313d6bf-9a35-18d7-932a-3adc09c064d8@redhat.com> <CAH6eHdRwuHW8oEY4P5F3UeWEg9RTLt=Fwp+21dTFq5BH5po7FA@mail.gmail.com> <CAH6eHdT+pNGVYDpgYDW9KhFq=1fNinGtDKvkQYG4TM4yAqp=2A@mail.gmail.com> <alpine.DEB.2.21.1805081642190.22263@stedding.saclay.inria.fr>
On 8 May 2018 at 15:45, Marc Glisse <marc.glisse@inria.fr> wrote:
> On Tue, 8 May 2018, Jonathan Wakely wrote:
>
>> On 8 May 2018 at 14:00, Jonathan Wakely wrote:
>>>
>>> On 8 May 2018 at 13:44, Stephan Bergmann wrote:
>>>>
>>>> I was recently bitten by the following issue (Linux, libstdc++ 8.0.1): A
>>>> process loads two dynamic libraries A and B both using std::regex, and A
>>>> is
>>>> compiled without -D_GLIBCXX_DEBUG while B is compiled with
>>>> -D_GLIBCXX_DEBUG.
>>>
>>>
>>> This is only supported in very restricted cases.
>>>
>>>> B creates an instance of std::regex, which internally creates a
>>>> std::shared_ptr<std::__detail::_NFA<std::__cxx11::regex_traits<char>>>,
>>>> where _NFA has various members of std::__debug::vector type (but which
>>>> isn't
>>>> reflected in the mangled name of that _NFA instantiation itself).
>>>>
>>>> Now, when that instance of std::regex is destroyed again in library B,
>>>> the
>>>>
>>>> std::shared_ptr<std::__detail::_NFA<std::__cxx11::regex_traits<char>>>::~shared_ptr
>>>> destructor (and functions it in turn calls) that happens to get picked
>>>> is
>>>> the (inlined, and exported due to default visibility) instance from
>>>> library
>>>> A. And that assumes that that _NFA instantiation has members of
>>>> non-debug
>>>> std::vector type, which causes a crash.
>>>>
>>>> Should it be considered a bug that such mixture of debug and non-debug
>>>> std::regex usage causes ODR violations?
>>>
>>>
>>> Yes, but my frank response is "don't do that".
>>>
>>> The right fix here might be to ensure that _NFA always uses the
>>> non-debug vector even in Debug Mode, but I'm fairly certain there are
>>> other similar problems lurking.
>>
>>
>> N.B. I think this discussion belongs on the libstdc++ list.
>
>
> Would it make sense to use the abi_tag attribute to help with that? (I
> didn't really think about it, maybe it doesn't)
Yes, I think we could add it conditionally in debug mode, so that
types with members that are either std::xxx or __gnu_debug::xxx get a
different mangled name in debug mode.
For the regex _NFA type I don't think we want the debug mode checking,
because users can't access it directly so any errors are in the
libstdc++ implementation and we should have eliminated them ourselves,
not be pushing detection of those logic errors into users' programs.
For std::match_results (which derives from std::vector) it's possible
for users to use invalid iterators obtained from a match_results, so
Debug Mode can help. In that case we could decide whether to add the
abi_tag, or always derive from _GLIBCXX_STD_C::vector (i.e. the
non-debug mode one), or even provide an entire
__gnu_debug::match_results type.
> "don't do that" remains the most sensible answer.
Yes, it's just asking for trouble.