Nim
Nim copied to clipboard
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
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
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
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
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
?
Yeah, I testsed with --threads:on
echo "hello"
doAssert compileOption("threads")
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...
You could use --listCmd
to see the call to your C compiler and see if anything doesn't make sense.
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
Diffing the generated C with threads on (left) vs threads off (right)
This is the only difference in hello.c (from hello.nim)
Similar results in the standard library compiled C
NIM_THREADVAR is just this
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
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
It works on 1.6.0
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.
@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.
@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.
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
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
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 alsowhere 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.
@xflywind This isn't the gcc that ships with choosenim right?
Yeah, I installed it manually.
@creikey Hi, is this issue related to libwinthread.dll?
@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.
This is a showstopper imo https://forum.nim-lang.org/t/9368. Seems to be a regression too?
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.
If we don't want an implicit dependency, maybe we should re-enable --tlsEmulation. #18146 was reopened.
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.
As @rockcavera mentioned, there are some MinGW distributions that statically link winpthread and other similar libraries, such as https://jmeubank.github.io/tdm-gcc/
Would be awesome for Nim to ship that.
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
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?
I will have a try with https://jmeubank.github.io/tdm-gcc/
which @Yardanico suggests.