-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
First call to spdlog crashes process in Windows Release build #3212
Comments
I'm using spdlog 1.14.1 x64-windows from vcpkg |
As far as I can see from the log, the project is a debug build. spdlog crashes if it is a release build, because in C++, release builds and debug builds cannot be used together. |
It seems that vcpkg builds spdlog and fmt and generates |
The CMake log output was VS Code output for a Debug build. When selecting a release build the variables and appropriate dlls are all correct. The release and debug builds start fine run in a command window or even when run from
It's just when the process is started from a jvm with ProcessBuilder that I get the problem It works fine from the Kotlin multiplatform project when using I can only think that it is some incompatibility with how the ProcessBulder handles the IO streams and spdlog but I'm not really sure what to try next. https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ProcessBuilder.html I've tried various combinations of
with Redirect PIPE, INHERIT or DISCARD but nothing seems to work for me. |
Release and debug builds cannot be used together. I can't even isolate the problem due to using vcpkg and Kotlin. |
OK. Maybe I wasn't being clear. I use VS Code with Cmake to build a release build or a debug build of TimerLog.exe. Changing the config wipes the previous build files and re-creates the apropriate exe and dlls. It's this output that I referred to as Release or Debug for the C++ process. Both the Release and Debug versions work fine stand alone or even when started using the same mechanism as ProcessBuilder i.e. cmd /c start "" /wait C:\prog\SpdLogTest\build\TimerLog.exe The kotlin / Java jvm is required because the issue is down to the incompatibility of the ProcessBuilder started process with spdlog but then only when built as Release and a kotlin ReleaseDistribution. I guess it is something to do with the way the input, output and error streams are plumbed through to the process but don't really know where to look. I can try using the latest header only spdlog to take vcpkg out of the equation. |
Thank you for your detailed explanation. I understand the situation very well. Thank you. Then we should consider that there is a problem with See also;
And See: |
Other means of isolating the cause that I can think of are as follows:
|
OK Thanks for the suggestions: Environment variables. Built in commands work OK as does the TimerLog process with calls to std::cout instead of spdlog. Stop redirecting output. I shall try spdlog built from headers as I guess this gets round the need for spdlog.dll and fmt.dll to be present and loadable. |
I was thinking, contrary to you, that Kotlin may not be getting the environment variables of the current process correct. This is because the
|
You can |
You may try val process = Runtime.getRuntime().exec("cmd /C start", \"MyTitle\" \"C:/prog/SpdLogTest/TimerLog/build/TimerLog.exe\""); |
OK. I've taken a snapshot of the spdlog repository head and rebuilt TimerLog.exe using headers only to overcome any dll issues. I've also tried: I'm still getting exactly the same symptoms. i.e. fails with Release TimerLog.exe and createDistributable ProcessBldrTest. It works fine with any other combinations containing one of, i.e. No usage of spdlog, OR Debug build of TimerLog.exe OR ./gradlew run ProcessBldrTest. No I have the spdlog source code, I'll try adding some printf to see if I can isolate what is causing the incompatibility. Thanks for your help so far. |
Some progress. It is failing when it tries to acquire the lock at line 56 of wincolor_sink-in.h in the subroutine below: template <typename ConsoleMutex>
void SPDLOG_INLINE wincolor_sink<ConsoleMutex>::log(const details::log_msg &msg) {
if (out_handle_ == nullptr || out_handle_ == INVALID_HANDLE_VALUE) {
return;
}
std::lock_guard<mutex_t> lock(mutex_);
msg.color_range_start = 0;
msg.color_range_end = 0;
memory_buf_t formatted;
formatter_->format(msg, formatted);
if (should_do_colors_ && msg.color_range_end > msg.color_range_start) {
// before color range
print_range_(formatted, 0, msg.color_range_start);
// in color range
auto orig_attribs =
static_cast<WORD>(set_foreground_color_(colors_[static_cast<size_t>(msg.level)]));
print_range_(formatted, msg.color_range_start, msg.color_range_end);
// reset to orig colors
::SetConsoleTextAttribute(static_cast<HANDLE>(out_handle_), orig_attribs);
print_range_(formatted, msg.color_range_end, formatted.size());
} else // print without colors if color range is invalid (or color is disabled)
{
write_to_file_(formatted);
}
} If I comment this line out (obviously not appropriate as a workaround) it all works fine. |
Hmmm, if See:
However, this problem is 100% reproducible, and it is odd that it only crashes when the process is run from Kotlin. |
You're a star!!! Yes, strange that it only manifested with a specific set of conditions, but I've tested with and without a few times now and it does appear fixed. I'm sure this esoteric bug must be causing all sorts of hard to diagnose problems out there. Thanks again for your help. spdlog is my goto logging library for C/C++. I love the simplicity of the fmt library too. |
Oh, I had no idea that was the cause. Anyway I'm glad your problem is solved. |
A bit more explanation as to why it fails only with ./gradlew runDistribution and works as standalone: This gradle taks packages the whole Kotlin App with a JVM and all the necessary dlls to run independently on its own. This includes an out of date version of the MS VC redistributable dlls, in my case MSVCP140.dll v 14.29.30135.0. In order to run without the _DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR you need the latest version of the MS VC redistributables, currently version 14.40.33816.0. I'll try updating my Java JDK and see if it fixes it without requiring the compiler flag. |
Can't find a JDK that packages the latest VC redistributables. :-( |
Raised as JDK bug: https://bugs.java.com/bugdatabase/view_bug?bug_id=JDK-8342299 |
A rather weird one that I have investigated about as far as I can.
I have a simple C++ process that I would like to start from a Kotlin Desktop App.
The C++ is just
This C++ exe process is started from kotlin using:
This crashes the process on the first call to spdlog but only if I build the C++ in Release mode and run the kotlin as runDistributable or runReleaseDistributable. If I build the C++ as Debug or run the Kotlin in the IDE as Run it works as expected.
Maybe some sort of timing issue / race condition?
I'm running on a 13th Gen Intel(R) Core(TM) i7-13700K 3.40 GHz under Windows 11 Pro using the Visual Studio Community 2022 Release compiler for amd64 kit. I've attached the CMake project for the C++ process. The Kotlin project can be created by going to https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-multiplatform-create-first-app.html and selecting just Desktop. Then paste the kotlin code above into the desktop main.kt just before the Window call.
Any ideas where to go form here?
SpdLogTest.zip
CMake config is
The text was updated successfully, but these errors were encountered: