Closed KunMengcode closed 8 months ago
It is thought that release builds and debug builds are mixed, or that the application and spdlog have different compile options.
@tt4g Indeed, release build and debug build are mixed, But the new problems I'm facing now.
#0 0x00005555555943f5 in spdlog::logger::sink_it_(spdlog::details::log_msg const&) ()
#1 0x000055555561f891 in spdlog::logger::log(spdlog::source_loc, spdlog::level::level_enum, fmt::v9::basic_string_view<char>) ()
#2 0x0000555555571c70 in main ()
Toolchain during Windows compilation : CMake+MSbuild Toolchain during Linux compilation : CMake+make+gcc
Previously, my main program used - D CMAKE_ BUILD_ TYPE=RELEASE
and spdlog did not use this option.
Just now I also set spdlog to - D CMAKE_ BUILD_ TYPE=RELEASE
.
Are there any other aspects of my build configuration that I haven't noticed? I think Windows and Linux should be similar at the moment
If there is already spdlog installed on the Linux system, the built spdlog may not be loaded.
I did not install spdlog in the system.Could it be because I didn't install something like libfmt9 for compilation?
fmt library does not need to be installed on the system, because spdlog uses the bundled fmt unless the CMake variable SPDLOG_FMT_EXTERNAL
is specified.
Do you have a different version of fmt installed on your system than the one bundled with spdlog?
I did not specify SPDLOG FMT INTERNATIONAL
If so, the cause is unpredictable. The only thing I can think of is that there is a symbol in the Linux machine that causes a segmentation fault, or you are passing a dangling pointer to spdlog.
The code for initializing 'spdlog:: logger' is as follows. Is there a problem with this type of writing?
LogOutput::LogOutput(std::string instance, LogConfiguration LogConfig)
{
auto console_sink = std::make_shared<spdlog::sinks::stdout_sink_st>();
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_st>(LogConfig.fileOut_v, false);
auto null_sink = std::make_shared<spdlog::sinks::null_sink_st>();
console_sink->set_level(spdlog::level::level_enum(LogConfig.level_v));
file_sink->set_level(spdlog::level::level_enum(LogConfig.level_v));
console_sink->set_pattern(LogConfig.pattern_v);
file_sink->set_pattern(LogConfig.pattern_v);
spdlog::sinks_init_list sink_list;
switch (LogConfig.sink_v)
{
case 0:
sink_list = { console_sink };
break;
case 1:
sink_list = { file_sink };
break;
case 2:
sink_list = { file_sink, console_sink };
break;
case 3:
sink_list = { null_sink };
break;
}
log_sink = new spdlog::logger(instance, sink_list.begin(), sink_list.end());
log_sink->flush_on(spdlog::level::info);
}
I don't think it has anything to do with the logger initialization process, since what is crashing is the process of writing logs.
case 0 , 1 and 3 . can all be correctly output in the console or file.
Only sink_list = { file_sink, console_sink };
An error has occurred.
spdlog::sinks_init_list
is the alias of std::initializer_list<spdlog::sink_ptr>
.
As far as I can see from the cppreference (https://en.cppreference.com/w/cpp/utility/initializer_list), std::initializer_list
cannot be copy assigned.
Your program may have undefined behavior because it compiles code that is not in the C++ standard.
You should use std::vector<spdlog::sink_ptr>
.
Oh , oh , oh , oh , oh !
I changed the switch
code snippet and the program resumed normal operation
switch (LogConfig.sink_v)
{
case 0:
log_sink = new spdlog::logger(instance, {console_sink});
break;
case 1:
log_sink = new spdlog::logger(instance, {file_sink});
break;
case 2:
log_sink = new spdlog::logger(instance, {file_sink, console_sink});
break;
case 3:
log_sink = new spdlog::logger(instance, {null_sink});
break;
}
Deleted spdlog::sinks_init_list sink_list;
But I think what I wrote is the same, which is very puzzling
Thank you for answering this question for me .
This method is available in MSVC.(sink_list = { file_sink, console_sink };
)
MSVC may have done something in initializer_list
.
Different platforms have produced different results.
OS :Ubuntu 24.04 GCC:gcc version 13.2.0 (Ubuntu 13.2.0-9ubuntu1)