spdlog icon indicating copy to clipboard operation
spdlog copied to clipboard

Logger Stall - GCC 11.4 - External FMT - Debug configuration

Open tstrutz opened this issue 6 months ago • 1 comments

We have been encountering a problem where SPDLOG hangs within FMT when passed long double values. I don't know what is causing this as previously we used FMT without spdlog and it worked fine. This issue only occurs in Debug (CMake) configuration.

I would assume this is likely a bug. The issue can apparently be fixed by casting any long double values to double values.

Versions used: GCC: 11.4.0 C++ Standard: 20 FMT Version: 11.0.2 Spdlog version: 1.15.3

Log of where the hang occurs:

(gdb) thread 100
[Switching to thread 100 (Thread 0x7fffe0fe1640 (LWP 3757368))]
#0  0x00007ffff713c74f in fmt::v11::detail::bigint::remove_leading_zeros (this=0x7fffe0fdbfc0)
    at /home/tstrutz/development/my_project/build/vcpkg_installed/x64-linux/include/fmt/format.h:2756
2756        while (num_bigits > 0 && (*this)[num_bigits] == 0) --num_bigits;
(gdb) bt
#0  0x00007ffff713c74f in fmt::v11::detail::bigint::remove_leading_zeros (this=0x7fffe0fdbfc0)
    at /home/tstrutz/development/my_project/build/vcpkg_installed/x64-linux/include/fmt/format.h:2756
#1  fmt::v11::detail::bigint::subtract_aligned (other=..., this=0x7fffe0fdbfc0) at /home/tstrutz/development/my_project/build/vcpkg_installed/x64-linux/include/fmt/format.h:2769
#2  fmt::v11::detail::bigint::divmod_assign (divisor=..., this=<optimized out>) at /home/tstrutz/development/my_project/build/vcpkg_installed/x64-linux/include/fmt/format.h:2976
#3  fmt::v11::detail::bigint::divmod_assign (this=0x7fffe0fdbfc0, divisor=...) at /home/tstrutz/development/my_project/build/vcpkg_installed/x64-linux/include/fmt/format.h:2969
#4  0x00007ffff7d3cbe5 in fmt::v11::detail::format_dragon(fmt::v11::detail::basic_fp<unsigned __int128>, unsigned int, int, fmt::v11::detail::buffer<char>&, int&) (value=..., 
    flags=6, num_digits=6, buf=..., exp10=@0x7fffe0fdc308: -10) at /home/tstrutz/development/vcpkg/buildtrees/fmt/src/11.0.2-c30c0a133f.clean/include/fmt/format.h:3098
#5  0x00007ffff7d51e0f in fmt::v11::detail::format_float<long double> (value=2.70999999999999988796e-06, precision=10, specs=..., buf=...)
    at /home/tstrutz/development/vcpkg/buildtrees/fmt/src/11.0.2-c30c0a133f.clean/include/fmt/format.h:3522
#6  0x00007ffff7d4c3e3 in fmt::v11::detail::write_float<char, fmt::v11::basic_appender<char>, long double> (out=..., value=2.70999999999999988796e-06, specs=..., loc=...)
    at /home/tstrutz/development/vcpkg/buildtrees/fmt/src/11.0.2-c30c0a133f.clean/include/fmt/format.h:3580
#7  0x00007ffff7d470f6 in fmt::v11::detail::write<char, fmt::v11::basic_appender<char>, long double, 0> (out=..., value=2.70999999999999988796e-06, specs=..., loc=...)
    at /home/tstrutz/development/vcpkg/buildtrees/fmt/src/11.0.2-c30c0a133f.clean/include/fmt/format.h:3593
#8  0x00007ffff7d4481d in fmt::v11::detail::arg_formatter<char>::operator()<long double> (this=0x7fffe0fdc780, value=2.70999999999999988796e-06)
    at /home/tstrutz/development/vcpkg/buildtrees/fmt/src/11.0.2-c30c0a133f.clean/include/fmt/format.h:3747
#9  0x00007ffff7d42652 in fmt::v11::basic_format_arg<fmt::v11::context>::visit<fmt::v11::detail::arg_formatter<char> > (this=0x32e806d1, vis=...)
    at /home/tstrutz/development/vcpkg/buildtrees/fmt/src/11.0.2-c30c0a133f.clean/include/fmt/base.h:1804
#10 0x00007ffff7d40cfc in fmt::v11::detail::vformat_to<char>(fmt::v11::detail::buffer<char>&, fmt::v11::basic_string_view<char>, fmt::v11::detail::vformat_args<char>::type, fmt::v11::detail::locale_ref)::format_handler::on_format_specs(int, char const*, char const*) (this=0x7ffff7d60ff8, id=1, begin=0x7ffff7d60ff4 ".10f}", end=0x7ffff7d60ff9 "")
    at /home/tstrutz/development/vcpkg/buildtrees/fmt/src/11.0.2-c30c0a133f.clean/include/fmt/format.h:4278
#11 0x00007ffff7d44a25 in fmt::v11::detail::parse_replacement_field<char, fmt::v11::detail::vformat_to<char>(fmt::v11::detail::buffer<char>&, fmt::v11::basic_string_view<char>, fmt::v11::detail::vformat_args<char>::type, fmt::v11::detail::locale_ref)::format_handler&>(char const*, char const*, fmt::v11::detail::vformat_to<char>(fmt::v11::detail::buffer<char>&, fmt::v11::basic_string_view<char>, fmt::v11::detail::vformat_args<char>::type, fmt::v11::detail::locale_ref)::format_handler&) (
    begin=0x32e806d1 <error: Cannot access memory at address 0x32e806d1>, end=0x7ffff7d60ff9 "", handler=...)
    at /home/tstrutz/development/vcpkg/buildtrees/fmt/src/11.0.2-c30c0a133f.clean/include/fmt/base.h:2591
#12 0x00007ffff7d4289b in fmt::v11::detail::parse_format_string<false, char, fmt::v11::detail::vformat_to<char>(fmt::v11::detail::buffer<char>&, fmt::v11::basic_string_view<char>, fmt::v11::detail::vformat_args<char>::type, fmt::v11::detail::locale_ref)::format_handler>(fmt::v11::basic_string_view<char>, fmt::v11::detail::vformat_to<char>(fmt::v11::detail::buffer<char>&, fmt::v11::basic_string_view<char>, fmt::v11::detail::vformat_args<char>::type, fmt::v11::detail::locale_ref)::format_handler&&) (format_str=..., handler=...)
    at /home/tstrutz/development/vcpkg/buildtrees/fmt/src/11.0.2-c30c0a133f.clean/include/fmt/base.h:2647
#13 0x00007ffff7d3e9d2 in fmt::v11::detail::vformat_to<char> (buf=..., fmt=..., args=..., loc=...)
    at /home/tstrutz/development/vcpkg/buildtrees/fmt/src/11.0.2-c30c0a133f.clean/include/fmt/format.h:4285
#14 0x00007ffff6ff8b75 in fmt::v11::vformat_to<fmt::v11::basic_appender<char>, 0> (args=..., fmt=..., out=...)
    at /home/tstrutz/development/my_project/build/vcpkg_installed/x64-linux/include/fmt/base.h:1585
#15 spdlog::logger::log_<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, void const*, long double> (fmt=..., lvl=spdlog::level::debug, 
    loc=..., this=0x55555564c200) at /home/tstrutz/development/my_project/build/vcpkg_installed/x64-linux/include/spdlog/logger.h:328
--Type <RET> for more, q to quit, c to continue without paging--
#16 spdlog::logger::log<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, void const*, long double> (fmt=..., lvl=spdlog::level::debug, 
    loc=..., this=0x55555564c200) at /home/tstrutz/development/my_project/build/vcpkg_installed/x64-linux/include/spdlog/logger.h:80
#17 my_project::TriggerManager::nextTriggeredObject (this=this@entry=0x555555661a70) at /home/tstrutz/development/my_project/src/TriggerManager.cpp:212
#18 0x00007ffff71b7e97 in my_project::Simulation::triggerNextObject (this=this@entry=0x5555556618c0)
    at /home/tstrutz/development/my_project/src/configurable_objects/simulations/Simulation.cpp:322
#19 0x00007ffff71ca19a in my_project::SimulationFlatEarth::runSimulation (this=0x5555556618c0)
    at /home/tstrutz/development/my_project/src/configurable_objects/simulations/SimulationFlatEarth.cpp:80
#20 0x00007ffff71b9624 in my_project::Simulation::startSimulation (this=0x5555556618c0, simID=<optimized out>)
    at /home/tstrutz/development/my_project/src/configurable_objects/simulations/Simulation.cpp:268
#21 0x00007ffff71b9a92 in my_project::Simulation::startSimulationHandleException (this=<optimized out>, simID=<optimized out>, ep=...)
    at /home/tstrutz/development/my_project/src/configurable_objects/simulations/Simulation.cpp:238
#22 0x00007ffff69ea253 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#23 0x00007ffff6759ac3 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
#24 0x00007ffff67eb850 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
(gdb) 

Relevant code spdlog is calling:

    void TriggerableObject::printTableFormat(std::shared_ptr<spdlog::logger> logger, const std::string & prefix ) const
    {
        LOGGER_INFO(logger, "{} {:<40} Addr: {:<40} Trigger Time: {:<40} Update Rate: {:<40}",
                        prefix,
                        m_objectName,
                        fmt::ptr(this),
                        fmt::format( "{} (s)", m_nextTriggerTime ), // This is a long double
                        fmt::format( "{} (s)", m_requiredDeltaTime )); // This is also a long double


        for (auto child : m_children)
        {
            child->printTableFormat(logger, prefix + "\t");
        }
    }

Running the same code with fmt::print runs without issue.

NOTE: LOGGER_INFO is a simple macro redirection to SPDLOG_LOGGER_INFO:

#define LOGGER_INFO( logger, ...) \
         if ((logger) != nullptr) SPDLOG_LOGGER_INFO(logger,__VA_ARGS__)

tstrutz avatar Jun 20 '25 14:06 tstrutz

It looks like fmt::format() is formatting long double and the backtrace seems to stop at fmt::v11::detail::bigint::remove_leading_zeros. I don't think this is the spdlog problem.

Also, the latest version of fmt is 11.2.0.

tt4g avatar Jun 20 '25 21:06 tt4g