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
|
||||
)
|
||||
set_src(ENGINE_SHARED GLOB src/engine/shared
|
||||
assertion_logger.cpp
|
||||
assertion_logger.h
|
||||
compression.cpp
|
||||
compression.h
|
||||
config.cpp
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
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/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");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue