Re: Incorrect std::ostream behavior when using RTLD_DEEPBIND and Optimization

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxx> 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@xxxxxxxxxxxxxxxxx>
School of Aerospace Science and Technology, Xidian University



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux