сбой spdlog на заводских методах - PullRequest
0 голосов
/ 14 ноября 2018

Вчера я начал включать spdlog в мой личный проект, чтобы использовать его для регистрации.До сих пор у меня были некоторые проблемы с включением работы библиотеки, но теперь они полностью решены.

Теперь все прекрасно компилируется, однако все заголовки обнаруживаются, когда я пытаюсь создать регистраторы или просто установить шаблон для ведения журнала.код падает с ошибкой сегментации.Более конкретно, независимо от того, какую функцию я вызываю из пространства имен spdlog в первый раз в программе, происходит сбой.

У меня есть класс, абстрагирующий некоторые части от spdlog (основанный на this repo) следующим образом:

//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 в spdlog по какой-то причине установлен в null где-то внутри библиотеки.Я использую последний CLion, C ++ 14 (я знаю, что spdlog - это C ++ 11, но мне нужны возможности, начиная с 14, а также установка -std = c ++ 11 не решает проблему)и последняя версия spdlog от вчерашнего дня (вытащенная прямо из их репозитория GitHub) в Ubuntu 18.04.

РЕДАКТИРОВАТЬ: согласно запросу в комментариях я создал небольшой проект (один файл cpp, включающийspdlog как я делаю в реальном проекте или в той же настройке кода и библиотеки, что и в реальном проекте, указанном в файле main.cpp и связанном с ним), целью которого является воспроизведение проблемы, и вот мои выводы:проблема отсутствует, когда я использую spdlog непосредственно в исполняемом файле * проблема возникает, если класс Logger перемещен в общую библиотеку и связан с ней

Вот сообщение об ошибке, которое я получаю:

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

И файлы CMakeLists.txt, которые я использую (я вкладываю один файл библиотеки в проект, поскольку на данный момент CLion не поддерживает "несколько проектов в одном решении", как, например, VS): # CMakeLists.txt для библиотеки 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)

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

Возможно, проблема в том, что статические объекты spdlog определяются дважды - из общей библиотеки и из клиентского кода, который включает заголовок вашего регистратора (в том числе spdlog.h).

Попробуйте удалить файл include to spdlog.h из файла заголовка и (и вместо этого использовать прямое объявление spdlog :: logger) и включить файл spdlog.h только из файла Logger.cpp.

Редактировать

spdlog :: logger не может быть объявлен через границы модуля компиляции. Решение состоит в том, чтобы обернуть регистратор некоторым простым классом, определенным в logger.cpp, и экспортировать его только в logger.h

.
0 голосов
/ 14 ноября 2018

Вы используете одно и то же имя для обоих регистраторов, при запуске вы получите:

$ ./logger
libc++abi.dylib: terminating with uncaught exception of type spdlog::spdlog_ex: logger with name 'CORE' already exists
Abort trap: 6

Если вы измените имя клиентского логгера на другое, он будет работать нормально:

sCoreLogger = spdlog::stdout_color_mt("CORE");
sClientLogger = spdlog::stdout_color_mt("CLIENT");
...