mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 01:58:19 +00:00
Write log to disk on assert
This commit is contained in:
parent
fd533a47f6
commit
25ceea6f5f
|
@ -1579,6 +1579,8 @@ set_src(ENGINE_INTERFACE GLOB src/engine
|
||||||
warning.h
|
warning.h
|
||||||
)
|
)
|
||||||
set_src(ENGINE_SHARED GLOB src/engine/shared
|
set_src(ENGINE_SHARED GLOB src/engine/shared
|
||||||
|
assertion_logger.cpp
|
||||||
|
assertion_logger.h
|
||||||
compression.cpp
|
compression.cpp
|
||||||
compression.h
|
compression.h
|
||||||
config.cpp
|
config.cpp
|
||||||
|
|
|
@ -132,12 +132,13 @@ IOHANDLE io_current_exe()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct
|
struct DBG_LOGGER_DATA
|
||||||
{
|
{
|
||||||
DBG_LOGGER logger;
|
DBG_LOGGER logger;
|
||||||
DBG_LOGGER_FINISH finish;
|
DBG_LOGGER_FINISH finish;
|
||||||
|
DBG_LOGGER_ASSERTION on_assert = nullptr;
|
||||||
void *user;
|
void *user;
|
||||||
} DBG_LOGGER_DATA;
|
};
|
||||||
|
|
||||||
static DBG_LOGGER_DATA loggers[16];
|
static DBG_LOGGER_DATA loggers[16];
|
||||||
static int has_stdout_logger = 0;
|
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)
|
#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)
|
void dbg_assert_imp(const char *filename, int line, int test, const char *msg)
|
||||||
{
|
{
|
||||||
if(!test)
|
if(!test)
|
||||||
{
|
{
|
||||||
dbg_msg("assert", "%s(%d): %s", filename, line, msg);
|
dbg_msg("assert", "%s(%d): %s", filename, line, msg);
|
||||||
|
dbg_assert_notify_loggers();
|
||||||
dbg_break();
|
dbg_break();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -337,6 +348,13 @@ void dbg_logger(DBG_LOGGER logger, DBG_LOGGER_FINISH finish, void *user)
|
||||||
num_loggers++;
|
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()
|
void dbg_logger_stdout()
|
||||||
{
|
{
|
||||||
#if defined(CONF_FAMILY_WINDOWS)
|
#if defined(CONF_FAMILY_WINDOWS)
|
||||||
|
|
|
@ -1849,6 +1849,9 @@ typedef void (*DBG_LOGGER)(const char *line, void *user);
|
||||||
typedef void (*DBG_LOGGER_FINISH)(void *user);
|
typedef void (*DBG_LOGGER_FINISH)(void *user);
|
||||||
void dbg_logger(DBG_LOGGER logger, DBG_LOGGER_FINISH 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_stdout();
|
||||||
void dbg_logger_debugger();
|
void dbg_logger_debugger();
|
||||||
void dbg_logger_file(const char *filename);
|
void dbg_logger_file(const char *filename);
|
||||||
|
|
54
src/engine/shared/assertion_logger.cpp
Normal file
54
src/engine/shared/assertion_logger.cpp
Normal 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);
|
||||||
|
}
|
36
src/engine/shared/assertion_logger.h
Normal file
36
src/engine/shared/assertion_logger.h
Normal 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
|
|
@ -9,6 +9,8 @@
|
||||||
#include <engine/shared/network.h>
|
#include <engine/shared/network.h>
|
||||||
#include <engine/storage.h>
|
#include <engine/storage.h>
|
||||||
|
|
||||||
|
#include <engine/shared/assertion_logger.h>
|
||||||
|
|
||||||
CHostLookup::CHostLookup() = default;
|
CHostLookup::CHostLookup() = default;
|
||||||
|
|
||||||
CHostLookup::CHostLookup(const char *pHostname, int Nettype)
|
CHostLookup::CHostLookup(const char *pHostname, int Nettype)
|
||||||
|
@ -29,6 +31,10 @@ public:
|
||||||
IStorage *m_pStorage;
|
IStorage *m_pStorage;
|
||||||
bool m_Logging;
|
bool m_Logging;
|
||||||
|
|
||||||
|
CAssertionLogger m_AssertionLogger;
|
||||||
|
|
||||||
|
char m_aAppName[256];
|
||||||
|
|
||||||
static void Con_DbgLognetwork(IConsole::IResult *pResult, void *pUserData)
|
static void Con_DbgLognetwork(IConsole::IResult *pResult, void *pUserData)
|
||||||
{
|
{
|
||||||
CEngine *pEngine = static_cast<CEngine *>(pUserData);
|
CEngine *pEngine = static_cast<CEngine *>(pUserData);
|
||||||
|
@ -53,6 +59,7 @@ public:
|
||||||
|
|
||||||
CEngine(bool Test, const char *pAppname, bool Silent, int Jobs)
|
CEngine(bool Test, const char *pAppname, bool Silent, int Jobs)
|
||||||
{
|
{
|
||||||
|
str_copy(m_aAppName, pAppname, std::size(m_aAppName));
|
||||||
if(!Test)
|
if(!Test)
|
||||||
{
|
{
|
||||||
if(!Silent)
|
if(!Silent)
|
||||||
|
@ -87,6 +94,10 @@ public:
|
||||||
if(!m_pConsole || !m_pStorage)
|
if(!m_pConsole || !m_pStorage)
|
||||||
return;
|
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");
|
m_pConsole->Register("dbg_lognetwork", "", CFGFLAG_SERVER | CFGFLAG_CLIENT, Con_DbgLognetwork, this, "Log the network");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue