Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: KjellKod/g3log
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 2.1
Choose a base ref
...
head repository: KjellKod/g3log
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 2.2
Choose a head ref
  • 6 commits
  • 10 files changed
  • 2 contributors

Commits on Nov 29, 2022

  1. __func__ doesn't make sense (#469)

    __func__ doesn't make sense since we have left c++11 in the dust
    KjellKod authored Nov 29, 2022
    Copy the full SHA
    881e6da View commit details

Commits on Nov 30, 2022

  1. __SIGFUNC__ no longer default for Windows. __PRETTY__FUNCTION no long…

    …er default for gcc/clang (#470)
    
    * __SIGFUNC__ no longer default for Windows, It has to be explicitly picked through CMAKE option
    * __PRETTY_FUNCTION__ no longer default for gcc/clang, It has to be explicitly picked through CMAKE option
    KjellKod authored Nov 30, 2022
    Copy the full SHA
    dbd3d74 View commit details

Commits on Dec 9, 2022

  1. optionable to buffer x messages before writing to file, default to 10…

    …0 which will really boost performance (#471)
    KjellKod authored Dec 9, 2022
    Copy the full SHA
    6c6122f View commit details

Commits on Feb 4, 2023

  1. Copy the full SHA
    16bb6f7 View commit details
  2. Parse OSX stack dump format in order to demangle it correctly (#473)

    * Parse OSX format  mangled stack trace correctly
    Co-authored-by: Grzegorz Glowacki <grzegorz.glowacki@avid.com>
    gglowacki authored Feb 4, 2023
    Copy the full SHA
    09317e3 View commit details
  3. Copy the full SHA
    43f5edd View commit details
Showing with 107 additions and 41 deletions.
  1. +7 −1 .github/workflows/ctest.yml
  2. +1 −1 CMakeLists.txt
  3. +27 −0 Options.cmake
  4. +1 −1 appveyor.yml
  5. +15 −0 docs/building.md
  6. +1 −1 scripts/buildAndRunTests.sh
  7. +32 −25 src/crashhandler_unix.cpp
  8. +14 −4 src/filesink.cpp
  9. +4 −2 src/g3log/filesink.hpp
  10. +5 −6 src/g3log/g3log.hpp
8 changes: 7 additions & 1 deletion .github/workflows/ctest.yml
Original file line number Diff line number Diff line change
@@ -78,4 +78,10 @@ jobs:
shell: bash
# Execute tests defined by the CMake configuration.
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: ctest -C $BUILD_TYPE
run: ctest -C $BUILD_TYP

- name: Fatal Exit Example
working-directory: ${{github.workspace}}/build
shell: bash
# hacky / crude and effective
run: ./g3log-FATAL-sigsegv || true && echo -e "\n\n=======================\n\nverifying SIGSEGV existed in stackdump\n\n\n\n" && cat /tmp/g3log*FATAL*.log | grep "SIGSEGV"
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -68,7 +68,7 @@ endif()

# Calculate the version number
SET(MAJOR_VERSION 2)
SET(MINOR_VERSION 1)
SET(MINOR_VERSION 2)

IF ( NOT VERSION )
IF ( "${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows" )
27 changes: 27 additions & 0 deletions Options.cmake
Original file line number Diff line number Diff line change
@@ -14,6 +14,8 @@
# to the auto generated file src/g3log/generated_definitions.hpp
# add_definitions(-DG3_DYNAMIC_LOGGING)
# add_definitions(-DCHANGE_G3LOG_DEBUG_TO_DBUG)
# add_definitions(-DWINDOWS_FUNCSIG)
# add_definitions(-DPRETTY_FUNCTION)
# add_definitions(-DDISABLE_FATAL_SIGNALHANDLING)
# add_definitions(-DDISABLE_VECTORED_EXCEPTIONHANDLING)
# add_definitions(-DDEBUG_BREAK_AT_FATAL_SIGNAL)
@@ -61,6 +63,31 @@ ELSE()
ENDIF(CHANGE_G3LOG_DEBUG_TO_DBUG)


# -DWINDOWS_USE_FUNCSIG=ON : (Default OFF) Override the use of __FUNCTION__ for Windows platform and instead use __FUNCSIG__
option (WINDOWS_FUNCSIG
"Windows __FUNCSIG__ to expand `Function` location of the LOG call instead of the default __FUNCTION__" OFF)
IF(WINDOWS_FUNCSIG)
LIST(APPEND G3_DEFINITIONS WINDOWS_FUNCSIG)
message( STATUS "-DWINDOWS_FUNCSIG=ON\t\t__SIGFUNC__ is used instead of the default __FUNCTION__ for LOG call locations" )
ELSE()
message( STATUS "-DWINDOWS_FUNCSIG=OFF")
ENDIF(WINDOWS_FUNCSIG)


# -DPRETTY_FUNCTION=ON : (Default OFF) Override the use of __FUNCTION__ for Windows platform and instead use __FUNCSIG__
# NOTE: heavy templated integrations such as boost log calls that shows the function name can cause function name expansion
# to "spam" the LOG output with the now visible template arguments.
option (PRETTY_FUNCTION
"Windows __PRETTY_FUNCTION__ to expand `Function` location of the LOG call instead of the default __FUNCTION__" OFF)
IF(PRETTY_FUNCTION)
LIST(APPEND G3_DEFINITIONS PRETTY_FUNCTION)
message( STATUS "-DPRETTY_FUNCTION=ON\t\t__PRETTY_FUNCTION__ is used instead of the default __FUNCTION__ for LOG call locations" )
ELSE()
message( STATUS "-DPRETTY_FUNCTION=OFF")
ENDIF(PRETTY_FUNCTION)



# -DG3_DYNAMIC_MAX_MESSAGE_SIZE : use dynamic memory for final_message in logcapture.cpp
option (USE_G3_DYNAMIC_MAX_MESSAGE_SIZE
"Use dynamic memory for message buffer during log capturing" OFF)
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ before_build:
- cd build

build_script:
- cmake -G "Visual Studio 15 2017 Win64" -DADD_G3LOG_UNIT_TEST=ON -DUSE_DYNAMIC_LOGGING_LEVELS=ON -DCHANGE_G3LOG_DEBUG_TO_DBUG=ON -DCMAKE_INSTALL_PREFIX=c:\g3log ..
- cmake -G "Visual Studio 15 2017 Win64" -DADD_G3LOG_UNIT_TEST=ON -DWINDOWS_FUNCSIG=ON -DUSE_DYNAMIC_LOGGING_LEVELS=ON -DCHANGE_G3LOG_DEBUG_TO_DBUG=ON -DCMAKE_INSTALL_PREFIX=c:\g3log ..
- cmake --build . --config Release --target install

# scripts to run after build
15 changes: 15 additions & 0 deletions docs/building.md
Original file line number Diff line number Diff line change
@@ -47,6 +47,21 @@ ADD_G3LOG_UNIT_TEST:BOOL=OFF
// By default DEBUG is the debugging level
CHANGE_G3LOG_DEBUG_TO_DBUG:BOOL=OFF
// Windows only: Use __FUNCSIG__ instead of the default __FUNCTION__
// to show LOG function location
// WARNING: using this in heavily templated code, like boost can expand
// the function name into massive size
WINDOWS_FUNCSIG:BOOL=OFF
// gcc/clang only: Use __PRETTY_FUNCTION__ instead of the default __FUNCTION__
// to show LOG function location
// WARNING: using this in heavily templated code, like boost can expand
// the function name into massive size
PRETTY_FUNCTION:BOOL=OFF
// Specifies the build type on single-configuration generators.
// Possible values are empty, Debug, Release, RelWithDebInfo, MinSizeRel, …
CMAKE_BUILD_TYPE:STRING=
2 changes: 1 addition & 1 deletion scripts/buildAndRunTests.sh
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ set -x

mkdir -p build_travis
cd build_travis
cmake -DADD_G3LOG_BENCH_PERFORMANCE=ON -DADD_G3LOG_UNIT_TEST=ON -DCMAKE_INSTALL_PREFIX=./install -DCPACK_PACKAGING_INSTALL_PREFIX=/opt/g3log ..
cmake -DADD_G3LOG_BENCH_PERFORMANCE=ON -DPRETTY_FUNCTION=ON -DADD_G3LOG_UNIT_TEST=ON -DCMAKE_INSTALL_PREFIX=./install -DCPACK_PACKAGING_INSTALL_PREFIX=/opt/g3log ..
cmake --build . --target install

if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
57 changes: 32 additions & 25 deletions src/crashhandler_unix.cpp
Original file line number Diff line number Diff line change
@@ -145,50 +145,57 @@ namespace g3 {
if (nullptr != rawdump && !std::string(rawdump).empty()) {
return {rawdump};
}

const size_t max_dump_size = 50;
void* dump[max_dump_size];
size_t size = backtrace(dump, max_dump_size);
const size_t size = backtrace(dump, max_dump_size);
char** messages = backtrace_symbols(dump, static_cast<int>(size)); // overwrite sigaction with caller's address

// dump stack: skip first frame, since that is here
std::ostringstream oss;
for (size_t idx = 1; idx < size && messages != nullptr; ++idx) {
char* mangled_name = 0, *offset_begin = 0, *offset_end = 0;
// find parentheses and +address offset surrounding mangled name
for (char* p = messages[idx]; *p; ++p) {
if (*p == '(') {
mangled_name = p;
} else if (*p == '+') {
offset_begin = p;
} else if (*p == ')') {
offset_end = p;
break;
}
std::string strMessage{messages[idx]};
std::string mangled_name, offset;

/// first look for format that includes brackets "(mangled_name+offset)""
const auto firstBracket = strMessage.find_last_of('(');
const auto secondBracket = strMessage.find_last_of(')');
if (firstBracket != strMessage.npos && secondBracket != strMessage.npos)
{
const auto betweenBrackets = strMessage.substr(firstBracket + 1, secondBracket - firstBracket - 1);
const auto plusSign = betweenBrackets.find_first_of('+');
if (plusSign != betweenBrackets.npos)
{
mangled_name = betweenBrackets.substr(0, plusSign);
offset = betweenBrackets.substr(plusSign + 1, betweenBrackets.npos);
}
}
else
{
/// we did not found brackets, looking for "_mangled_name + offset"
const auto plusSign = strMessage.find_first_of('+');
const auto lastUnderscore = strMessage.rfind(" _");
if (plusSign != strMessage.npos && lastUnderscore != strMessage.npos)
{
mangled_name = strMessage.substr(lastUnderscore + 1, plusSign - lastUnderscore - 2);
offset = strMessage.substr(plusSign + 2, strMessage.npos);
}
}

// if the line could be processed, attempt to demangle the symbol
if (mangled_name && offset_begin && offset_end &&
mangled_name < offset_begin) {
*mangled_name++ = '\0';
*offset_begin++ = '\0';
*offset_end++ = '\0';

if (!mangled_name.empty() && !offset.empty()) {
int status;
char* real_name = abi::__cxa_demangle(mangled_name, 0, 0, &status);
char* real_name = abi::__cxa_demangle(mangled_name.c_str(), 0, 0, &status);
// if demangling is successful, output the demangled function name
if (status == 0) {
oss << "\n\tstack dump [" << idx << "] " << messages[idx] << " : " << real_name << "+";
oss << offset_begin << offset_end << std::endl;
oss << "\tstack dump [" << idx << "] " << real_name << " + " << offset<< std::endl;
}// otherwise, output the mangled function name
else {
oss << "\tstack dump [" << idx << "] " << messages[idx] << mangled_name << "+";
oss << offset_begin << offset_end << std::endl;
oss << "\tstack dump [" << idx << "] " << mangled_name << " + " << offset<< std::endl;
}
free(real_name); // mallocated by abi::__cxa_demangle(...)
} else {
// no demangling done -- just dump the whole line
oss << "\tstack dump [" << idx << "] " << messages[idx] << std::endl;
oss << "\tstack dump [" << idx << "] " << strMessage << std::endl;
}
} // END: for(size_t idx = 1; idx < size && messages != nullptr; ++idx)
free(messages);
18 changes: 14 additions & 4 deletions src/filesink.cpp
Original file line number Diff line number Diff line change
@@ -14,13 +14,15 @@
namespace g3 {
using namespace internal;

FileSink::FileSink(const std::string &log_prefix, const std::string &log_directory, const std::string& logger_id)
FileSink::FileSink(const std::string &log_prefix, const std::string &log_directory, const std::string& logger_id, size_t write_to_log_every_x_message)
: _log_details_func(&LogMessage::DefaultLogDetailsToString)
,_log_file_with_path(log_directory)
, _log_prefix_backup(log_prefix)
, _outptr(new std::ofstream)
, _header("\t\tLOG format: [YYYY/MM/DD hh:mm:ss uuu* LEVEL FILE->FUNCTION:LINE] message\n\n\t\t(uuu*: microseconds fractions of the seconds value)\n\n")
, _firstEntry(true)
, _write_counter(0)
, _write_to_log_every_x_message(write_to_log_every_x_message)
{
_log_prefix_backup = prefixSanityFix(log_prefix);
if (!isValidFilename(_log_prefix_backup)) {
@@ -42,10 +44,12 @@ namespace g3 {


FileSink::~FileSink() {
std::string exit_msg {"g3log g3FileSink shutdown at: "};
std::string exit_msg = {"g3log g3FileSink shutdown at: "};
auto now = std::chrono::system_clock::now();
exit_msg.append(localtime_formatted(now, internal::time_formatted)).append("\n");
filestream() << exit_msg << std::flush;

// write anything buffered up and then end with the exit msg
filestream() << _write_buffer << exit_msg << std::flush;

exit_msg.append("Log file at: [").append(_log_file_with_path).append("]\n");
std::cerr << exit_msg << std::flush;
@@ -59,7 +63,13 @@ namespace g3 {
}

std::ofstream &out(filestream());
out << message.get().toString(_log_details_func) << std::flush;
auto data = message.get().toString(_log_details_func);

_write_buffer.append(data);
if (++_write_counter % _write_to_log_every_x_message == 0) {
out << message.get().toString(_log_details_func) << std::flush;
_write_buffer.clear();
}
}

std::string FileSink::changeLogFile(const std::string &directory, const std::string &logger_id) {
6 changes: 4 additions & 2 deletions src/g3log/filesink.hpp
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ namespace g3 {

class FileSink {
public:
FileSink(const std::string &log_prefix, const std::string &log_directory, const std::string &logger_id="g3log");
FileSink(const std::string &log_prefix, const std::string &log_directory, const std::string &logger_id="g3log", size_t write_to_log_every_x_message = 100);
virtual ~FileSink();

void fileWrite(LogMessageMover message);
@@ -27,12 +27,14 @@ namespace g3 {

private:
LogMessage::LogDetailsFunc _log_details_func;

std::string _log_file_with_path;
std::string _log_prefix_backup; // needed in case of future log file changes of directory
std::unique_ptr<std::ofstream> _outptr;
std::string _header;
bool _firstEntry;
std::string _write_buffer;
size_t _write_counter;
size_t _write_to_log_every_x_message;

void addLogFileHeader();
std::ofstream &filestream() {
11 changes: 5 additions & 6 deletions src/g3log/g3log.hpp
Original file line number Diff line number Diff line change
@@ -29,13 +29,12 @@
#include <string>
#include <functional>


#if defined(__GNUC__) // GCC extension compatible
#define G3LOG_PRETTY_FUNCTION __PRETTY_FUNCTION__
#elif defined(_MSC_VER) // Microsoft
#if defined(_MSC_VER) && (defined(WINDOWS_FUNCSIG)) // Microsoft
#define G3LOG_PRETTY_FUNCTION __FUNCSIG__
#else // Fallback to c99 / c++11
#define G3LOG_PRETTY_FUNCTION __func__
#elif defined(__GNUC__) && defined(PRETTY_FUNCTION) // GCC compatible
#define G3LOG_PRETTY_FUNCTION __PRETTY_FUNCTION__
#else
#define G3LOG_PRETTY_FUNCTION __FUNCTION__
#endif

// thread_local doesn't exist before VS2013