Write log to disk on assert

This commit is contained in:
Jupeyy 2022-03-02 14:28:37 +01:00
parent fd533a47f6
commit 25ceea6f5f
6 changed files with 126 additions and 2 deletions

View file

@ -1579,6 +1579,8 @@ set_src(ENGINE_INTERFACE GLOB src/engine
warning.h
)
set_src(ENGINE_SHARED GLOB src/engine/shared
assertion_logger.cpp
assertion_logger.h
compression.cpp
compression.h
config.cpp

View file

@ -132,12 +132,13 @@ IOHANDLE io_current_exe()
#endif
}
typedef struct
struct DBG_LOGGER_DATA
{
DBG_LOGGER logger;
DBG_LOGGER_FINISH finish;
DBG_LOGGER_ASSERTION on_assert = nullptr;
void *user;
} DBG_LOGGER_DATA;
};
static DBG_LOGGER_DATA loggers[16];
static int has_stdout_logger = 0;
@ -181,11 +182,21 @@ static NETSOCKET_INTERNAL invalid_socket = {NETTYPE_INVALID, -1, -1, -1};
#define AF_WEBSOCKET_INET (0xee)
static void dbg_assert_notify_loggers()
{
for(int i = 0; i < num_loggers; i++)
{
if(loggers[i].on_assert)
loggers[i].on_assert(loggers[i].user);
}
}
void dbg_assert_imp(const char *filename, int line, int test, const char *msg)
{
if(!test)
{
dbg_msg("assert", "%s(%d): %s", filename, line, msg);
dbg_assert_notify_loggers();
dbg_break();
}
}
@ -337,6 +348,13 @@ void dbg_logger(DBG_LOGGER logger, DBG_LOGGER_FINISH finish, void *user)
num_loggers++;
}
void dbg_logger_assertion(DBG_LOGGER logger, DBG_LOGGER_FINISH finish, DBG_LOGGER_ASSERTION on_assert, void *user)
{
dbg_logger(logger, finish, user);
loggers[num_loggers - 1].on_assert = on_assert;
}
void dbg_logger_stdout()
{
#if defined(CONF_FAMILY_WINDOWS)

View file

@ -1849,6 +1849,9 @@ typedef void (*DBG_LOGGER)(const char *line, void *user);
typedef void (*DBG_LOGGER_FINISH)(void *user);
void dbg_logger(DBG_LOGGER logger, DBG_LOGGER_FINISH finish, void *user);
typedef void (*DBG_LOGGER_ASSERTION)(void *user);
void dbg_logger_assertion(DBG_LOGGER logger, DBG_LOGGER_FINISH finish, DBG_LOGGER_ASSERTION on_assert, void *user);
void dbg_logger_stdout();
void dbg_logger_debugger();
void dbg_logger_file(const char *filename);

View file

@ -0,0 +1,54 @@
#include "assertion_logger.h"
#include <base/system.h>
#include <mutex>
void CAssertionLogger::DbgLogger(const char *pLine, void *pUser)
{
((CAssertionLogger *)pUser)->DbgLogger(pLine);
}
void CAssertionLogger::DbgLoggerAssertion(void *pUser)
{
((CAssertionLogger *)pUser)->DbgLoggerAssertion();
}
void CAssertionLogger::DbgLogger(const char *pLine)
{
std::unique_lock<std::mutex> Lock(m_DbgMessageMutex);
SDebugMessageItem *pMsgItem = (SDebugMessageItem *)m_DbgMessages.Allocate(sizeof(SDebugMessageItem));
str_copy(pMsgItem->m_aMessage, pLine, std::size(pMsgItem->m_aMessage));
}
void CAssertionLogger::DbgLoggerAssertion()
{
char aAssertLogFile[IO_MAX_PATH_LENGTH];
char aDate[64];
str_timestamp(aDate, sizeof(aDate));
str_format(aAssertLogFile, std::size(aAssertLogFile), "%s%s_assert_log_%d_%s.txt", m_aAssertLogPath, m_aGameName, pid(), aDate);
std::unique_lock<std::mutex> Lock(m_DbgMessageMutex);
IOHANDLE FileHandle = io_open(aAssertLogFile, IOFLAG_WRITE);
if(FileHandle)
{
auto *pIt = m_DbgMessages.First();
while(pIt)
{
io_write(FileHandle, pIt->m_aMessage, str_length(pIt->m_aMessage));
io_write(FileHandle, "\n", 1);
pIt = m_DbgMessages.Next(pIt);
}
io_sync(FileHandle);
io_close(FileHandle);
}
}
void CAssertionLogger::Init(const char *pAssertLogPath, const char *pGameName)
{
str_copy(m_aAssertLogPath, pAssertLogPath, std::size(m_aAssertLogPath));
str_copy(m_aGameName, pGameName, std::size(m_aGameName));
dbg_logger_assertion(DbgLogger, nullptr, DbgLoggerAssertion, this);
}

View file

@ -0,0 +1,36 @@
#ifndef ENGINE_SHARED_ASSERTION_LOGGER_H
#define ENGINE_SHARED_ASSERTION_LOGGER_H
#include <base/system.h>
#include <cstddef>
#include <mutex>
#include <engine/shared/ringbuffer.h>
class CAssertionLogger
{
static void DbgLogger(const char *pLine, void *pUser);
static void DbgLoggerAssertion(void *pUser);
static constexpr size_t s_MaxDbgMessageCount = 64;
void DbgLogger(const char *pLine);
void DbgLoggerAssertion();
struct SDebugMessageItem
{
char m_aMessage[1024];
};
std::mutex m_DbgMessageMutex;
CStaticRingBuffer<SDebugMessageItem, sizeof(SDebugMessageItem) * s_MaxDbgMessageCount, CRingBufferBase::FLAG_RECYCLE> m_DbgMessages;
char m_aAssertLogPath[IO_MAX_PATH_LENGTH];
char m_aGameName[256];
public:
void Init(const char *pAssertLogPath, const char *pGameName);
};
#endif

View file

@ -9,6 +9,8 @@
#include <engine/shared/network.h>
#include <engine/storage.h>
#include <engine/shared/assertion_logger.h>
CHostLookup::CHostLookup() = default;
CHostLookup::CHostLookup(const char *pHostname, int Nettype)
@ -29,6 +31,10 @@ public:
IStorage *m_pStorage;
bool m_Logging;
CAssertionLogger m_AssertionLogger;
char m_aAppName[256];
static void Con_DbgLognetwork(IConsole::IResult *pResult, void *pUserData)
{
CEngine *pEngine = static_cast<CEngine *>(pUserData);
@ -53,6 +59,7 @@ public:
CEngine(bool Test, const char *pAppname, bool Silent, int Jobs)
{
str_copy(m_aAppName, pAppname, std::size(m_aAppName));
if(!Test)
{
if(!Silent)
@ -87,6 +94,10 @@ public:
if(!m_pConsole || !m_pStorage)
return;
char aFullPath[IO_MAX_PATH_LENGTH];
m_pStorage->GetCompletePath(IStorage::TYPE_SAVE, "dumps/", aFullPath, sizeof(aFullPath));
m_AssertionLogger.Init(aFullPath, m_aAppName);
m_pConsole->Register("dbg_lognetwork", "", CFGFLAG_SERVER | CFGFLAG_CLIENT, Con_DbgLognetwork, this, "Log the network");
}