Bug 61758 - std::chrono::steady_clock::now() no longer exported
Summary: std::chrono::steady_clock::now() no longer exported
Status: RESOLVED WONTFIX
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 4.8.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-07-09 09:25 UTC by Martin von Gagern
Modified: 2014-12-21 11:06 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin von Gagern 2014-07-09 09:25:44 UTC
Between 4.8.0 and 4.8.1, SVN commit 199331 changed the implementation of compatibility-chrono.cc. Up to that point, it basically included chrono.cc which provided implementations for system_clock and steady_clock, but bound them to specific symbol versions. That commit changes the approach to make use of an inline namespace, which is certainly more portable. The compatibility implementation was modified to no longer include chrono.cc but instead duplicate part of its functionality.

And therein lies the rub: only PART of the implementation has been copied to the compatibility file. Now system_clock is included there, but steady_clock is not. Which causes ABI breakage, as observed in https://bugs.gentoo.org/513386.
Comment 1 Martin von Gagern 2014-07-09 10:16:53 UTC
I just read https://gcc.gnu.org/ml/gcc-patches/2013-05/msg01553.html indicating that this is likely a deliberate ABI breakage for an experimental API. If that is your official position, feel free to close WONTFIX. Too bad that this kind of information contained in the email isn't included in the commit message. Would have saved me a lot of time.
Comment 2 Jonathan Wakely 2014-07-09 11:39:56 UTC
It is totally unsupported (and unlikely to work) to mix C++11 code built with GCC 4.x and 4.y, for any x!=y

Mixing code built with 4.8.x and 4.8.y should work, and does with the default configuration.

You didn't actually provide the information required by http://gcc.gnu.org/bugs such as the output of 'gcc -v' but I assume you're building GCC with --enable-libstdcxx-time, in which case there are fewer guarantees. If Gentoo is using that option (which should not be necessary with GCC 4.8 anyway) then you need to rebuild all the libraries that depend on the <chrono> types.

We could potentially export a steady_clock::now() compatibility symbol for the --enable-libstdcxx-time config, but I'd prefer to see that option go away rather than keep it on life support.
Comment 3 Jakub Jelinek 2014-07-09 11:49:27 UTC
The main problem was that --enable-libstdcxx-time used to be ABI incompatible option in the past.
Comment 4 Martin von Gagern 2014-07-09 12:40:24 UTC
Thanks for the quick reply.

(In reply to Jonathan Wakely from comment #2)
> It is totally unsupported (and unlikely to work) to mix C++11 code built
> with GCC 4.x and 4.y, for any x!=y

Any particular reason why you don't change the SONAME of the library for every change from x to y in this case?

The way I see it, this might be causing serious problems for Gentoo in the near future. As far as I understand things, Gentoo will always dynamically link against the latest version of libstdc++, even though different versions of gcc (and there can be several installed concurrently) will compile against their own matching version. Assuming ABI backwards-compatibility, at least with the help of symbol versioning, this probably worked well enough so far. But if there are no such guarantees for C++11 then things will break more often as applications start to use C++11.

> Mixing code built with 4.8.x and 4.8.y should work, and does with the
> default configuration.

I've got some doubts regarding 4.8.0 to 4.8.1 since the commits I mentioned were in between. But I don't have evidence to support my doubts, and I'm more interested in the 4.7 to 4.8 issues.

> You didn't actually provide the information required by
> http://gcc.gnu.org/bugs such as the output of 'gcc -v' but I assume you're
> building GCC with --enable-libstdcxx-time, in which case there are fewer
> guarantees. If Gentoo is using that option

It is, as per https://bugs.gentoo.org/411681

> (which should not be necessary with GCC 4.8 anyway) then you need to
> rebuild all the libraries that depend on the <chrono> types.

Using gcc 4.8 throughout works fine, it's the mixing of a 4.7 compiler, configured as system default, and a 4.8 library used since it's the latest, which is causing the specific troubles on Gentoo.

> We could potentially export a steady_clock::now() compatibility symbol for
> the --enable-libstdcxx-time config, but I'd prefer to see that option go
> away rather than keep it on life support.

In what way has the ABI actually changed between chrono::steady_clock::now() and chrono::_V2::steady_clock::now()? Looking at http://repo.or.cz/w/official-gcc.git/blobdiff/95da0dc6f30722a5c46af68d1d6a24e7830b4b68..HEAD:/libstdc%2B%2B-v3/src/c%2B%2B11/chrono.cc it looks to me as if you added that syscall capability, which I consider an internal modification only, and you changed the #ifdef _GLIBCXX_USE_CLOCK_MONOTONIC from completely removing the function to falling back on system_clock. Right? So either the old lib did export that symbol or it did not, but the new lib always export the symbol, and does so in a compatible fashion. Is there any drawback from unconditionally exporting that new implementation as an alias for the old? Something like this:

#if defined(_GLIBCXX_SYMVER_GNU) && defined(_GLIBCXX_SHARED) \
 && defined(_GLIBCXX_HAVE_AS_SYMVER_DIRECTIVE)               \
 && defined(_GLIBCXX_HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT)
// alias for backwards abi compatibility, see #61758
asm (".symver "
     "_ZNSt6chrono3_V212steady_clock3nowEv,"
     "_ZNSt6chrono12steady_clock3nowEv@GLIBCXX_3.4.17");
#endif

That way, you would not have to maintain the --enable-libstdcxx-time config setting, and you would also help portability in those cases where code was compiled on a 4.7 system with --enable-libstdcxx-time no matter the setting used for the 4.8 system where the code is executed.
Comment 5 Jonathan Wakely 2014-07-09 13:01:38 UTC
(In reply to Martin von Gagern from comment #4)
> (In reply to Jonathan Wakely from comment #2)
> > It is totally unsupported (and unlikely to work) to mix C++11 code built
> > with GCC 4.x and 4.y, for any x!=y
> 
> Any particular reason why you don't change the SONAME of the library for
> every change from x to y in this case?

Think about it. That would prevent you from combining C++03 code compiled with different versions, and that works fine and is not experimental. Forcing millions of lines of C++03 code to be recompiled because of changes to experimental C++11 features would not be acceptable.

> The way I see it, this might be causing serious problems for Gentoo in the
> near future. As far as I understand things, Gentoo will always dynamically
> link against the latest version of libstdc++, even though different versions
> of gcc (and there can be several installed concurrently) will compile
> against their own matching version. Assuming ABI backwards-compatibility, at
> least with the help of symbol versioning, this probably worked well enough
> so far. But if there are no such guarantees for C++11 then things will break
> more often as applications start to use C++11.

There will be guarantees soon, when the ABI stabilises. Until then, if Gentoo does that then it's Gentoo's problem. We can devote our limited resources to getting the ABI stable sooner, or we can spend our time on loads of nasty hacks to maintain compatibility for people using unsupported configurations and expecting behaviour we never guaranteed.
 
> > Mixing code built with 4.8.x and 4.8.y should work, and does with the
> > default configuration.
> 
> I've got some doubts regarding 4.8.0 to 4.8.1 since the commits I mentioned
> were in between. But I don't have evidence to support my doubts, and I'm
> more interested in the 4.7 to 4.8 issues.

There is no guarantee of compatibility for C++11 features between those releases, so any issues are irrelevant.


> > (which should not be necessary with GCC 4.8 anyway) then you need to
> > rebuild all the libraries that depend on the <chrono> types.
> 
> Using gcc 4.8 throughout works fine, it's the mixing of a 4.7 compiler,
> configured as system default, and a 4.8 library used since it's the latest,
> which is causing the specific troubles on Gentoo.

You can't do that for code that uses C++11 library types. Period. Not a bug.

> That way, you would not have to maintain the --enable-libstdcxx-time config
> setting, and you would also help portability in those cases where code was
> compiled on a 4.7 system with --enable-libstdcxx-time no matter the setting
> used for the 4.8 system where the code is executed.

I'm not interested in supporting C++11 code built with 4.7 and linking to 4.8 at runtime. Don't do that.
Comment 6 Jonathan Wakely 2014-12-21 11:06:30 UTC
As previously discussed, the --enable-libstdcxx-time function alters the experimental C++11 ABI and is not expected to be stable.

It shouldn't be used (or necessary) going forward anyway.