Bug 87199 - Thread local storage dynamic initialization behaviour differs Linux vs macOS
Summary: Thread local storage dynamic initialization behaviour differs Linux vs macOS
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 8.2.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-09-03 09:28 UTC by me
Modified: 2019-02-27 01:04 UTC (History)
3 users (show)

See Also:
Host:
Target: x86_64-apple-darwin*
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
program output & gcc configuration in Yosemite (505 bytes, text/plain)
2019-01-31 09:24 UTC, Ev Drikos
Details
program output & gcc configuration in Sierra (666 bytes, text/plain)
2019-01-31 09:26 UTC, Ev Drikos
Details

Note You need to log in before you can comment on or make changes to this bug.
Description me 2018-09-03 09:28:11 UTC
Hello,

Here is a test program that behaves different on Linux vs macOS.

main.c:
```
#include "lib.h"

int main() {
    getProfileEvents();
}
```

lib.cpp
```
#include "lib.h"

thread_local ThreadStatus thread_local_var = ThreadStatus();

ThreadStatus::ThreadStatus() {
    std::cout << "cons";

    doX();
}
```

lib.h
```
#pragma once

#include <memory>
#include <iostream>

class ThreadStatus {
public:
    int x = 0;

    ThreadStatus();

    static void doX() { std::cout << "test"; }
};

extern thread_local ThreadStatus thread_local_var;

static int getProfileEvents() {
    return thread_local_var.x;
}
```

Compiling it using the following command:

`g++-8 -g -std=c++17 -c -I . main.cpp && g++-8 -g  -std=c++17 -c -I . lib.cpp && g++-8 -o main main.o lib.o && ./main`

On a Linux machine the output is: "constest" (g++-8 (Ubuntu 8-20180414-1ubuntu2) 8.0.1 20180414 (experimental) [trunk revision 259383])
On a macOS machine the output is empty. (Homebrew GCC 8.2.0, also HEAD)

I found curious that moving doX definition from .h file to .cpp will make this work correctly.
Comment 1 Eric Gallager 2018-09-03 11:31:20 UTC
My first guess would be that the difference is Linux has native TLS, whereas macOS only has emutls, which would be bug 52268. I'll wait for someone else to confirm, though.
Comment 2 Ev Drikos 2019-01-24 00:38:07 UTC
(In reply to Eric Gallager from comment #1)
> My first guess would be that the difference is Linux has native TLS, whereas
> macOS only has emutls, which would be bug 52268. I'll wait for someone else
> to confirm, though.


Not really sure if my response is indeed the confirmation you want. 

If I compile the above example in macOS High Sierra (10.13) with the much older GNU gcc-4.8.5, then the output is "constest". Whereas with the newer gcc-8.2 I see the same results with the OP.

$ g++ --version && uname -r
g++ (GCC) 4.8.5
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

17.5.0
$ g++  -g  -std=c++11 -c -I . main.c
$ g++  -g  -std=c++11 -c -I . lib.cpp
$ g++  -o main main.o lib.o
$ ./main
constest$ 
$ g++8  -g  -std=c++11 -c -I . main.c
$ g++8  -g  -std=c++11 -c -I . lib.cpp
$ g++8  -o main main.o lib.o
$ ./main
$

Ev. Drikos
Comment 3 Ev Drikos 2019-01-31 09:24:04 UTC
Created attachment 45573 [details]
program output & gcc configuration in Yosemite
Comment 4 Ev Drikos 2019-01-31 09:26:00 UTC
Created attachment 45574 [details]
program output & gcc configuration in Sierra

Hello,

Having run this small test in older systems also, Yosemite (10.11) and sierra (10.12), 
I see that the results vary. I can reproduce the problem in Yosemite, not in Sierra.

IMHO opinion, this issue depends either on GNU GCC configuration or to some patch
I've applied in the meantime. My guess is that the reason is likely the configuration.

Ev. Drikos
Comment 5 Ev Drikos 2019-02-26 23:29:06 UTC
 Hello,

 At first, I'd like to note that these 2 options are also ok in MacOS-10.13:
 (a) g++8 -g  -std=c++11      lib.cpp   main.c -o main && ./main
 (b) g++8 -g  -std=c++11 -I . main.c    -S
     g++8 -g  -std=c++11 -I . lib.cpp   -S 
     g++8 -g  -std=c++11 -I . lib.s main.s     -o main && ./main

 Just for the record, a fresh built gcc-4.8.5~36 in OS X Yosemite (10.10) 
 doesn't have this problem but I just faced it in OS X Mavericks (10.9),
 where I had to properly comment the stmt "ld_uses_coal_sects = true" in
 file "darwin.c", added by an unofficial backport of PR/71767.

 
 Hope this helps,
 Ev. Drikos