segfault 由在 file_event_handlers 回调中调用 spdlog::get( “logger” )->info() 引起

huangapple go评论64阅读模式
英文:

segfault caused by a call to spdlog::get( "logger" )->info() in a file_event_handlers's callback

问题

以下是您要翻译的内容:

"以下程序由于段错误而崩溃。我找不到原因。我现在知道的是,两次对info()成员spdlog::get("basic_logger")->info("\nLogging started...");spdlog::get("basic_logger")->info("Logging finished.");的调用都引起了问题(第一个引发了段错误,第二个引发了双重释放)。

一个最小的示例:

#include <chrono>
#include <exception>
#include <cstdio>
#include <fmt/core.h>
#include <fmt/chrono.h>
#include <spdlog/spdlog.h>
#include <spdlog/sinks/basic_file_sink.h>

int main()
{
    spdlog::file_event_handlers handlers;

    handlers.after_open = [](const spdlog::filename_t filename, std::FILE* const stream)
    {
        // Comment this line out to see the error caused by the before_close callback
        spdlog::get("basic_logger")->info("\nLogging started...");
        fmt::print(stream, "\n[{}] [{}] Logging started...\n",
            std::chrono::system_clock::now(), filename);
    };

    handlers.before_close = [](const spdlog::filename_t filename, std::FILE* const stream)
    {
        spdlog::get("basic_logger")->info("Logging finished.");
        fmt::print(stream, "[{}] [{}] Logging finished.\n",
            std::chrono::system_clock::now(), filename);
    };

    try
    {
        auto logger = spdlog::basic_logger_st("basic_logger", "logs/basic-log.txt", true, handlers);
    }
    catch (const std::exception& sx)
    {
        fmt::print(stderr, "\nSomething went wrong during program startup: log file init failed: {}\n\n",
            sx.what());
    }
}

错误信息:

Segmentation fault (core dumped)

还有:

free(): double free detected in tcache 2
Aborted (core dumped)

构建命令:

g++ -std=c++23 -O3 -march=westmere -Wall -Wextra -Wpedantic -Wconversion -Wsign-conversion -Wshadow -fwhole-program -DNDEBUG `pkg-config --cflags spdlog` `pkg-config --libs spdlog` Temp.cpp -o runTemp

尽管print的调用没有引起任何问题,但我想用上面所示的info()调用替换它们,因为它记录了更多细节。"

英文:

The below program crashes due to a seg fault. I don't find a reason for this. All I know at the moment is that the two calls to info() member spdlog::get( &quot;basic_logger&quot; )-&gt;info( &quot;\nLogging started...&quot; ); and spdlog::get( &quot;basic_logger&quot; )-&gt;info( &quot;Logging finished.&quot; ); are causing problems (the first one causes a segfault and the second one causes a double free).

A minimal example:

#include &lt;chrono&gt;
#include &lt;exception&gt;
#include &lt;cstdio&gt;
#include &lt;fmt/core.h&gt;
#include &lt;fmt/chrono.h&gt;
#include &lt;spdlog/spdlog.h&gt;
#include &lt;spdlog/sinks/basic_file_sink.h&gt;


int main( )
{
    spdlog::file_event_handlers handlers;

    handlers.after_open   = [ ]( const spdlog::filename_t filename, std::FILE* const stream )
                            {   // Comment this line out to see the error caused by the before_close callback
                                spdlog::get( &quot;basic_logger&quot; )-&gt;info( &quot;\nLogging started...&quot; );
                                fmt::print( stream, &quot;\n[{}] [{}] Logging started...\n&quot;,
                                            std::chrono::system_clock::now( ), filename );
                            };

    handlers.before_close = [ ]( const spdlog::filename_t filename, std::FILE* const stream )
                            {
                                spdlog::get( &quot;basic_logger&quot; )-&gt;info( &quot;Logging finished.&quot; );
                                fmt::print( stream, &quot;[{}] [{}] Logging finished.\n&quot;,
                                            std::chrono::system_clock::now( ), filename );
                            };

    try
    {
        auto logger { spdlog::basic_logger_st( &quot;basic_logger&quot;, &quot;logs/basic-log.txt&quot;, true, handlers ) };
    }
    catch ( const std::exception&amp; sx )
    {
        fmt::print( stderr, &quot;\nSomething went wrong during program startup: log file init failed: {}\n\n&quot;,
                            sx.what( ) );
    }
}

The errors:

Segmentation fault (core dumped)

And also:

free(): double free detected in tcache 2
Aborted (core dumped)

Build command:

g++ -std=c++23 -O3 -march=westmere -Wall -Wextra -Wpedantic -Wconversion -Wsign-conversion -Wshadow -fwhole-program -DNDEBUG `pkg-config --cflags spdlog` `pkg-config --libs spdlog` Temp.cpp -o runTemp

The calls to print are not causing any issues though. However, I want to replace them with calls to info() as seen above because that logs more details.

答案1

得分: 1

你试图做的事情很遗憾不可能。不幸的是,你对 spdlog::basic_logger_st 的调用最终在 此处 结束:

    static std::shared_ptr&lt;spdlog::logger&gt; create(std::string logger_name, SinkArgs &amp;&amp;... args)
    {
/*[1]*/ auto sink = std::make_shared&lt;Sink&gt;(std::forward&lt;SinkArgs&gt;(args)...);
        auto new_logger = std::make_shared&lt;spdlog::logger&gt;(std::move(logger_name), std::move(sink));
/*[2]*/ details::registry::instance().initialize_logger(new_logger);
        return new_logger;
    }

标记为 [1] 的那行代码是创建 sink 并调用你的 after_open 回调的代码,但 [2] 行实际上是将 logger 作为 basic_logger 可用的代码。

你将不得不将 after_open 中的日志语句提升到对 basic_logger_st 的调用之后。before_close 中的日志语句应该可以正常工作。

英文:

What you are trying to do is not possible, unfortunately. Your call to spdlog::basic_logger_st ends up here:

    static std::shared_ptr&lt;spdlog::logger&gt; create(std::string logger_name, SinkArgs &amp;&amp;... args)
    {
/*[1]*/ auto sink = std::make_shared&lt;Sink&gt;(std::forward&lt;SinkArgs&gt;(args)...);
        auto new_logger = std::make_shared&lt;spdlog::logger&gt;(std::move(logger_name), std::move(sink));
/*[2]*/ details::registry::instance().initialize_logger(new_logger);
        return new_logger;
    }

The line marked with [1] is the one that creates the sink and calls your after_open callback, but line [2] is actually the one that makes the logger available as basic_logger.

You will have to hoist the log statement in after_open to the line after your call to basic_logger_st. The log statement in before_close should work without a problem.

huangapple
  • 本文由 发表于 2023年5月10日 19:14:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/76217733.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定