This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]