Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

basic streams may not be initialized early enough #29324

Closed
llvmbot opened this issue Aug 12, 2016 · 9 comments
Closed

basic streams may not be initialized early enough #29324

llvmbot opened this issue Aug 12, 2016 · 9 comments
Assignees
Labels
bugzilla Issues migrated from bugzilla libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

Comments

@llvmbot
Copy link
Collaborator

llvmbot commented Aug 12, 2016

Bugzilla Link 28954
Resolution FIXED
Resolved on Sep 16, 2020 10:21
Version unspecified
OS Linux
Reporter LLVM Bugzilla Contributor
CC @eastig,@hfinkel,@ldionne,@mclow,@zygoloid,@sbc100
Fixed by commit(s) 39faf42

Extended Description

This is a bug that https://reviews.llvm.org/D12689 attempted to address.

The C++11 standard (Section 27.4.1.2) requires that basic streams be initialized as if an inclusion of statically defined an instance of std::ios_base::Init.

The example given in the changelist:

#include

class Foo {
public:
Foo(int n) {
std::cout << "Hello World - " << n << std::endl;
}
};

Foo f(5);

int main() {
return 0;
}

With the head version of libc++, this program may crash.

@llvmbot
Copy link
Collaborator Author

llvmbot commented Aug 12, 2016

assigned to @ldionne

@eastig
Copy link
Member

eastig commented Aug 15, 2016

The issue can happen when static linking is used. The patch is not accepted because of performance concerns.However the similar approach is used by gcc libc++.

@hfinkel
Copy link
Collaborator

hfinkel commented Mar 10, 2017

We really do need to fix this. It makes a statically-linked libc++ unusable for many applications (I just ran across one today as well).

On the review https://reviews.llvm.org/D12689, Richard asked if we can solve this using link order. I don't think so. libc++.a needs to occur after the object files being linked (I played around with putting libc++.a before the object files and using -start-group/-end-group to make the linking work anyway, but that didn't solve the problem).

Reid suggested using " attribute((init_priority(101))) on Linux and #pragma init_seg(lib) on Windows to ensure that libc++'s iostream initializer runs earlier."

It was pointed out that these don't work with all linkers (perhaps only ld.bfd and ld.gold). Nevertheless, I'm inclined to agree: this is the best approach. For systems using other linkers that don't support this, some other system-specific approach can be used (linker scripts or similar).

Thoughts?

@hfinkel
Copy link
Collaborator

hfinkel commented Mar 10, 2017

We really do need to fix this. It makes a statically-linked libc++ unusable
for many applications (I just ran across one today as well).

On the review https://reviews.llvm.org/D12689, Richard asked if we can solve
this using link order. I don't think so. libc++.a needs to occur after the
object files being linked (I played around with putting libc++.a before the
object files and using -start-group/-end-group to make the linking work
anyway, but that didn't solve the problem).

Reid suggested using " attribute((init_priority(101))) on Linux and
#pragma init_seg(lib) on Windows to ensure that libc++'s iostream
initializer runs earlier."

It was pointed out that these don't work with all linkers (perhaps only
ld.bfd and ld.gold). Nevertheless, I'm inclined to agree: this is the best
approach. For systems using other linkers that don't support this, some
other system-specific approach can be used (linker scripts or similar).

Or maybe we should have the solution posed in D12689, but only as a fallback for systems where this can't be done any other way?

Thoughts?

@eastig
Copy link
Member

eastig commented Mar 10, 2017

Or maybe we should have the solution posed in D12689, but only as a fallback
for systems where this can't be done any other way?

Thoughts?

I like your idea. If a target system provides a faster way to do this we should use it. If not, the fallback should be used.

@hfinkel
Copy link
Collaborator

hfinkel commented Mar 11, 2017

FWIW, I tried the attribute((init_priority(101))) on my system (PPC64/Linux) and it seems to work.

@llvmbot
Copy link
Collaborator Author

llvmbot commented Mar 28, 2017

Thanks Hal. I put that fix up for review as https://reviews.llvm.org/D31413. Hopefully somebody will know how to write a test for it.

@sbc100
Copy link
Collaborator

sbc100 commented Sep 16, 2020

This came up again in wasi-sdk: WebAssembly/wasi-sdk#153

And for the record the original emscripten issue from way back: emscripten-core/emscripten#3824

And my proposed fix: https://reviews.llvm.org/D74885

@ldionne
Copy link
Member

ldionne commented Sep 16, 2020

Should be fixed by

commit 39faf42
Author: Louis Dionne ldionne@apple.com
Date: Thu May 14 09:56:35 2020 -0400

[libc++] Ensure streams are initialized early

When statically linking libc++ on some systems, the streams are not
initialized early enough, which causes all kinds of issues. This was
reported e.g. in llvm/llvm-project#29324 , but also in various open
source projects that use libc++.

Fixes llvm/llvm-project#29324 .

Differential Revision: https://reviews.llvm.org/D31413

Thanks to everyone who submitted patches, explored various options, wrote tests. I didn't do anything except gather these into a single patch and commit it.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

No branches or pull requests

5 participants