Browse Source

* Fixed bug: log_helper objects will cause segmentation fault if their member methods are used to update the log entry values

master
bergmann 4 years ago
parent
commit
b0aece03ab
7 changed files with 39 additions and 165 deletions
  1. +3
    -3
      include/cpplogging/interface/global.h
  2. +1
    -1
      include/cpplogging/interface/iomanip.h
  3. +1
    -1
      include/cpplogging/interface/iomanip.inl
  4. +3
    -69
      include/cpplogging/interface/logger.h
  5. +2
    -89
      include/cpplogging/interface/logger.inl
  6. +2
    -2
      src/cpplogging/manager/matcher/matcher_regex.cpp
  7. +27
    -0
      test/cpplogging/cpplogging_tests.cpp

+ 3
- 3
include/cpplogging/interface/global.h View File

@@ -5,6 +5,6 @@
#define cpplogging_global_log(p_level) \
if (::cpplogging::logger::get().is_enabled(::cpplogging::log_level::p_level)) \
::cpplogging::logger::get().log() \
.level(::cpplogging::log_level::p_level) \
.file(__FILE__) \
.line(__LINE__)
<< ::cpplogging::level(::cpplogging::log_level::p_level) \
<< ::cpplogging::file(__FILE__) \
<< ::cpplogging::line(__LINE__)

+ 1
- 1
include/cpplogging/interface/iomanip.h View File

@@ -32,7 +32,7 @@ namespace cpplogging
* @brief Set the sender of a log stream.
*/
template<typename T_sender>
inline auto sender(const T_sender * sender);
inline auto sender(const T_sender* sender);

/**
* @brief Set the sender type of a log stream.


+ 1
- 1
include/cpplogging/interface/iomanip.inl View File

@@ -33,7 +33,7 @@ namespace cpplogging
}

template<typename T_sender>
auto sender(const T_sender * sender)
auto sender(const T_sender* sender)
{
return __impl::make_stream_setter([=](log_entry& e){
int status;


+ 3
- 69
include/cpplogging/interface/logger.h View File

@@ -6,9 +6,9 @@
#define cpplogging_log(p_logger, p_level) \
if (p_logger.is_enabled(::cpplogging::log_level::p_level)) \
p_logger.log() \
.level(::cpplogging::log_level::p_level) \
.file(__FILE__) \
.line(__LINE__)
<< ::cpplogging::level(::cpplogging::log_level::p_level) \
<< ::cpplogging::file(__FILE__) \
<< ::cpplogging::line(__LINE__)

namespace cpplogging
{
@@ -59,72 +59,6 @@ namespace cpplogging
* @brief Destructor. Will finally write the log entry.
*/
inline ~log_helper();

/**
* @brief Set the log level of the entry,
*/
inline log_helper& level(log_level level);

/**
* @brief Set the sender of the log entry.
*/
inline log_helper& sender(const void * sender);

/**
* @brief Set the sender and the sender type of the log entry.
*/
template<typename T_sender>
inline log_helper& sender(const T_sender * sender);

/**
* @brief Set the sender type of the log entry.
*/
inline log_helper& sender_type(const std::string& sender_type);

/**
* @brief Set the filename of the log entry.
*/
inline log_helper& file(const char * file);

/**
* @brief Set the line number of the log entry.
*/
inline log_helper& line(int line);

/**
* @brief Set the message of the log entry.
*/
inline log_helper& message(const std::string& msg);

/**
* @brief Add the passed string to the log message.
*/
inline log_helper& add_message(const std::string& msg);

/**
* @brief Set the message of the entry using format string.
*/
template<typename... T_args>
inline log_helper& format(const std::string& fmt, T_args&&... args);

/**
* @brief Add a message to the entry using format string.
*/
template<typename... T_args>
inline log_helper& add_format(const std::string& fmt, T_args&&... args);

private:
/**
* @brief Format a string.
*
* @tparam T_args Arguments of the format string.
*
* @param[in] fmt Format string.
* @param[in] sz Size of the buffer to use for the formatting.
* @param[in] args Arguments of the format.
*/
template<typename... T_args>
static inline std::string format(const std::string& fmt, size_t sz, T_args&&... args);
};

}


+ 2
- 89
include/cpplogging/interface/logger.inl View File

@@ -27,96 +27,9 @@ namespace cpplogging
::~log_helper()
{
entry->message += str();
logger.write_entry(entry);
if (entry.use_count() == 1)
logger.write_entry(entry);
}

log_helper& log_helper
::level(log_level level)
{
entry->level = level;
return *this;
}

log_helper& log_helper
::sender(const void * sender)
{
entry->sender = sender;
return *this;
}

template<typename T_sender>
log_helper& log_helper
::sender(const T_sender * sender)
{
int status;
auto name = abi::__cxa_demangle(typeid(T_sender).name(), 0, 0, &status);
entry->sender_type = std::string(name ? name : typeid(T_sender).name());
entry->sender = sender;
return *this;
}

log_helper& log_helper
::sender_type(const std::string& sender_type)
{
entry->sender_type = sender_type;
return *this;
}

log_helper& log_helper
::file(const char * file)
{
entry->file = file;
return *this;
}

log_helper& log_helper
::line(int line)
{
entry->line = line;
return *this;
}

log_helper& log_helper
::message(const std::string& msg)
{
entry->message = msg;
return *this;
}

log_helper& log_helper
::add_message(const std::string& msg)
{
entry->message += msg;
return *this;
}

template<typename... T_args>
log_helper& log_helper
::format(const std::string& fmt, T_args&&... args)
{
entry->message = format(fmt, 0x8000, std::forward<T_args>(args)...);
return *this;
}

template<typename... T_args>
log_helper& log_helper
::add_format(const std::string& fmt, T_args&&... args)
{
entry->message += format(fmt, 0x8000, std::forward<T_args>(args)...);
return *this;
}

template<typename... T_args>
std::string log_helper
::format(const std::string& fmt, size_t sz, T_args&&... args)
{
std::unique_ptr<char, decltype(&free)> buff(static_cast<char*>(malloc(sz)), &free);
auto len = snprintf(buff.get(), sz, fmt.c_str(), std::forward<T_args>(args)...);
if (len < 0)
throw std::runtime_error("unable to format string");
return std::string(buff.get(), len);
}

}

/* logger */


+ 2
- 2
src/cpplogging/manager/matcher/matcher_regex.cpp View File

@@ -8,7 +8,7 @@ matcher_regex::matcher_regex(const std::string regex, bool invert)
{ }

bool matcher_regex::match(const logger& logger) const
{ return !logger.name().empty() && std::regex_match(logger.name(), _regex) != _invert; }
{ return std::regex_match(logger.name(), _regex) != _invert; }

bool matcher_regex::match(const consumer& consumer) const
{ return !consumer.name().empty() && std::regex_match(consumer.name(), _regex) != _invert; }
{ return std::regex_match(consumer.name(), _regex) != _invert; }

+ 27
- 0
test/cpplogging/cpplogging_tests.cpp View File

@@ -128,6 +128,33 @@ TEST(LoggingTests, log_base)
cpplogging_log(l1, error).sender((void*)0x24).message("test2") << " error";
}

TEST(LoggingTests, log_inverted_regex)
{
LoggingReset loggingReset;
StrictMock<consumer_mock> c0("consumer0");

EXPECT_CALL(c0, write_entry(MatchLogData(
log_level::debug,
(void*)0x12,
std::this_thread::get_id(),
std::string("logger2"),
std::string("test2"))));

manager::define_rule(
std::make_unique<matcher_regex>("^logger[0-1]+$", true),
std::make_unique<matcher_regex>("consumer0"),
log_level::debug,
log_level::error);

auto& l0 = logger::get("logger0");
auto& l1 = logger::get("logger1");
auto& l2 = logger::get("logger2");

cpplogging_log(l0, debug).sender((void*)0x10) << "test0";
cpplogging_log(l1, debug).sender((void*)0x11) << "test1";
cpplogging_log(l2, debug).sender((void*)0x12) << "test2";
}

#ifdef CPPLOGGING_HAS_LOAD_CONFIG
TEST(LoggingTests, load)
{


Loading…
Cancel
Save