Error: undefined symbol: ___chkstk_ms (original) (raw)

I’m trying to build an existing application that previously was built with MinGW 32-bit… I’m using this version of clang++

D:\SourceCode\Git\media_list Yes, Master?? > D:\clang\bin\g++ --version
clang version 20.1.5 (GitHub - llvm/llvm-project: The LLVM Project is a collection of modular and reusable compiler and toolchain technologies. 7b09d7b446383b71b63d429b21ee45ba389c5134)
Target: i686-w64-windows-gnu
Thread model: posix
InstalledDir: D:/clang/bin
Configuration file: D:/clang/bin/i686-w64-windows-gnu.cfg

I had experimented with smaller projects (none using explicit linker), and clang g++ worked exactly as MinGW g++ … but in my current application, I got this error:

D:\SourceCode\Git\media_list Yes, Master?? > make clean all
rm -f *.o *.exe *~ *.zip
D:\clang\bin\g++ -Wall -O3 -c -Weffc++ -Wno-write-strings -DUNICODE -D_UNICODE -Ider_libs -c media_list.cpp -o media_list.o
D:\clang\bin\g++ -Wall -O3 -c -Weffc++ -Wno-write-strings -DUNICODE -D_UNICODE -Ider_libs -c ext_lookup.cpp -o ext_lookup.o
D:\clang\bin\g++ -Wall -O3 -c -Weffc++ -Wno-write-strings -DUNICODE -D_UNICODE -Ider_libs -c file_fmts.cpp -o file_fmts.o
D:\clang\bin\g++ -Wall -O3 -c -Weffc++ -Wno-write-strings -DUNICODE -D_UNICODE -Ider_libs -c conio_min.cpp -o conio_min.o
D:\clang\bin\g++ -Wall -O3 -c -DUNICODE -D_UNICODE -Ider_libs -c MediaInfoDll.cxx -o MediaInfoDll.o
D:\clang\bin\g++ media_list.o ext_lookup.o file_fmts.o conio_min.o der_libs\common_funcs.o der_libs\common_win.o der_libs\qualify.o MediaInfoDll.o -s -O3 -dUNICODE -d_UNICODE -o MediaList.exe -lshlwapi -lgdi32 -lcomdlg32
ld.lld: error: undefined symbol: ___chkstk_ms

referenced by der_libs\common_funcs.o:(.text)
referenced by der_libs\common_funcs.o:(syslog(wchar_t const*, …))
clang-20: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [MediaList.exe] Error 1

Is there any way to resolve this??
As far as I know, this project is not using any third-party libraries…

Gorlash June 5, 2025, 12:02am 2

just for completeness, here is the syslog() function which is referenced in that error message:

int syslog(const TCHAR *fmt, …)
{
TCHAR consoleBuffer[3000] ;
va_list al; //lint !e522

va_start(al, fmt); //lint !e1055 !e530
_vstprintf(consoleBuffer, fmt, al); //lint !e64
OutputDebugString(consoleBuffer) ;
va_end(al);
return 1;
}

Gorlash June 5, 2025, 4:58pm 3

BTW, I resolved this linker error by defining the following function in my module:

#ifdef USING_CLANG
void ___chkstk_ms(void)
{

}
#endif

That allowed me to get the the project to build, and the program appears to work properly… Are there any hidden surprises that might leap out at me as a result of this hack ??

___chkstk_ms is supposed to implement stack probing: accessing the stack once for every 4KB allocated so you don’t skip over the guard page on the stack. If you skip probing, you might get a crash. (A closer look at the stack guard page - The Old New Thing has a description of how this works.)

The static library that provides ___chkstk_ms is supposed to get linked in automatically if you’re targeting MinGW; not sure why that isn’t working for you.

Well, I got this distribution from this website:

Perhaps that site didn’t build correctly??

I went here because I wanted an i686 gnu build, which the default distribution site didn’t have… it did have a
clang+llvm-18.1.8-x86_64-pc-windows-msvc
distribution, but that dist didn’t have g++.exe/gcc.exe , so wasn’t sure that was equivalent…

Can you add -v to the linking command (D:\clang\bin\g++ media_list.o ext_lookup.o file_fmts.o conio_min.o der_libs\common_funcs.o der_libs\common_win.o der_libs\qualify.o MediaInfoDll.o -s -O3 -dUNICODE -d_UNICODE -o MediaList.exe -lshlwapi -lgdi32 -lcomdlg32) to let it print out more exactly what it tells the linker to do.

The symbol ___chkstk_ms sure is available, in the x86_64 version of the compiler-rt builtins library. (Common sources of this issue would be if linking with -nostdlib or similar, and failing to add the right libraries. This can happen with libtool due to a longstanding issue there - but this case doesn’t seem to have libtool or -nostdlib involved.)

However, if you’re building things in i686 mode, then you wouldn’t be getting references to ___chkstk_ms, then you should be getting references to __alloca instead; the stack probe function has different names between the architectures (see Compiler Explorer as example). But then again, if you would be mixing in object files of inconsistent architectures, the linker would complain about that as well.

Gorlash June 6, 2025, 1:28pm 7

Here is the linker output with -v included:

D:\clang\bin\g++ media_list.o ext_lookup.o file_fmts.o conio_min.o der_libs\common_funcs.o der_libs\common_win.o der_libs\qualify.o  MediaInfoDll.o  -s -O3 -v -dUNICODE -d_UNICODE -o MediaList.exe -lshlwapi -lgdi32 -lcomdlg32
clang version 20.1.6 (https://github.com/llvm/llvm-project.git 47addd4540b4c393e478ba92bea2589e330c57fb)
Target: i686-w64-windows-gnu
Thread model: posix
InstalledDir: D:/clang/bin
Configuration file: D:/clang/bin/i686-w64-windows-gnu.cfg
 "D:/clang/bin/ld.lld" -s -m i386pe -Bdynamic -o MediaList.exe -s D:/clang/i686-w64-mingw32/lib/crt2.o D:/clang/i686-w64-mingw32/lib/crtbegin.o -LD:/clang/i686-w64-mingw32/lib -LD:/clang/i686-w64-mingw32/mingw/lib -LD:/clang/lib -LD:/clang/lib/clang/20/lib/windows media_list.o ext_lookup.o file_fmts.o conio_min.o "der_libs\\common_funcs.o" "der_libs\\common_win.o" "der_libs\\qualify.o" MediaInfoDll.o -lshlwapi -lgdi32 -lcomdlg32 -lc++ -lmingw32 D:/clang/lib/clang/20/lib/windows/libclang_rt.builtins-i386.a -lunwind -lmoldname -lmingwex -lmsvcrt -ladvapi32 -lshell32 -luser32 -lkernel32 -lmingw32 D:/clang/lib/clang/20/lib/windows/libclang_rt.builtins-i386.a -lunwind -lmoldname -lmingwex -lmsvcrt -lkernel32 D:/clang/i686-w64-mingw32/lib/crtend.o
ld.lld: error: undefined symbol: ___chkstk_ms
>>> referenced by der_libs\common_funcs.o:(.text)
>>> referenced by der_libs\common_funcs.o:(syslog(wchar_t const*, ...))
clang-20: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [MediaList.exe] Error 1

as for what version I have, I’m definitely beginning to suspect that the package that I got from mstorsjo (linked above) is not valid, but I don’t know where else to get that specific package from, and I really don’t want to deal with building the whole thing myself!!

I also had another issue with that package; I tried building a Windows app (this one is a console app), and got an error message from windres, about my .rc files which no other package has had any issue with… I didn’t bother posting about that error, as I’m waiting to see how this discussion resolves first…

That’s definitely not the right conclusion here - that toolchain is quite ok. (I’m the one who maintains it.)

So it is linking in i686 mode, but for some unknown reason you end up with an undefined reference to ___chkstk_ms - in der_libs\common_funcs.o. But you shouldn’t be getting a reference to that symbol in an i686 build, only in an x86_64 build.

My suspicion is that something in the source itself produces this reference to ___chkstk_ms, which isn’t something you can assume to exist in an i686 build. (Although with libgcc, both variants of stack probe functions are available in both architectures, even if the “wrong” ones are entirely unused normally.)

Can you provide a way to reproduce your der_libs\common_funcs.o? Can you show the command that builds that file, plus the source files? Ideally for someone else to reproduce it, they’d need all transitive headers etc. But it’s possible to reproduce building the object file if you produce the preprocessed output from it, making it standalone. So from a command like cc <lots of options> -c source.c -o source.o, change it into cc <lots of options> -E source.c -o source-preproc.c. Then upload source-preproc.c somewhere where someone can fetch it and reproduce building it.

This toolchain uses llvm-rc/llvm-windres, which can be a bit more picky about unusual inputs than GNU windres or MS rc.exe - please file an issue for that on GitHub · Where software is built if it can be reproduced neatly.

Okay, first step:
common_funcs.cpp is in my der_libs library; in this case, it is being used used by my media_list utility… both are free software on my github page:

you can clone the package using (note --recursive to get der_libs submodule):
git clone GitHub - DerellLicht/media_list --recursive
then just build using ‘make’ …
You’ll probably have to update the path to the toolchain in Makefile…

Although, if you just want that one debug file, I can generate that too!!
I’ll get back to you in a little while…

Gorlash June 6, 2025, 2:48pm 10

NEVERMIND !!!
I figured out what was wrong…
I had my ‘clean’ label defined wrong, so it wasn’t deleting object files in the der_libs submodule … meaning that as I was experimenting with different toolchains (32-bit and 64-bit), I was leaving obsolete object files in der_libs - which includes common_funcs.o … I thought I had updated the clean labels in all my projects, long ago, but apparently not…

Now that I corrected the Makefile so that it cleans the submodule as well, the clang package is working fine !!!

Sorry for the confusion!!!

Ok, thanks, that explains it! Yes that was also one of my hunches here - although I’m surprised that the linker doesn’t straight out error out when mixing architectures. But that’s on us to try to figure out why :slight_smile:

Gorlash June 7, 2025, 1:25pm 12

This toolchain uses llvm-rc/llvm-windres, which can be a bit more picky about unusual inputs than GNU windres or MS rc.exe - please file an issue for that on GitHub · Where software is built if it can be reproduced neatly.

BTW, I did post the windres issue over on that github page…
That issue was not related to this one, and was not involved in the .o confusion.