Add any output from CheckCaches to desync log

desync-debugging
Jonathan G Rennison 5 years ago
parent e1274b420a
commit 9b74b979c8

@ -37,6 +37,8 @@
#include "table/strings.h"
#include <functional>
#include "safeguards.h"
void ClearEnginesHiddenFlagOfCompany(CompanyID cid);
@ -902,8 +904,8 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
if (StoryPage::GetNumItems() == 0 || Goal::GetNumItems() == 0) InvalidateWindowData(WC_MAIN_TOOLBAR, 0);
extern void CheckCaches(bool force_check);
CheckCaches(true);
extern void CheckCaches(bool force_check, std::function<void(const char *)> log);
CheckCaches(true, nullptr);
break;
}

@ -41,6 +41,8 @@
#include <time.h>
#include "string_func.h"
#include <functional>
#include "safeguards.h"
/* scriptfile handling */
@ -2049,8 +2051,8 @@ DEF_CONSOLE_CMD(ConCheckCaches)
if (broadcast) {
DoCommandP(0, 0, 0, CMD_DESYNC_CHECK);
} else {
extern void CheckCaches(bool force_check);
CheckCaches(true);
extern void CheckCaches(bool force_check, std::function<void(const char *)> log);
CheckCaches(true, nullptr);
}
return true;

@ -34,6 +34,7 @@
#include "company_base.h"
#include "company_func.h"
#include <functional>
#include <time.h>
#ifdef WITH_ALLEGRO
@ -398,6 +399,15 @@ char *CrashLog::FillDesyncCrashLog(char *buffer, const char *last) const
buffer = this->LogRecentNews(buffer, last);
buffer = this->LogRecentCommands(buffer, last);
bool have_cache_log = false;
extern void CheckCaches(bool force_check, std::function<void(const char *)> log);
CheckCaches(true, [&](const char *str) {
if (!have_cache_log) buffer += seprintf(buffer, last, "CheckCaches:\n");
buffer += seprintf(buffer, last, " %s\n", str);
have_cache_log = true;
});
if (have_cache_log) buffer += seprintf(buffer, last, "\n");
buffer += seprintf(buffer, last, "*** End of OpenTTD Multiplayer %s Desync Report ***\n", _network_server ? "Server" : "Client");
return buffer;
}

@ -52,6 +52,8 @@
#include "table/strings.h"
#include "table/pricebase.h"
#include <functional>
#include "safeguards.h"
@ -1990,8 +1992,8 @@ static void DoAcquireCompany(Company *c)
delete c;
extern void CheckCaches(bool force_check);
CheckCaches(true);
extern void CheckCaches(bool force_check, std::function<void(const char *)> log);
CheckCaches(true, nullptr);
}
extern int GetAmountOwnedBy(const Company *c, Owner owner);

@ -279,9 +279,6 @@ void ClientNetworkGameSocketHandler::ClientError(NetworkRecvStatus res)
my_client->ClientError(NETWORK_RECV_STATUS_DESYNC);
CrashLog::DesyncCrashLog();
extern void CheckCaches(bool force_check);
CheckCaches(true);
return false;
}

@ -65,11 +65,13 @@
#include "viewport_sprite_sorter.h"
#include "framerate_type.h"
#include "industry.h"
#include "string_func.h"
#include "linkgraph/linkgraphschedule.h"
#include <stdarg.h>
#include <system_error>
#include <functional>
#include "safeguards.h"
@ -1136,7 +1138,7 @@ void SwitchToMode(SwitchMode new_mode)
* the cached value and what the value would
* be when calculated from the 'base' data.
*/
void CheckCaches(bool force_check)
void CheckCaches(bool force_check, std::function<void(const char *)> log)
{
if (!force_check) {
/* Return here so it is easy to add checks that are run
@ -1146,6 +1148,13 @@ void CheckCaches(bool force_check)
if (_debug_desync_level == 1 && _tick_counter % 500 != 0) return;
}
char cclog_buffer[1024];
#define CCLOG(...) { \
seprintf(cclog_buffer, lastof(cclog_buffer), __VA_ARGS__); \
DEBUG(desync, 0, "%s", cclog_buffer); \
if (log) log(cclog_buffer); \
}
/* Check the town caches. */
std::vector<TownCache> old_town_caches;
for (const Town *t : Town::Iterate()) {
@ -1159,7 +1168,7 @@ void CheckCaches(bool force_check)
uint i = 0;
for (Town *t : Town::Iterate()) {
if (MemCmpT(old_town_caches.data() + i, &t->cache) != 0) {
DEBUG(desync, 0, "town cache mismatch: town %i", (int)t->index);
CCLOG("town cache mismatch: town %i", (int)t->index);
}
i++;
}
@ -1174,12 +1183,18 @@ void CheckCaches(bool force_check)
i = 0;
for (const Company *c : Company::Iterate()) {
if (MemCmpT(old_infrastructure.data() + i, &c->infrastructure) != 0) {
DEBUG(desync, 0, "infrastructure cache mismatch: company %i", (int)c->index);
CCLOG("infrastructure cache mismatch: company %i", (int)c->index);
char buffer[4096];
old_infrastructure.Get(i)->Dump(buffer, lastof(buffer));
DEBUG(desync, 0, "Previous:\n%s", buffer);
old_infrastructure[i].Dump(buffer, lastof(buffer));
CCLOG("Previous:");
ProcessLineByLine(buffer, [&](const char *line) {
CCLOG(" %s", line);
});
c->infrastructure.Dump(buffer, lastof(buffer));
DEBUG(desync, 0, "Recalculated:\n%s", buffer);
CCLOG("Recalculated:");
ProcessLineByLine(buffer, [&](const char *line) {
CCLOG(" %s", line);
});
}
i++;
}
@ -1249,49 +1264,49 @@ void CheckCaches(bool force_check)
for (const Vehicle *u = v; u != nullptr; u = u->Next()) {
FillNewGRFVehicleCache(u);
if (memcmp(&grf_cache[length], &u->grf_cache, sizeof(NewGRFCache)) != 0) {
DEBUG(desync, 0, "newgrf cache mismatch: type %i, vehicle %i, company %i, unit number %i, wagon %i", (int)v->type, v->index, (int)v->owner, v->unitnumber, length);
CCLOG("newgrf cache mismatch: type %i, vehicle %i, company %i, unit number %i, wagon %i", (int)v->type, v->index, (int)v->owner, v->unitnumber, length);
}
if (memcmp(&veh_cache[length], &u->vcache, sizeof(VehicleCache)) != 0) {
DEBUG(desync, 0, "vehicle cache mismatch: type %i, vehicle %i, company %i, unit number %i, wagon %i", (int)v->type, v->index, (int)v->owner, v->unitnumber, length);
}
if (veh_old[length]->acceleration != u->acceleration) {
DEBUG(desync, 0, "acceleration mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length);
CCLOG("acceleration mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length);
}
if (veh_old[length]->breakdown_chance != u->breakdown_chance) {
DEBUG(desync, 0, "breakdown_chance mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length);
CCLOG("breakdown_chance mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length);
}
if (veh_old[length]->breakdowns_since_last_service != u->breakdowns_since_last_service) {
DEBUG(desync, 0, "breakdowns_since_last_service mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length);
CCLOG("breakdowns_since_last_service mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length);
}
if (veh_old[length]->vehicle_flags != u->vehicle_flags) {
DEBUG(desync, 0, "vehicle_flags mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length);
CCLOG("vehicle_flags mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length);
}
switch (u->type) {
case VEH_TRAIN:
if (memcmp(&gro_cache[length], &Train::From(u)->gcache, sizeof(GroundVehicleCache)) != 0) {
DEBUG(desync, 0, "train ground vehicle cache mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length);
CCLOG("train ground vehicle cache mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length);
}
if (memcmp(&tra_cache[length], &Train::From(u)->tcache, sizeof(TrainCache)) != 0) {
DEBUG(desync, 0, "train cache mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length);
CCLOG("train cache mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length);
}
if (Train::From(veh_old[length])->railtype != Train::From(u)->railtype) {
DEBUG(desync, 0, "railtype mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length);
CCLOG("railtype mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length);
}
if (Train::From(veh_old[length])->compatible_railtypes != Train::From(u)->compatible_railtypes) {
DEBUG(desync, 0, "compatible_railtypes mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length);
CCLOG("compatible_railtypes mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length);
}
if (Train::From(veh_old[length])->flags != Train::From(u)->flags) {
DEBUG(desync, 0, "flags mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length);
CCLOG("flags mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length);
}
break;
case VEH_ROAD:
if (memcmp(&gro_cache[length], &RoadVehicle::From(u)->gcache, sizeof(GroundVehicleCache)) != 0) {
DEBUG(desync, 0, "road vehicle ground vehicle cache mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length);
CCLOG("road vehicle ground vehicle cache mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length);
}
break;
case VEH_AIRCRAFT:
if (memcmp(&air_cache[length], &Aircraft::From(u)->acache, sizeof(AircraftCache)) != 0) {
DEBUG(desync, 0, "Aircraft vehicle cache mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length);
CCLOG("Aircraft vehicle cache mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length);
}
break;
default:
@ -1372,6 +1387,8 @@ void CheckCaches(bool force_check)
}
i++;
}
#undef CCLOG
}
/**
@ -1386,7 +1403,7 @@ void CheckCaches(bool force_check)
CommandCost CmdDesyncCheck(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
if (flags & DC_EXEC) {
CheckCaches(true);
CheckCaches(true, nullptr);
}
return CommandCost();
@ -1440,7 +1457,7 @@ void StateGameLoop()
SaveOrLoad(name, SLO_SAVE, DFT_GAME_FILE, AUTOSAVE_DIR, false);
}
CheckCaches(false);
CheckCaches(false, nullptr);
/* All these actions has to be done from OWNER_NONE
* for multiplayer compatibility */

Loading…
Cancel
Save