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

Windows gcc shipped with choosenim 1.6.4 with TLS emulation turned off : The application was unable to start correctly (0xc000007b). Click OK to close the application #19713

Closed
creikey opened this issue Apr 12, 2022 · 28 comments · Fixed by #20327

Comments

@creikey
Copy link

creikey commented Apr 12, 2022

Hello world fails with this error:

The application was unable to start correctly (0xc000007b). Click OK to close the application

building with nim r --threads:on hello.nim
without --threads:on it works
with the file:

echo "hello"

On windows 11 nim 1.6.4 on a fresh install

This worked on nim 1.6.0

image

I completely deleted .choosenim, .nimble, nimcache, cleared the path variables, then reinstalled nim once by downloading from the website, which didn't work, then again with choosenim, which also didn't work.

Nim Compiler Version 1.6.4 [Windows: amd64]
Compiled at 2022-02-09
Copyright (c) 2006-2021 by Andreas Rumpf

active boot switches: -d:release
@creikey creikey changed the title The application was unable to start correctly (0xc000007b). Click OK to close the application When building 1.6.4 with threads: The application was unable to start correctly (0xc000007b). Click OK to close the application Apr 12, 2022
@ringabout
Copy link
Member

Cannot reproduce on win11

Nim Compiler Version 1.6.4 [Windows: amd64]
Compiled at 2022-02-09
Copyright (c) 2006-2021 by Andreas Rumpf

active boot switches: -d:release

@creikey
Copy link
Author

creikey commented Apr 12, 2022

Cannot reproduce on win11

Nim Compiler Version 1.6.4 [Windows: amd64]
Compiled at 2022-02-09
Copyright (c) 2006-2021 by Andreas Rumpf

active boot switches: -d:release

did you try compiling hello with --threads:on?

@ringabout
Copy link
Member

Yeah, I testsed with --threads:on

echo "hello"

doAssert compileOption("threads")

@creikey
Copy link
Author

creikey commented Apr 12, 2022

Because it's an issue with threads, I suspect it's some kind of path confusion with what threads dll it's linking with, but I have no idea how to check something like this...

@beef331
Copy link
Collaborator

beef331 commented Apr 12, 2022

You could use --listCmd to see the call to your C compiler and see if anything doesn't make sense.

@creikey
Copy link
Author

creikey commented Apr 12, 2022

You could use --listCmd to see the call to your C compiler and see if anything doesn't make sense.

Thanks for the troubleshooting tip

Everything is ran like

nim --threads:on --listCmd r -f hello.nim
CC: stdlib_digitsutils.nim: gcc.exe -c  -w -fmax-errors=3 -mno-ms-bitfields   -IC:\Users\Cameron\.choosenim\toolchains\nim-1.6.4\lib -IC:\Users\Cameron\Documents -o C:\Users\Cameron\nimcache\hello_d\stdlib_digitsutils.nim.c.o C:\Users\Cameron\nimcache\hello_d\stdlib_digitsutils.nim.c
CC: stdlib_dollars.nim: gcc.exe -c  -w -fmax-errors=3 -mno-ms-bitfields   -IC:\Users\Cameron\.choosenim\toolchains\nim-1.6.4\lib -IC:\Users\Cameron\Documents -o C:\Users\Cameron\nimcache\hello_d\stdlib_dollars.nim.c.o C:\Users\Cameron\nimcache\hello_d\stdlib_dollars.nim.c
CC: stdlib_sharedlist.nim: gcc.exe -c  -w -fmax-errors=3 -mno-ms-bitfields   -IC:\Users\Cameron\.choosenim\toolchains\nim-1.6.4\lib -IC:\Users\Cameron\Documents -o C:\Users\Cameron\nimcache\hello_d\stdlib_sharedlist.nim.c.o C:\Users\Cameron\nimcache\hello_d\stdlib_sharedlist.nim.c
CC: stdlib_io.nim: gcc.exe -c  -w -fmax-errors=3 -mno-ms-bitfields   -IC:\Users\Cameron\.choosenim\toolchains\nim-1.6.4\lib -IC:\Users\Cameron\Documents -o C:\Users\Cameron\nimcache\hello_d\stdlib_io.nim.c.o C:\Users\Cameron\nimcache\hello_d\stdlib_io.nim.c
CC: stdlib_system.nim: gcc.exe -c  -w -fmax-errors=3 -mno-ms-bitfields   -IC:\Users\Cameron\.choosenim\toolchains\nim-1.6.4\lib -IC:\Users\Cameron\Documents -o C:\Users\Cameron\nimcache\hello_d\stdlib_system.nim.c.o C:\Users\Cameron\nimcache\hello_d\stdlib_system.nim.c
CC: hello.nim: gcc.exe -c  -w -fmax-errors=3 -mno-ms-bitfields   -IC:\Users\Cameron\.choosenim\toolchains\nim-1.6.4\lib -IC:\Users\Cameron\Documents -o C:\Users\Cameron\nimcache\hello_d\@mhello.nim.c.o C:\Users\Cameron\nimcache\hello_d\@mhello.nim.c

These are compiling the .o files, nothing weird here

Here is the linking

Hint: gcc.exe   -o C:\Users\Cameron\nimcache\hello_d\hello_7D9E602FA2A89065BE0A59241375AEACB65D60A1.exe  C:\Users\Cameron\nimcache\hello_d\stdlib_digitsutils.nim.c.o C:\Users\Cameron\nimcache\hello_d\stdlib_dollars.nim.c.o C:\Users\Cameron\nimcache\hello_d\stdlib_sharedlist.nim.c.o C:\Users\Cameron\nimcache\hello_d\stdlib_io.nim.c.o C:\Users\Cameron\nimcache\hello_d\stdlib_system.nim.c.o C:\Users\Cameron\nimcache\hello_d\@mhello.nim.c.o     [Link]

It looks like it's just linking the .o files it compiled earlier with no extra flags? What does --threads:on actually change? where gcc.exe returns the proper path by the way

where gcc.exe
C:\Users\Cameron\.nimble\bin\gcc.exe

@creikey
Copy link
Author

creikey commented Apr 12, 2022

Diffing the generated C with threads on (left) vs threads off (right)
image

This is the only difference in hello.c (from hello.nim)

Similar results in the standard library compiled C
image

NIM_THREADVAR is just this
image

Apart from CLANG_NO_SANITIZE_ADDRESS which I could not find the meaning of, I've tried to duplicate the error in a plain C file with as minimal code as possible to no such luck

#include <stdio.h>

#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112 && !defined __STDC_NO_THREADS__
#  define NIM_THREADVAR _Thread_local
#elif defined _WIN32 && ( \
       defined _MSC_VER || \
       defined __ICL || \
       defined __DMC__ || \
       defined __BORLANDC__ )
#  define NIM_THREADVAR __declspec(thread)
#elif defined(__TINYC__) || defined(__GENODE__)
#  define NIM_THREADVAR
/* note that ICC (linux) and Clang are covered by __GNUC__ */
#elif defined __GNUC__ || \
       defined __SUNPRO_C || \
       defined __xlC__
#  define NIM_THREADVAR __thread
#else
#  error "Cannot define NIM_THREADVAR"
#endif

typedef char* NCSTRING;
typedef signed short int NI16;
typedef __int64 NI64;
typedef NI64 NI;

typedef struct TFrame_ TFrame;
struct TFrame_ {
  TFrame* prev;
  NCSTRING procname;
  NI line;
  NCSTRING filename;
  NI16 len;
  NI16 calldepth;
  NI frameMsgLen;
};

#  define N_LIB_PRIVATE


extern NIM_THREADVAR TFrame * framePtr__system_3025;
N_LIB_PRIVATE NIM_THREADVAR TFrame* framePtr__system_3025;


int main(int argc, char ** argv) {
        printf("Hello\n");
}

This compiles and runs fine

@creikey
Copy link
Author

creikey commented Apr 13, 2022

MSVC compiler works with no issues

nim --threads:on r --cc:vcc hello.nim
Hint: used config file 'C:\Users\Cameron\.choosenim\toolchains\nim-1.6.4\config\nim.cfg' [Conf]
Hint: used config file 'C:\Users\Cameron\.choosenim\toolchains\nim-1.6.4\config\config.nims' [Conf]
.................................................................
CC: stdlib_digitsutils.nim
CC: stdlib_dollars.nim
CC: stdlib_sharedlist.nim
CC: stdlib_io.nim
CC: stdlib_system.nim
CC: hello.nim
stdlib_sharedlist.nim.c
stdlib_digitsutils.nim.c
stdlib_io.nim.c
@mhello.nim.c
stdlib_system.nim.c
stdlib_dollars.nim.c
Hint:  [Link]
Hint: gc: refc; threads: on; opt: none (DEBUG BUILD, `-d:release` generates faster code)
28676 lines; 5.999s; 31.648MiB peakmem; proj: C:\Users\Cameron\Documents\hello.nim; out: C:\Users\Cameron\nimcache\hello_d\hello_4121733DA6CB1D320C1A2E318F8C2FC0B9E0FB70.exe [SuccessX]
Hint: C:\Users\Cameron\nimcache\hello_d\hello_4121733DA6CB1D320C1A2E318F8C2FC0B9E0FB70.exe  [Exec]
Hello

@creikey
Copy link
Author

creikey commented Apr 14, 2022

It works on 1.6.0

@rockcavera
Copy link
Contributor

Does the error only happen if using gcc as a backend? Could you tell which gcc you use with: gcc -v.

If it's the mingw64 gcc provided by the nim website, try these others and see if the error persists:
https://github.com/jmeubank/tdm-gcc/releases/download/v10.3.0-tdm64-2/tdm64-gcc-10.3.0-2.exe
https://github.com/brechtsanders/winlibs_mingw/releases/download/11.2.0-10.0.0-msvcrt-r1/winlibs-x86_64-posix-seh-gcc-11.2.0-mingw-w64msvcrt-10.0.0-r1.7z

Also you can check with llvm/clang.

@rockcavera
Copy link
Contributor

rockcavera commented Apr 14, 2022

@creikey can you compile on 1.6.4 with --tlsEmulation:on and see if it works?

In 1.6.0, on Windows, it was standard to compile with --tlsEmulation:on. Not in 1.6.4.

@creikey
Copy link
Author

creikey commented Apr 15, 2022

@rockcavera it only happens when using gcc as a backend yes. I use the gcc shipped with choosenim, here is the gcc -v

C:\Users\Cameron\Documents>C:\Users\Cameron\.nimble\bin\gcc.exe -v
Using built-in specs.
COLLECT_GCC=C:\Users\Cameron\.choosenim\toolchains\mingw64\bin\gcc.exe
COLLECT_LTO_WRAPPER=c:/users/cameron/.choosenim/toolchains/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/11.1.0/lto-wrapper.exe
OFFLOAD_TARGET_NAMES=nvptx-none
Target: x86_64-w64-mingw32
Configured with: ../configure --prefix=/R/winlibs64_stage/inst_gcc-11.1.0/share/gcc --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --enable-offload-targets=nvptx-none --with-pkgversion='MinGW-W64 x86_64-posix-seh, built by Brecht Sanders' --with-tune=generic --enable-checking=release --enable-threads=posix --disable-sjlj-exceptions --disable-libunwind-exceptions --disable-serial-configure --disable-bootstrap --enable-host-shared --enable-plugin --disable-default-ssp --disable-rpath --enable-libstdcxx-pch --enable-libstdcxx-time=yes --disable-libstdcxx-debug --disable-version-specific-runtime-libs --with-stabs --disable-symvers --enable-languages=c,c++,fortran,lto,objc,obj-c++,d,jit --disable-gold --disable-nls --disable-stage1-checking --disable-win32-registry --disable-multilib --enable-ld --enable-libquadmath --enable-libada --enable-libssp --enable-libstdcxx --enable-lto --enable-fully-dynamic-string --enable-libgomp --enable-graphite --enable-mingw-wildcard --with-mpc=/d/Prog/winlibs64_stage/custombuilt --with-mpfr=/d/Prog/winlibs64_stage/custombuilt --with-gmp=/d/Prog/winlibs64_stage/custombuilt --with-isl=/d/Prog/winlibs64_stage/custombuilt --enable-install-libiberty --enable-__cxa_atexit --without-included-gettext --with-diagnostics-color=auto --enable-clocale=generic --with-libiconv --with-system-zlib --with-build-sysroot=/R/winlibs64_stage/gcc-11.1.0/build_mingw/mingw-w64 CFLAGS=-I/d/Prog/winlibs64_stage/custombuilt/include/libdl-win32
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 11.1.0 (MinGW-W64 x86_64-posix-seh, built by Brecht Sanders)

I tried tdm64 and it worked correctly without issues, like this:

import os

proc threadFunc {.thread.} =
  echo "From thread"

var myThread: Thread[void]
createThread(myThread, threadFunc)
sleep(500)

Compiles and prints "From thread"

Going back to the gcc which is broken, compiling with
nim --threads:on --tlsEmulation:on --listCmd --cc:env -f r hello.nim

Works! With the CC environment variable being

echo %CC%
C:\Users\Cameron\.nimble\bin\gcc.exe

Without --tlsEmulation:on , it still crashes, so that fixes it.

@creikey creikey changed the title When building 1.6.4 with threads: The application was unable to start correctly (0xc000007b). Click OK to close the application Windows gcc shipped with choosenim 1.6.4 with TLS emulation turned off : The application was unable to start correctly (0xc000007b). Click OK to close the application Apr 15, 2022
@creikey
Copy link
Author

creikey commented Apr 15, 2022

Why does tlsEmulation:off break on my config in windows? It seems like it doesn't for others. @xflywind can you try compiling hello world with nim --tlsEmulation:off --threads:on r -f hello.nim , and also where gcc to show where your gcc is from? For now I guess I will use the TDM compiler

@ringabout
Copy link
Member

ringabout commented Apr 15, 2022

where gcc
C:\Users\blue\Desktop\exe\mingw64\mingw64\bin\gcc.exe
gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=c:/users/blue/desktop/exe/mingw64/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/11.1.0/lto-wrapper.exe
OFFLOAD_TARGET_NAMES=nvptx-none
Target: x86_64-w64-mingw32
Configured with: ../configure --prefix=/R/winlibs64_stage/inst_gcc-11.1.0/share/gcc --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --enable-offload-targets=nvptx-none --with-pkgversion='MinGW-W64 x86_64-posix-seh, built by Brecht Sanders' --with-tune=generic --enable-checking=release --enable-threads=posix --disable-sjlj-exceptions --disable-libunwind-exceptions --disable-serial-configure --disable-bootstrap --enable-host-shared --enable-plugin --disable-default-ssp --disable-rpath --enable-libstdcxx-pch --enable-libstdcxx-time=yes --disable-libstdcxx-debug --disable-version-specific-runtime-libs --with-stabs --disable-symvers --enable-languages=c,c++,fortran,lto,objc,obj-c++,d,jit --disable-gold --disable-nls --disable-stage1-checking --disable-win32-registry --disable-multilib --enable-ld --enable-libquadmath --enable-libada --enable-libssp --enable-libstdcxx --enable-lto --enable-fully-dynamic-string --enable-libgomp --enable-graphite --enable-mingw-wildcard --with-mpc=/d/Prog/winlibs64_stage/custombuilt --with-mpfr=/d/Prog/winlibs64_stage/custombuilt --with-gmp=/d/Prog/winlibs64_stage/custombuilt --with-isl=/d/Prog/winlibs64_stage/custombuilt --enable-install-libiberty --enable-__cxa_atexit --without-included-gettext --with-diagnostics-color=auto --enable-clocale=generic --with-libiconv --with-system-zlib --with-build-sysroot=/R/winlibs64_stage/gcc-11.1.0/build_mingw/mingw-w64 CFLAGS=-I/d/Prog/winlibs64_stage/custombuilt/include/libdl-win32
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 11.1.0 (MinGW-W64 x86_64-posix-seh, built by Brecht Sanders)

--tlsEmulation:off/on doesn't affect the threads on my PC.

I use 21H2: 22000.556

@rockcavera
Copy link
Contributor

Why does tlsEmulation:off break on my config in windows? It seems like it doesn't for others. @xflywind can you try compiling hello world with nim --tlsEmulation:off --threads:on r -f hello.nim , and also where gcc to show where your gcc is from? For now I guess I will use the TDM compiler

That's a good question. I have no knowledge of how tlsEmulation works to answer you. But as it worked using tdm, I believe the mingw64 that nimble is installing, from winlibs.com, is linking some dll (maybe) that is corrupt.

I once had a big battle with mingw64 from winlibs.com, as it doesn't statically link to glibc (at least when compiling a dll). Until I figured out the problem, when I tested tdm, I wasted almost a week.

You could check between the executable with problem and the executable generated by tdm (which works without problem) the dlls that each one depends on with the Dependency Walker.

Here, unfortunately, on Windows 10, I couldn't reproduce the problem.

@creikey
Copy link
Author

creikey commented Apr 15, 2022

@xflywind
This isn't the gcc that ships with choosenim right?

@ringabout
Copy link
Member

Yeah, I installed it manually.

@ringabout
Copy link
Member

ringabout commented Aug 10, 2022

@creikey Hi, is this issue related to libwinthread.dll?

@creikey
Copy link
Author

creikey commented Aug 10, 2022

@creikey Hi, is this issue related to libwinthread.dll?

Yeah, I forgot I opened this issue but I figured out how to fix it for me, I added the bin folder in the choosenim mingw installation with the pthreads dll to my path and everything worked again. Windows is very helpful in not specifying at all what the problem is when you see an error like this. Nim should probably check for existence of the threads dll and warn the user if it can't find it instead of failing like this where it's not obvious what's wrong.

@dom96
Copy link
Contributor

dom96 commented Aug 14, 2022

This is a showstopper imo https://forum.nim-lang.org/t/9368. Seems to be a regression too?

@ringabout
Copy link
Member

Seems to be a regression too

After switching to --tlsEmulation:off on windows, Now Nim depends on linwinthread.dll on windows with mingw. The solution is to add mingw/bin to path.

@metagn
Copy link
Collaborator

metagn commented Aug 15, 2022

If we don't want an implicit dependency, maybe we should re-enable --tlsEmulation. #18146 was reopened.

@rockcavera
Copy link
Contributor

rockcavera commented Aug 15, 2022

If we don't want an implicit dependency, maybe we should re-enable --tlsEmulation. #18146 was reopened.

The problem actually lies with the mingw64 distribution that Nim uses, which prefers to dynamically link certain components. Depending on what you compile, there will even be a dependency on "libgcc_s_seh-1.dll", as that's what the maintainer of winlibs wanted.

I'm not saying that winlibs is wrong, but it's a behavior I don't like.

Edit: The problem has appeared in people who installed Nim with choosenim. Then choosenim should add to the Windows environment variable %PATH% the BIN folder of mingw64.

@ghost
Copy link

ghost commented Aug 15, 2022

As @rockcavera mentioned, there are some MinGW distributions that statically link winpthread and other similar libraries, such as https://jmeubank.github.io/tdm-gcc/

@dom96
Copy link
Contributor

dom96 commented Aug 15, 2022

Would be awesome for Nim to ship that.

@creikey
Copy link
Author

creikey commented Aug 16, 2022

If we don't want an implicit dependency, maybe we should re-enable --tlsEmulation. #18146 was reopened.

The problem actually lies with the mingw64 distribution that Nim uses, which prefers to dynamically link certain components. Depending on what you compile, there will even be a dependency on "libgcc_s_seh-1.dll", as that's what the maintainer of winlibs wanted.

I'm not saying that winlibs is wrong, but it's a behavior I don't like.

Edit: The problem has appeared in people who installed Nim with choosenim. Then choosenim should add to the Windows environment variable %PATH% the BIN folder of mingw64.

oh yeah I just realized the binaries I ship too need those dlls to work, that sucks

@dom96
Copy link
Contributor

dom96 commented Aug 17, 2022

For what it's worth, choosenim specifically installs everything into ~/.nimble/bin so that you only need to add that to your PATH. Choosenim also installs the DLLs in Nim's dlls.zip file (https://github.com/dom96/choosenim/blob/master/src/choosenimpkg/download.nim#L25) so maybe we should just recreate this zip with the required gcc DLLs? I'd rather avoid having to modify choosenim to extract DLLs from gcc and put them in ~/.nimble/bin if possible.

This is just a workaround though, I don't think it's ideal for all Windows programs to have this runtime dependency. How difficult would it be to statically link this?

@ringabout
Copy link
Member

I will have a try with https://jmeubank.github.io/tdm-gcc/ which @Yardanico suggests.

Araq pushed a commit that referenced this issue Sep 19, 2022
…config" (#19119) (#20327)

* Revert "Remove tlsEmulation enabled from Windows + GCC config (#19119) [backport:1.6]"

This reverts commit 77b696c.

* increase nimTlsSize to 48000

* enable for windows

* fixes tests

* fixes tlsEmulation:on
narimiran pushed a commit that referenced this issue Sep 19, 2022
…config" (#19119) (#20327)

* Revert "Remove tlsEmulation enabled from Windows + GCC config (#19119) [backport:1.6]"

This reverts commit 77b696c.

* increase nimTlsSize to 48000

* enable for windows

* fixes tests

* fixes tlsEmulation:on

(cherry picked from commit 97259a5)
capocasa pushed a commit to capocasa/Nim that referenced this issue Mar 31, 2023
…s + GCC config" (nim-lang#19119) (nim-lang#20327)

* Revert "Remove tlsEmulation enabled from Windows + GCC config (nim-lang#19119) [backport:1.6]"

This reverts commit 77b696c.

* increase nimTlsSize to 48000

* enable for windows

* fixes tests

* fixes tlsEmulation:on
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants