This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: Incorrect std::ostream behavior when using RTLD_DEEPBIND and Optimization
- From: Xi Ruoyao <ryxi at stu dot xidian dot edu dot cn>
- To: Daniel Peck <dpeck at plexsys dot com>
- Cc: "gcc-help at gcc dot gnu dot org" <gcc-help at gcc dot gnu dot org>, Jakub Jelinek <jakub at gcc dot gnu dot org>
- Date: Sat, 26 May 2018 15:39:01 +0800
- Subject: Re: Incorrect std::ostream behavior when using RTLD_DEEPBIND and Optimization
- References: <2D612A9D3034DD46901712ECBE139B30396A8A66@mail4.plexsysipi.local>
On 2018-05-26 00:20 +0000, Daniel Peck wrote:
> Hello,
>
> I have encountered an issue when using std::ostream's that causes them to enter a fail state anytime a number is piped
> into them.
>
> I have attached a minimal example project which will allow you to reproduce the issue.
>
> The minimal example is as follows, I have a main executable that dynamically loads two shared libraries using the
> RTLD_DEEPBIND flag, both the main module and the shared libraries statically link against libgcc and libstdc++, and
> they both are built with optimization enabled.
>
> If you do not use the RTLD_DEEPBIND flag, the issue does not occur. If you do not use optimization, the issue does
> not occur. The issue does not occur in the first shared library loaded but does occur in all subsequently loaded
> shared libraries.
I found PR42679 <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=42679> with Google.
Jakub Jelinek <jakub@gcc.gnu.org> said:
> If libstdc++ relies on ODR, then RTLD_DEEPBIND can break its assumptions, as then the same symbol which is defined in
> multiple shared libraries can resolve to different addresses (RTLD_DEEPBIND means first the dlopened library and its
> dependencies, and only after it the global search scope, will be searched).
>
> STB_GNU_UNIQUE object ought to cure it, though it is only in 4.5 (and 4.4-RH) gcc and sufficiently new binutils and
> glibc are needed for it too.
This may cause the issue.
> Both the main module and the shared libraries are also being built with the -fPIC argument.
>
> I originally discovered this issue using gcc-5.3.0, so I built gcc-7.3.0 and tried with that but I am still
> experiencing the same issue. Just for some context, I am running on CentOS 6.7 and I have also tried on CentOS 6.9.
*
> To build the project run "make debug" or "make release" at the top level directory or individually within the
> different projects. The main difference between debug and release is the use of optimization.
> Also, the makefiles create both x86 and x64 versions but the main module is explicitly loading the x64 versions of the
> shared libraries.
>
> Within the first shared library the following code snippet outputs "Number: 5.", but in the second shared library
> which is identical, it outputs "Number: " and the stream enters a error state (the failbit and the badbit are set).
>
> // OtherLibrary: shared library code snippet
> void UseStreams()
> {
> std::ostringstream oss;
> uint16_t unNumber = 5;
>
> // note that neither the number nor the period are displayed because the stream enters an invalid state.
> oss << "Number: " << unNumber << ".";
>
> std::cout << oss.str() << std::endl;
> }
I can reproduce this with:
$ g++ so.cc -shared -fPIC -o so.so -g -static-libstdc++
$ g++ main.cc -ldl -g
$ ./a.out
Number:
Note that there is no optimization. But if I use -static-libstdc++ for main.cc:
$ g++ main.cc -ldl -g -static-libstdc++
$ ./a.out
Number: 5.
This is good.
I tried GCC 7.3.0 and 8.1.0, but I don't have a libstdc++.a of GCC 7.3.0 so I used
the one from 8.1.0.
--
Xi Ruoyao <ryxi@stu.xidian.edu.cn>
School of Aerospace Science and Technology, Xidian University