1

spdlog昨日、ログに使用する個人的なプロジェクトに組み込み始めました。これまでのところ、ライブラリのインクルードを機能させるのにいくつか問題がありましたが、それらは完全に解決されました。

これで、すべてが正常にコンパイルされ、すべてのヘッダーが見つかりましたが、ロガーを作成しようとしたり、単にコードをログに記録するためのパターンを設定したりすると、セグメンテーション違反でクラッシュします。spdlogより具体的には、プログラムで初めて名前空間からどの関数を呼び出しても、クラッシュが発生します。

次のように、(このspdlogレポに基づいて)からいくつかの部分を抽象化するクラスがあります。

//Logger.hpp
#ifndef TE_LOGGER_HPP
#define TE_LOGGER_HPP

#include <spdlog/spdlog.h>

namespace te {

class Logger {
public:
    static void Init();

    inline static std::shared_ptr<spdlog::logger> &getCoreLogger() {
        return sCoreLogger;
    }
    inline static std::shared_ptr<spdlog::logger> &getClientLogger() {
        return sClientLogger;
    }

private:
    static std::shared_ptr<spdlog::logger> sCoreLogger;
    static std::shared_ptr<spdlog::logger> sClientLogger;
};

}
#endif //TE_LOGGER_HPP

//Logger.cpp
#include "Logger.hpp"
#include <spdlog/sinks/stdout_color_sinks.h>

std::shared_ptr<spdlog::logger> te::Logger::sCoreLogger;
std::shared_ptr<spdlog::logger> te::Logger::sClientLogger;

void te::Logger::Init() {
    //The first of any of the following three lines cause a crash
    //no matter the order, regardless of the pattern used in set_pattern
    spdlog::set_pattern("%v");
    sCoreLogger = spdlog::stdout_color_mt("CORE");
    sClientLogger = spdlog::stdout_color_mt("CORE");

    sCoreLogger->set_level(spdlog::level::trace);
    sClientLogger->set_level(spdlog::level::trace);
}

スタック トレースから、何らかの理由でライブラリ内のどこかに設定されているformatterクラスに問題があるようです。最新の CLion である C++14 を使用しています (spdlog が C++11 であることは認識していますが、14 以降の機能が必要であり、-std=c++11 を設定しても問題は解決しません)。そして、 Ubuntu 18.04 上の昨日の最新バージョン(GitHub リポジトリから直接取得)。spdlognullspdlog

編集:コメントのリクエストに従って、小さなプロジェクトを作成しました(単一のcppファイル、実際のプロジェクトで行う方法、またはファイルから参照され、それに応じてリンクさspdlogれた実際のプロジェクトと同じコードとライブラリのセットアップを含めますmain.cpp) 問題を再現することを目的としており、ここに私の調査結果があります: *spdlog実行可能ファイルで直接使用する場合、問題は存在しません * Logger クラスが共有ライブラリに移動され、そこからリンクされている場合、問題は存在します

これが私が得ているエラーメッセージです:

Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

そして、私が使用している CMakeLists.txt ファイル (現在、CLion は VS のように「同じソリューション内の複数のプロジェクト」をサポートしていないため、ライブラリのファイルをプロジェクトにネストしています): #CMakeLists.txt for Library cmake_minimum_required(VERSION 3.10 FATAL_ERROR)

project(TokenEngine VERSION 0.0.1 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 14)

set(SOURCE_FILES src/Application.cpp src/Application.hpp src/EntryPoint.hpp src/Logger.cpp src/Logger.hpp)

#include_directories("${CMAKE_CURRENT_SOURCE_DIR}/libs/")
add_library(TokenEngine SHARED ${SOURCE_FILES})

target_include_directories(TokenEngine PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/libs/spdlog-1.x/include")

#Expose the public API of the engine to any project that might use it
target_include_directories(TokenEngine PUBLIC include)

#CMakeLists.txt for top level project
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")

add_definitions(-DTE_PLATFORM_LINUX)

project(Build CXX)

add_subdirectory(TokenEngine)
add_subdirectory(Sandbox)
4

2 に答える 2

1

おそらく問題は、spdlog の静的オブジェクトが 2 回定義されていることです。共有ライブラリ内と、ロガー ヘッダー (spdlog.h を含む) を含むクライアント コードからです。

ヘッダー ファイルから spdlog.h へのインクルードを削除し (代わりに spdlog::logger の前方宣言を使用)、Logger.cpp ファイルからのみ spdlog.h をインクルードしてください。

編集

spdlog::logger は、コンパイル単位の境界を越えて前方宣言することはできません。解決策は、logger.cpp で定義された単純なクラスでロガーをラップし、logger.h でのみエクスポートすることです。

于 2018-11-14T21:52:50.780 に答える