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

Crashing using thread-local storage within shared libraries called from an MSVC-built executable #18

Closed
MrDOS opened this issue Jun 29, 2020 · 3 comments
Assignees
Labels
bug Something isn't working

Comments

@MrDOS
Copy link

MrDOS commented Jun 29, 2020

I'm encountering a hard crash (segfault) when using thread-local storage (TLS) in shared libraries (DLLs) built with TDM-GCC
and consumed from executables built with MSVC. This seems to only affect TDM-GCC: libraries built with MinGW-w64 don't have the issue. This is reproducible with the latest 64-bit release of TDM-GCC, 9.2.0, and the second-latest release, 5.1.0-2. I haven't tried any 32-bit targets.

The issue manifests itself when simply accessing (reading or writing) a TLS variable:

static _Thread_local int foo = 0;

void bar()
{
    ++foo; /* Crash! */
}

However, there are much more subtle ways of provoking the issue, because a number of libraries – notably, pthreads – rely on TLS. For example, pthread_self(3) will hard crash. Surprising behaviour from a function whose documentation boldly states

This function always succeeds.

Reproduction

Reproduction code is here: tlscrash.tar.gz.

main.c is about as small as it can be. The core of tls.c is lines 22–29; everything else is there to enable compilation under both MSVC and GCC. The Makefile mostly helps keep compiler flags and output filenames straight.

To build and reproduce, you'll need to have installed:

Launch the “x64 Native Tools Command Prompt for VS 2019” to get a command-line environment where MSVC will work. Then:

C:\path\to\tlscrash>mingw32-make VARIANT=msvc
cl /LD /Fetls-msvc.dll tls.c
...
cl  /Femain-msvc.exe main.c
...
C:\path\to\tlscrash>mingw32-make CC=C:\Tools\TDM-GCC-64-9.2.0\bin\x86_64-w64-mingw32-gcc.exe VARIANT=tdm-gcc-64-9.2.0
C:\Tools\TDM-GCC-64-9.2.0\bin\x86_64-w64-mingw32-gcc.exe -fPIC -shared -otls-tdm-gcc-64-9.2.0.dll tls.c
C:\Tools\TDM-GCC-64-9.2.0\bin\x86_64-w64-mingw32-gcc.exe  -omain-tdm-gcc-64-9.2.0.exe main.c

If you have any other toolchains installed, you can compile with those for comparison, too:

C:\path\to\tlscrash>mingw32-make CC=C:\Tools\mingw-w64\x86_64-8.1.0-release-posix-seh-rt_v6-rev0\bin\x86_64-w64-mingw32-gcc.exe VARIANT=mingw-w64-8.1.0
C:\Tools\mingw-w64\x86_64-8.1.0-release-posix-seh-rt_v6-rev0\bin\x86_64-w64-mingw32-gcc.exe -fPIC -shared -otls-mingw-w64-8.1.0.dll tls.c
C:\Tools\mingw-w64\x86_64-8.1.0-release-posix-seh-rt_v6-rev0\bin\x86_64-w64-mingw32-gcc.exe  -omain-mingw-w64-8.1.0.exe main.c

The main executables expect one argument: the name of the library to load.

Expected success:

C:\path\to\tlscrash>main-msvc.exe tls-msvc.dll
Now running library code.
The TLS value is 0.
Returning from the library code.

Expected failure:

C:\Users\scoleman\Projects\tlscrash>main-msvc.exe tls-tdm-gcc-64-9.2.0.dll
Now running library code.

Or, in a MSYS2 environment (e.g., Git Bash):

$ ./main-msvc.exe tls-tdm-gcc-64-9.2.0.dll
Segmentation fault

Toolchains tested

To isolate this to TDM-GCC, I've tried a variety of different toolchains. This failure seems to be particular to TDM-GCC, and not to the latest version.

DLL ↓/EXE → MSVC TDM-GCC-64 5.1.0-2 TDM-GCC-64 9.2.0 MinGW-w64 ??? (GCC 8.1.0) MinGW-w64 5.0.3 (GCC 7.3.0), Ubuntu host
MSVC
TDM-GCC-64 5.1.0-2
TDM-GCC-64 9.2.0
MinGW-w64 ??? (GCC 8.1.0)*
MinGW-w64 5.0.3 (GCC 7.3.0), Ubuntu host

* This was installed from x86_64-8.1.0-release-posix-seh-rt_v6-rev0.7z. MinGW and GCC version numbers don't seem to line up, so I'm not sure what MinGW version this would be.

@jmeubank jmeubank added the bug Something isn't working label Jul 3, 2020
@jmeubank
Copy link
Owner

jmeubank commented Jul 3, 2020

Hi @MrDOS - posting to say, thanks for the detailed analysis! It's appreciated. This should contain all the information needed to debug the issue, and points towards https://github.com/jmeubank/mingw-w64/blob/v7.x.public/_PATCHES/shmem.patch as the likely culprit. It may take some time to solve.

@jmeubank jmeubank self-assigned this Jul 3, 2020
@jmeubank
Copy link
Owner

This will be fixed in the upcoming TDM-GCC 10.3.0 release!

C:\crossdev\tests\tlscrash>main-msvc.exe tls-tdm-gcc-64-10.3.0.dll
Now running library code.
The TLS value is 0.
Returning from the library code.

@MrDOS
Copy link
Author

MrDOS commented May 29, 2021

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants