Add client desync log to server desync log output
This commit is contained in:
@@ -610,7 +610,7 @@ bool CrashLog::MakeCrashLog() const
|
|||||||
* information like paths to the console.
|
* information like paths to the console.
|
||||||
* @return true when everything is made successfully.
|
* @return true when everything is made successfully.
|
||||||
*/
|
*/
|
||||||
bool CrashLog::MakeDesyncCrashLog() const
|
bool CrashLog::MakeDesyncCrashLog(const std::string *log_in, std::string *log_out) const
|
||||||
{
|
{
|
||||||
char filename[MAX_PATH];
|
char filename[MAX_PATH];
|
||||||
char buffer[65536 * 2];
|
char buffer[65536 * 2];
|
||||||
@@ -624,7 +624,14 @@ bool CrashLog::MakeDesyncCrashLog() const
|
|||||||
strftime(name_buffer_date, lastof(name_buffer) - name_buffer_date, "%Y%m%dT%H%M%SZ", gmtime(&cur_time));
|
strftime(name_buffer_date, lastof(name_buffer) - name_buffer_date, "%Y%m%dT%H%M%SZ", gmtime(&cur_time));
|
||||||
|
|
||||||
printf("Desync encountered (%s), generating desync log...\n", mode);
|
printf("Desync encountered (%s), generating desync log...\n", mode);
|
||||||
this->FillDesyncCrashLog(buffer, lastof(buffer));
|
char *b = this->FillDesyncCrashLog(buffer, lastof(buffer));
|
||||||
|
|
||||||
|
if (log_in && !log_in->empty()) {
|
||||||
|
b = strecpy(b, "\n", lastof(buffer), true);
|
||||||
|
b = strecpy(b, log_in->c_str(), lastof(buffer), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (log_out) log_out->assign(buffer);
|
||||||
|
|
||||||
bool bret = this->WriteCrashLog(buffer, filename, lastof(filename), name_buffer);
|
bool bret = this->WriteCrashLog(buffer, filename, lastof(filename), name_buffer);
|
||||||
if (bret) {
|
if (bret) {
|
||||||
|
@@ -128,7 +128,7 @@ public:
|
|||||||
bool WriteScreenshot(char *filename, const char *filename_last, const char *name = "crash") const;
|
bool WriteScreenshot(char *filename, const char *filename_last, const char *name = "crash") const;
|
||||||
|
|
||||||
bool MakeCrashLog() const;
|
bool MakeCrashLog() const;
|
||||||
bool MakeDesyncCrashLog() const;
|
bool MakeDesyncCrashLog(const std::string *log_in, std::string *log_out) const;
|
||||||
bool MakeCrashSavegameAndScreenshot() const;
|
bool MakeCrashSavegameAndScreenshot() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -138,7 +138,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
static void InitialiseCrashLog();
|
static void InitialiseCrashLog();
|
||||||
|
|
||||||
static void DesyncCrashLog();
|
static void DesyncCrashLog(const std::string *log_in, std::string *log_out);
|
||||||
|
|
||||||
static void SetErrorMessage(const char *message);
|
static void SetErrorMessage(const char *message);
|
||||||
static void AfterCrashLogCleanup();
|
static void AfterCrashLogCleanup();
|
||||||
|
@@ -62,6 +62,9 @@ typedef unsigned long in_addr_t;
|
|||||||
# define ioctlsocket ioctl
|
# define ioctlsocket ioctl
|
||||||
# define closesocket close
|
# define closesocket close
|
||||||
# define GET_LAST_ERROR() (errno)
|
# define GET_LAST_ERROR() (errno)
|
||||||
|
# define SD_RECEIVE SHUT_RD
|
||||||
|
# define SD_SEND SHUT_WR
|
||||||
|
# define SD_BOTH SHUT_RDWR
|
||||||
/* Need this for FIONREAD on solaris */
|
/* Need this for FIONREAD on solaris */
|
||||||
# define BSD_COMP
|
# define BSD_COMP
|
||||||
|
|
||||||
@@ -102,6 +105,9 @@ typedef unsigned long in_addr_t;
|
|||||||
# define ioctlsocket ioctl
|
# define ioctlsocket ioctl
|
||||||
# define closesocket close
|
# define closesocket close
|
||||||
# define GET_LAST_ERROR() (sock_errno())
|
# define GET_LAST_ERROR() (sock_errno())
|
||||||
|
# define SD_RECEIVE SHUT_RD
|
||||||
|
# define SD_SEND SHUT_WR
|
||||||
|
# define SD_BOTH SHUT_RDWR
|
||||||
|
|
||||||
/* Includes needed for OS/2 systems */
|
/* Includes needed for OS/2 systems */
|
||||||
# include <types.h>
|
# include <types.h>
|
||||||
@@ -166,6 +172,21 @@ static inline bool SetNonBlocking(SOCKET d)
|
|||||||
return ioctlsocket(d, FIONBIO, &nonblocking) == 0;
|
return ioctlsocket(d, FIONBIO, &nonblocking) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to set the socket into blocking mode.
|
||||||
|
* @param d The socket to set the blocking more for.
|
||||||
|
* @return True if setting the blocking mode succeeded, otherwise false.
|
||||||
|
*/
|
||||||
|
static inline bool SetBlocking(SOCKET d)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
u_long nonblocking = 0;
|
||||||
|
#else
|
||||||
|
int nonblocking = 0;
|
||||||
|
#endif
|
||||||
|
return ioctlsocket(d, FIONBIO, &nonblocking) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to set the socket to not delay sending.
|
* Try to set the socket to not delay sending.
|
||||||
* @param d The socket to disable the delaying for.
|
* @param d The socket to disable the delaying for.
|
||||||
@@ -179,6 +200,32 @@ static inline bool SetNoDelay(SOCKET d)
|
|||||||
return setsockopt(d, IPPROTO_TCP, TCP_NODELAY, (const char*)&b, sizeof(b)) == 0;
|
return setsockopt(d, IPPROTO_TCP, TCP_NODELAY, (const char*)&b, sizeof(b)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to shutdown the socket in one or both directions.
|
||||||
|
* @param d The socket to disable the delaying for.
|
||||||
|
* @param read Whether to shutdown the read direction.
|
||||||
|
* @param write Whether to shutdown the write direction.
|
||||||
|
* @param linger_timeout The socket linger timeout.
|
||||||
|
* @return True if successful
|
||||||
|
*/
|
||||||
|
static inline bool ShutdownSocket(SOCKET d, bool read, bool write, uint linger_timeout)
|
||||||
|
{
|
||||||
|
if (!read && !write) return true;
|
||||||
|
#ifdef _WIN32
|
||||||
|
LINGER ln = { 1U, (uint16) linger_timeout };
|
||||||
|
#else
|
||||||
|
struct linger ln = { 1, (int) linger_timeout };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
setsockopt(d, SOL_SOCKET, SO_LINGER, (const char*)&ln, sizeof(ln));
|
||||||
|
|
||||||
|
int how = SD_BOTH;
|
||||||
|
if (!read) how = SD_SEND;
|
||||||
|
if (!write) how = SD_RECEIVE;
|
||||||
|
return shutdown(d, how) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Make sure these structures have the size we expect them to be */
|
/* Make sure these structures have the size we expect them to be */
|
||||||
assert_compile(sizeof(in_addr) == 4); ///< IPv4 addresses should be 4 bytes.
|
assert_compile(sizeof(in_addr) == 4); ///< IPv4 addresses should be 4 bytes.
|
||||||
assert_compile(sizeof(in6_addr) == 16); ///< IPv6 addresses should be 16 bytes.
|
assert_compile(sizeof(in6_addr) == 16); ///< IPv6 addresses should be 16 bytes.
|
||||||
|
@@ -99,6 +99,7 @@ NetworkRecvStatus NetworkGameSocketHandler::HandlePacket(Packet *p)
|
|||||||
case PACKET_CLIENT_SET_NAME: return this->Receive_CLIENT_SET_NAME(p);
|
case PACKET_CLIENT_SET_NAME: return this->Receive_CLIENT_SET_NAME(p);
|
||||||
case PACKET_CLIENT_QUIT: return this->Receive_CLIENT_QUIT(p);
|
case PACKET_CLIENT_QUIT: return this->Receive_CLIENT_QUIT(p);
|
||||||
case PACKET_CLIENT_ERROR: return this->Receive_CLIENT_ERROR(p);
|
case PACKET_CLIENT_ERROR: return this->Receive_CLIENT_ERROR(p);
|
||||||
|
case PACKET_CLIENT_DESYNC_LOG: return this->Receive_CLIENT_DESYNC_LOG(p);
|
||||||
case PACKET_SERVER_QUIT: return this->Receive_SERVER_QUIT(p);
|
case PACKET_SERVER_QUIT: return this->Receive_SERVER_QUIT(p);
|
||||||
case PACKET_SERVER_ERROR_QUIT: return this->Receive_SERVER_ERROR_QUIT(p);
|
case PACKET_SERVER_ERROR_QUIT: return this->Receive_SERVER_ERROR_QUIT(p);
|
||||||
case PACKET_SERVER_SHUTDOWN: return this->Receive_SERVER_SHUTDOWN(p);
|
case PACKET_SERVER_SHUTDOWN: return this->Receive_SERVER_SHUTDOWN(p);
|
||||||
@@ -185,6 +186,7 @@ NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_SET_PASSWORD(Packet *
|
|||||||
NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_SET_NAME(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CLIENT_SET_NAME); }
|
NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_SET_NAME(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CLIENT_SET_NAME); }
|
||||||
NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_QUIT(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CLIENT_QUIT); }
|
NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_QUIT(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CLIENT_QUIT); }
|
||||||
NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_ERROR(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CLIENT_ERROR); }
|
NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_ERROR(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CLIENT_ERROR); }
|
||||||
|
NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_DESYNC_LOG(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CLIENT_DESYNC_LOG); }
|
||||||
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_QUIT(Packet *p) { return this->ReceiveInvalidPacket(PACKET_SERVER_QUIT); }
|
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_QUIT(Packet *p) { return this->ReceiveInvalidPacket(PACKET_SERVER_QUIT); }
|
||||||
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_ERROR_QUIT(Packet *p) { return this->ReceiveInvalidPacket(PACKET_SERVER_ERROR_QUIT); }
|
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_ERROR_QUIT(Packet *p) { return this->ReceiveInvalidPacket(PACKET_SERVER_ERROR_QUIT); }
|
||||||
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_SHUTDOWN(Packet *p) { return this->ReceiveInvalidPacket(PACKET_SERVER_SHUTDOWN); }
|
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_SHUTDOWN(Packet *p) { return this->ReceiveInvalidPacket(PACKET_SERVER_SHUTDOWN); }
|
||||||
|
@@ -121,6 +121,7 @@ enum PacketGameType {
|
|||||||
PACKET_SERVER_QUIT, ///< A server tells that a client has quit.
|
PACKET_SERVER_QUIT, ///< A server tells that a client has quit.
|
||||||
PACKET_CLIENT_ERROR, ///< A client reports an error to the server.
|
PACKET_CLIENT_ERROR, ///< A client reports an error to the server.
|
||||||
PACKET_SERVER_ERROR_QUIT, ///< A server tells that a client has hit an error and did quit.
|
PACKET_SERVER_ERROR_QUIT, ///< A server tells that a client has hit an error and did quit.
|
||||||
|
PACKET_CLIENT_DESYNC_LOG, ///< A client reports a desync log
|
||||||
|
|
||||||
PACKET_END, ///< Must ALWAYS be on the end of this list!! (period)
|
PACKET_END, ///< Must ALWAYS be on the end of this list!! (period)
|
||||||
};
|
};
|
||||||
@@ -426,6 +427,7 @@ protected:
|
|||||||
* @param p The packet that was just received.
|
* @param p The packet that was just received.
|
||||||
*/
|
*/
|
||||||
virtual NetworkRecvStatus Receive_CLIENT_ERROR(Packet *p);
|
virtual NetworkRecvStatus Receive_CLIENT_ERROR(Packet *p);
|
||||||
|
virtual NetworkRecvStatus Receive_CLIENT_DESYNC_LOG(Packet *p);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notification that a client left the game:
|
* Notification that a client left the game:
|
||||||
|
@@ -174,16 +174,22 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::CloseConnection(NetworkRecvSta
|
|||||||
*/
|
*/
|
||||||
if (this->sock == INVALID_SOCKET) return status;
|
if (this->sock == INVALID_SOCKET) return status;
|
||||||
|
|
||||||
DEBUG(net, 1, "Closed client connection %d", this->client_id);
|
DEBUG(net, 1, "Shutting down client connection %d", this->client_id);
|
||||||
|
|
||||||
|
SetBlocking(this->sock);
|
||||||
|
|
||||||
this->SendPackets(true);
|
this->SendPackets(true);
|
||||||
|
|
||||||
|
ShutdownSocket(this->sock, false, true, 2);
|
||||||
|
|
||||||
/* Wait a number of ticks so our leave message can reach the server.
|
/* Wait a number of ticks so our leave message can reach the server.
|
||||||
* This is especially needed for Windows servers as they seem to get
|
* This is especially needed for Windows servers as they seem to get
|
||||||
* the "socket is closed" message before receiving our leave message,
|
* the "socket is closed" message before receiving our leave message,
|
||||||
* which would trigger the server to close the connection as well. */
|
* which would trigger the server to close the connection as well. */
|
||||||
CSleep(3 * MILLISECONDS_PER_TICK);
|
CSleep(3 * MILLISECONDS_PER_TICK);
|
||||||
|
|
||||||
|
DEBUG(net, 1, "Shutdown client connection %d", this->client_id);
|
||||||
|
|
||||||
delete this->GetInfo();
|
delete this->GetInfo();
|
||||||
delete this;
|
delete this;
|
||||||
|
|
||||||
@@ -223,6 +229,8 @@ void ClientNetworkGameSocketHandler::ClientError(NetworkRecvStatus res)
|
|||||||
SendError(errorno);
|
SendError(errorno);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->SendPackets();
|
||||||
|
|
||||||
ClientNetworkEmergencySave();
|
ClientNetworkEmergencySave();
|
||||||
|
|
||||||
_switch_mode = SM_MENU;
|
_switch_mode = SM_MENU;
|
||||||
@@ -281,9 +289,11 @@ void ClientNetworkGameSocketHandler::ClientError(NetworkRecvStatus res)
|
|||||||
NetworkError(STR_NETWORK_ERROR_DESYNC);
|
NetworkError(STR_NETWORK_ERROR_DESYNC);
|
||||||
DEBUG(desync, 1, "sync_err: date{%08x; %02x; %02x}", _date, _date_fract, _tick_skip_counter);
|
DEBUG(desync, 1, "sync_err: date{%08x; %02x; %02x}", _date, _date_fract, _tick_skip_counter);
|
||||||
DEBUG(net, 0, "Sync error detected!");
|
DEBUG(net, 0, "Sync error detected!");
|
||||||
my_client->ClientError(NETWORK_RECV_STATUS_DESYNC);
|
|
||||||
|
|
||||||
CrashLog::DesyncCrashLog();
|
std::string desync_log;
|
||||||
|
CrashLog::DesyncCrashLog(nullptr, &desync_log);
|
||||||
|
my_client->SendDesyncLog(desync_log);
|
||||||
|
my_client->ClientError(NETWORK_RECV_STATUS_DESYNC);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -469,6 +479,22 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendError(NetworkErrorCode err
|
|||||||
return NETWORK_RECV_STATUS_OKAY;
|
return NETWORK_RECV_STATUS_OKAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Send an error-packet over the network */
|
||||||
|
NetworkRecvStatus ClientNetworkGameSocketHandler::SendDesyncLog(const std::string &log)
|
||||||
|
{
|
||||||
|
for (size_t offset = 0; offset < log.size();) {
|
||||||
|
size_t size = min<size_t>(log.size() - offset, SHRT_MAX - 2);
|
||||||
|
|
||||||
|
Packet *p = new Packet(PACKET_CLIENT_DESYNC_LOG);
|
||||||
|
p->Send_uint16(size);
|
||||||
|
p->Send_binary(log.data() + offset, size);
|
||||||
|
my_client->SendPacket(p);
|
||||||
|
|
||||||
|
offset += size;
|
||||||
|
}
|
||||||
|
return NETWORK_RECV_STATUS_OKAY;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tell the server that we like to change the password of the company.
|
* Tell the server that we like to change the password of the company.
|
||||||
* @param password The new password.
|
* @param password The new password.
|
||||||
|
@@ -86,6 +86,7 @@ public:
|
|||||||
static NetworkRecvStatus SendJoin();
|
static NetworkRecvStatus SendJoin();
|
||||||
static NetworkRecvStatus SendCommand(const CommandPacket *cp);
|
static NetworkRecvStatus SendCommand(const CommandPacket *cp);
|
||||||
static NetworkRecvStatus SendError(NetworkErrorCode errorno);
|
static NetworkRecvStatus SendError(NetworkErrorCode errorno);
|
||||||
|
static NetworkRecvStatus SendDesyncLog(const std::string &log);
|
||||||
static NetworkRecvStatus SendQuit();
|
static NetworkRecvStatus SendQuit();
|
||||||
static NetworkRecvStatus SendAck();
|
static NetworkRecvStatus SendAck();
|
||||||
|
|
||||||
|
@@ -1171,7 +1171,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ERROR(Packet *p
|
|||||||
NetworkAdminClientError(this->client_id, errorno);
|
NetworkAdminClientError(this->client_id, errorno);
|
||||||
|
|
||||||
if (errorno == NETWORK_ERROR_DESYNC) {
|
if (errorno == NETWORK_ERROR_DESYNC) {
|
||||||
CrashLog::DesyncCrashLog();
|
CrashLog::DesyncCrashLog(&(this->desync_log), nullptr);
|
||||||
|
|
||||||
// have the server and all clients run some sanity checks
|
// have the server and all clients run some sanity checks
|
||||||
NetworkSendCommand(0, 0, 0, CMD_DESYNC_CHECK, nullptr, nullptr, _local_company, 0);
|
NetworkSendCommand(0, 0, 0, CMD_DESYNC_CHECK, nullptr, nullptr, _local_company, 0);
|
||||||
@@ -1180,6 +1180,16 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ERROR(Packet *p
|
|||||||
return this->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
|
return this->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_DESYNC_LOG(Packet *p)
|
||||||
|
{
|
||||||
|
uint size = p->Recv_uint16();
|
||||||
|
this->desync_log.resize(this->desync_log.size() + size);
|
||||||
|
p->Recv_binary(const_cast<char *>(this->desync_log.data() + this->desync_log.size() - size), size);
|
||||||
|
DEBUG(net, 2, "Received %u bytes of client desync log", size);
|
||||||
|
this->receive_limit += p->size;
|
||||||
|
return NETWORK_RECV_STATUS_OKAY;
|
||||||
|
}
|
||||||
|
|
||||||
NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_QUIT(Packet *p)
|
NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_QUIT(Packet *p)
|
||||||
{
|
{
|
||||||
/* The client wants to leave. Display this and report it to the other
|
/* The client wants to leave. Display this and report it to the other
|
||||||
|
@@ -38,6 +38,7 @@ protected:
|
|||||||
NetworkRecvStatus Receive_CLIENT_SET_NAME(Packet *p) override;
|
NetworkRecvStatus Receive_CLIENT_SET_NAME(Packet *p) override;
|
||||||
NetworkRecvStatus Receive_CLIENT_QUIT(Packet *p) override;
|
NetworkRecvStatus Receive_CLIENT_QUIT(Packet *p) override;
|
||||||
NetworkRecvStatus Receive_CLIENT_ERROR(Packet *p) override;
|
NetworkRecvStatus Receive_CLIENT_ERROR(Packet *p) override;
|
||||||
|
NetworkRecvStatus Receive_CLIENT_DESYNC_LOG(Packet *p) override;
|
||||||
NetworkRecvStatus Receive_CLIENT_RCON(Packet *p) override;
|
NetworkRecvStatus Receive_CLIENT_RCON(Packet *p) override;
|
||||||
NetworkRecvStatus Receive_CLIENT_NEWGRFS_CHECKED(Packet *p) override;
|
NetworkRecvStatus Receive_CLIENT_NEWGRFS_CHECKED(Packet *p) override;
|
||||||
NetworkRecvStatus Receive_CLIENT_MOVE(Packet *p) override;
|
NetworkRecvStatus Receive_CLIENT_MOVE(Packet *p) override;
|
||||||
@@ -75,6 +76,8 @@ public:
|
|||||||
struct PacketWriter *savegame; ///< Writer used to write the savegame.
|
struct PacketWriter *savegame; ///< Writer used to write the savegame.
|
||||||
NetworkAddress client_address; ///< IP-address of the client (so he can be banned)
|
NetworkAddress client_address; ///< IP-address of the client (so he can be banned)
|
||||||
|
|
||||||
|
std::string desync_log;
|
||||||
|
|
||||||
ServerNetworkGameSocketHandler(SOCKET s);
|
ServerNetworkGameSocketHandler(SOCKET s);
|
||||||
~ServerNetworkGameSocketHandler();
|
~ServerNetworkGameSocketHandler();
|
||||||
|
|
||||||
|
@@ -516,8 +516,8 @@ void CDECL HandleCrash(int signum, siginfo_t *si, void *context)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void CrashLog::DesyncCrashLog()
|
/* static */ void CrashLog::DesyncCrashLog(const std::string *log_in, std::string *log_out)
|
||||||
{
|
{
|
||||||
CrashLogOSX log(CrashLogOSX::DesyncTag{});
|
CrashLogOSX log(CrashLogOSX::DesyncTag{});
|
||||||
log.MakeDesyncCrashLog();
|
log.MakeDesyncCrashLog(log_in, log_out);
|
||||||
}
|
}
|
||||||
|
@@ -620,8 +620,8 @@ static void CDECL HandleCrash(int signum)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void CrashLog::DesyncCrashLog()
|
/* static */ void CrashLog::DesyncCrashLog(const std::string *log_in, std::string *log_out)
|
||||||
{
|
{
|
||||||
CrashLogUnix log(CrashLogUnix::DesyncTag{});
|
CrashLogUnix log(CrashLogUnix::DesyncTag{});
|
||||||
log.MakeDesyncCrashLog();
|
log.MakeDesyncCrashLog(log_in, log_out);
|
||||||
}
|
}
|
||||||
|
@@ -612,10 +612,10 @@ static void CDECL CustomAbort(int signal)
|
|||||||
SetUnhandledExceptionFilter(ExceptionHandler);
|
SetUnhandledExceptionFilter(ExceptionHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void CrashLog::DesyncCrashLog()
|
/* static */ void CrashLog::DesyncCrashLog(const std::string *log_in, std::string *log_out)
|
||||||
{
|
{
|
||||||
CrashLogWindows log(nullptr);
|
CrashLogWindows log(nullptr);
|
||||||
log.MakeDesyncCrashLog();
|
log.MakeDesyncCrashLog(log_in, log_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The crash log GUI */
|
/* The crash log GUI */
|
||||||
|
Reference in New Issue
Block a user