LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 28954 - basic streams may not be initialized early enough
Summary: basic streams may not be initialized early enough
Status: RESOLVED FIXED
Alias: None
Product: libc++
Classification: Unclassified
Component: All Bugs (show other bugs)
Version: unspecified
Hardware: PC Linux
: P normal
Assignee: Louis Dionne
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-08-12 15:08 PDT by dsturtevant
Modified: 2020-09-16 10:21 PDT (History)
8 users (show)

See Also:
Fixed By Commit(s): 39faf428164a28f3652370958ce893d9200927c8


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description dsturtevant 2016-08-12 15:08:16 PDT
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 <iostream> statically defined an instance of std::ios_base::Init.

The example given in the changelist:

#include <iostream>
 
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.
Comment 1 Evgeny Astigeevich 2016-08-15 03:55:25 PDT
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++.
Comment 2 Hal Finkel 2017-03-09 17:42:23 PST
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?
Comment 3 Hal Finkel 2017-03-09 17:52:19 PST
(In reply to Hal Finkel from comment #2)
> 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?
Comment 4 Evgeny Astigeevich 2017-03-10 02:36:02 PST
(In reply to Hal Finkel from comment #3)
> 
> 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.
Comment 5 Hal Finkel 2017-03-11 11:35:17 PST
FWIW, I tried the __attribute__((init_priority(101))) on my system (PPC64/Linux) and it seems to work.
Comment 6 Eric Fiselier 2017-03-27 20:00:22 PDT
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.
Comment 7 Sam Clegg 2020-09-15 18:01:41 PDT
This came up again in wasi-sdk: https://github.com/WebAssembly/wasi-sdk/issues/153


And for the record the original emscripten issue from way back: https://github.com/emscripten-core/emscripten/issues/3824

And my proposed fix: https://reviews.llvm.org/D74885
Comment 8 Louis Dionne 2020-09-16 10:21:51 PDT
Should be fixed by

commit 39faf428164a28f3652370958ce893d9200927c8
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 http://llvm.org/PR28954, but also in various open
    source projects that use libc++.

    Fixes http://llvm.org/PR28954.

    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.