From 1d3adb2b66989630b2a3c201ac1210a886d41a51 Mon Sep 17 00:00:00 2001 From: frosch Date: Sat, 5 Jun 2010 12:16:12 +0000 Subject: [PATCH] (svn r19931) -Fix (r19914): Convert assertion in Backup<> destructor into DEBUG() output. It was triggered on exceptions, especially when aborting world generation. --- src/ai/ai_core.cpp | 12 ++++++------ src/ai/ai_gui.cpp | 8 ++++---- src/aircraft_cmd.cpp | 6 +++--- src/core/backup_type.hpp | 21 ++++++++++++++++++--- src/debug.h | 3 +++ src/disaster_cmd.cpp | 4 ++-- src/economy.cpp | 12 ++++++------ src/industry_cmd.cpp | 14 +++++++------- src/industry_gui.cpp | 2 +- src/misc_cmd.cpp | 2 +- src/openttd.cpp | 2 +- src/rail_cmd.cpp | 2 +- src/roadveh_cmd.cpp | 2 +- src/saveload/afterload.cpp | 2 +- src/town_cmd.cpp | 6 +++--- src/vehicle.cpp | 4 ++-- src/water_cmd.cpp | 4 ++-- 17 files changed, 62 insertions(+), 44 deletions(-) diff --git a/src/ai/ai_core.cpp b/src/ai/ai_core.cpp index f61bc058c8..8d333877fd 100644 --- a/src/ai/ai_core.cpp +++ b/src/ai/ai_core.cpp @@ -69,7 +69,7 @@ assert(_settings_game.difficulty.competitor_speed <= 4); if ((AI::frame_counter & ((1 << (4 - _settings_game.difficulty.competitor_speed)) - 1)) != 0) return; - Backup cur_company(_current_company); + Backup cur_company(_current_company, FILE_LINE); const Company *c; FOR_ALL_COMPANIES(c) { if (c->is_ai) { @@ -96,7 +96,7 @@ { if (_networking && !_network_server) return; - Backup cur_company(_current_company, company); + Backup cur_company(_current_company, company, FILE_LINE); Company *c = Company::Get(company); delete c->ai_instance; @@ -112,7 +112,7 @@ { if (_networking && !_network_server) return; - Backup cur_company(_current_company, company); + Backup cur_company(_current_company, company, FILE_LINE); Company::Get(company)->ai_instance->Suspend(); cur_company.Restore(); @@ -201,7 +201,7 @@ } /* Queue the event */ - Backup cur_company(_current_company, company); + Backup cur_company(_current_company, company, FILE_LINE); AIEventController::InsertEvent(event); cur_company.Restore(); @@ -247,7 +247,7 @@ void CcAI(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) Company *c = Company::GetIfValid(company); assert(c != NULL && c->ai_instance != NULL); - Backup cur_company(_current_company, company); + Backup cur_company(_current_company, company, FILE_LINE); c->ai_instance->Save(); cur_company.Restore(); } else { @@ -261,7 +261,7 @@ void CcAI(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) Company *c = Company::GetIfValid(company); assert(c != NULL && c->ai_instance != NULL); - Backup cur_company(_current_company, company); + Backup cur_company(_current_company, company, FILE_LINE); c->ai_instance->Load(version); cur_company.Restore(); } else { diff --git a/src/ai/ai_gui.cpp b/src/ai/ai_gui.cpp index afad432f6c..91ebe07811 100644 --- a/src/ai/ai_gui.cpp +++ b/src/ai/ai_gui.cpp @@ -820,7 +820,7 @@ struct AIDebugWindow : public QueryStringBaseWindow { DrawCompanyIcon(i, button->pos_x + button->current_x / 2 - 7 + offset, this->GetWidget(AID_WIDGET_COMPANY_BUTTON_START + i)->pos_y + 2 + offset); } - Backup cur_company(_current_company, ai_debug_company); + Backup cur_company(_current_company, ai_debug_company, FILE_LINE); AILog::LogData *log = (AILog::LogData *)AIObject::GetLogPointer(); cur_company.Restore(); @@ -875,7 +875,7 @@ struct AIDebugWindow : public QueryStringBaseWindow { switch (widget) { case AID_WIDGET_LOG_PANEL: { - Backup cur_company(_current_company, ai_debug_company); + Backup cur_company(_current_company, ai_debug_company, FILE_LINE); AILog::LogData *log = (AILog::LogData *)AIObject::GetLogPointer(); cur_company.Restore(); if (log == NULL) return; @@ -914,7 +914,7 @@ struct AIDebugWindow : public QueryStringBaseWindow { this->RaiseWidget(ai_debug_company + AID_WIDGET_COMPANY_BUTTON_START); ai_debug_company = show_ai; - Backup cur_company(_current_company, ai_debug_company); + Backup cur_company(_current_company, ai_debug_company, FILE_LINE); AILog::LogData *log = (AILog::LogData *)AIObject::GetLogPointer(); cur_company.Restore(); this->vscroll.SetCount((log == NULL) ? 0 : log->used); @@ -1009,7 +1009,7 @@ struct AIDebugWindow : public QueryStringBaseWindow { /* If the log message is related to the active company tab, check the break string */ if (data == ai_debug_company && this->break_check_enabled && !StrEmpty(this->edit_str_buf)) { /* Get the log instance of the active company */ - Backup cur_company(_current_company, ai_debug_company); + Backup cur_company(_current_company, ai_debug_company, FILE_LINE); AILog::LogData *log = (AILog::LogData *)AIObject::GetLogPointer(); if (log != NULL && case_sensitive_break_check? diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index 450eb8b9b4..c4383b8862 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -1204,7 +1204,7 @@ void HandleMissingAircraftOrders(Aircraft *v) */ const Station *st = GetTargetAirportIfValid(v); if (st == NULL) { - Backup cur_company(_current_company, v->owner); + Backup cur_company(_current_company, v->owner, FILE_LINE); CommandCost ret = DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_SEND_AIRCRAFT_TO_HANGAR); cur_company.Restore(); @@ -1510,7 +1510,7 @@ static void AircraftEventHandler_HeliTakeOff(Aircraft *v, const AirportFTAClass /* Send the helicopter to a hangar if needed for replacement */ if (v->NeedsAutomaticServicing()) { - Backup cur_company(_current_company, v->owner); + Backup cur_company(_current_company, v->owner, FILE_LINE); DoCommand(v->tile, v->index, DEPOT_SERVICE | DEPOT_LOCATE_HANGAR, DC_EXEC, CMD_SEND_AIRCRAFT_TO_HANGAR); cur_company.Restore(); } @@ -1562,7 +1562,7 @@ static void AircraftEventHandler_Landing(Aircraft *v, const AirportFTAClass *apc /* check if the aircraft needs to be replaced or renewed and send it to a hangar if needed */ if (v->NeedsAutomaticServicing()) { - Backup cur_company(_current_company, v->owner); + Backup cur_company(_current_company, v->owner, FILE_LINE); DoCommand(v->tile, v->index, DEPOT_SERVICE, DC_EXEC, CMD_SEND_AIRCRAFT_TO_HANGAR); cur_company.Restore(); } diff --git a/src/core/backup_type.hpp b/src/core/backup_type.hpp index 90b48c2a8a..60799170f7 100644 --- a/src/core/backup_type.hpp +++ b/src/core/backup_type.hpp @@ -12,6 +12,8 @@ #ifndef BACKUP_TYPE_HPP #define BACKUP_TYPE_HPP +#include "../debug.h" + /** * Class to backup a specific variable and restore it later. * The variable is not restored automatically, but assertions make sure it is restored. @@ -22,16 +24,20 @@ struct Backup { /** * Backup variable. * @param original Variable to backup. + * @param file Filename for debug output. Use FILE_LINE macro. + * @param line Linenumber for debug output. Use FILE_LINE macro. */ - Backup(T &original) : original(original), valid(true), original_value(original) {} + Backup(T &original, const char * const file, const int line) : original(original), valid(true), original_value(original), file(file), line(line) {} /** * Backup variable and switch to new value. * @param original Variable to backup. * @param new_value New value for variable. + * @param file Filename for debug output. Use FILE_LINE macro. + * @param line Linenumber for debug output. Use FILE_LINE macro. */ template - Backup(T &original, const U &new_value) : original(original), valid(true), original_value(original) + Backup(T &original, const U &new_value, const char * const file, const int line) : original(original), valid(true), original_value(original), file(file), line(line) { /* Note: We use a separate typename U, so type conversions are handled by assignment operator. */ original = new_value; @@ -43,7 +49,13 @@ struct Backup { ~Backup() { /* Check whether restoration was done */ - assert(!this->valid); + if (this->valid) + { + /* We cannot assert here, as missing restoration is 'normal' when exceptions are thrown. + * Exceptions are especially used to abort world generation. */ + DEBUG(misc, 0, "%s:%d: Backupped value was not restored!", this->file, this->line); + this->Restore(); + } } /** @@ -129,6 +141,9 @@ private: T &original; bool valid; T original_value; + + const char * const file; + const int line; }; #endif /* BACKUP_TYPE_HPP */ diff --git a/src/debug.h b/src/debug.h index 35f74c2064..019f5d58dc 100644 --- a/src/debug.h +++ b/src/debug.h @@ -53,6 +53,9 @@ void SetDebugString(const char *s); const char *GetDebugString(); +/* Shorter form for passing filename and linenumber */ +#define FILE_LINE __FILE__, __LINE__ + /* Used for profiling * * Usage: diff --git a/src/disaster_cmd.cpp b/src/disaster_cmd.cpp index 44f27fa8a2..dcf3ef844a 100644 --- a/src/disaster_cmd.cpp +++ b/src/disaster_cmd.cpp @@ -73,7 +73,7 @@ static void DisasterClearSquare(TileIndex tile) switch (GetTileType(tile)) { case MP_RAILWAY: if (Company::IsHumanID(GetTileOwner(tile))) { - Backup cur_company(_current_company, OWNER_WATER); + Backup cur_company(_current_company, OWNER_WATER, FILE_LINE); DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); cur_company.Restore(); @@ -83,7 +83,7 @@ static void DisasterClearSquare(TileIndex tile) break; case MP_HOUSE: { - Backup cur_company(_current_company, OWNER_NONE); + Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); cur_company.Restore(); break; diff --git a/src/economy.cpp b/src/economy.cpp index 21e9516c3f..308334b1cd 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -305,7 +305,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) #endif /* ENABLE_NETWORK */ Town *t; - Backup cur_company(_current_company, old_owner); + Backup cur_company(_current_company, old_owner, FILE_LINE); assert(old_owner != new_owner); @@ -327,7 +327,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) } /* Sell all the shares that people have on this company */ - Backup cur_company2(_current_company); + Backup cur_company2(_current_company, FILE_LINE); c = Company::Get(old_owner); for (i = 0; i < 4; i++) { cur_company2.Change(c->share_owners[i]); @@ -553,7 +553,7 @@ static void CompaniesGenStatistics() Station *st; Company *c; - Backup cur_company(_current_company); + Backup cur_company(_current_company, FILE_LINE); FOR_ALL_STATIONS(st) { cur_company.Change(st->owner); CommandCost cost(EXPENSES_PROPERTY, _price[PR_STATION_VALUE] >> 1); @@ -688,7 +688,7 @@ static void CompaniesPayInterest() { const Company *c; - Backup cur_company(_current_company); + Backup cur_company(_current_company, FILE_LINE); FOR_ALL_COMPANIES(c) { cur_company.Change(c->index); @@ -1027,7 +1027,7 @@ CargoPayment::~CargoPayment() if (this->visual_profit == 0) return; - Backup cur_company(_current_company, this->front->owner); + Backup cur_company(_current_company, this->front->owner, FILE_LINE); SubtractMoneyFromCompany(CommandCost(this->front->GetExpenseType(true), -this->route_profit)); this->front->profit_this_year += this->visual_profit << 8; @@ -1458,7 +1458,7 @@ static void DoAcquireCompany(Company *c) } value = CalculateCompanyValue(c) >> 2; - Backup cur_company(_current_company); + Backup cur_company(_current_company, FILE_LINE); for (i = 0; i != 4; i++) { if (c->share_owners[i] != COMPANY_SPECTATOR) { cur_company.Change(c->share_owners[i]); diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index f425daf34e..1c72f6e4cf 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -1043,7 +1043,7 @@ static bool SearchLumberMillTrees(TileIndex tile, void *user_data) if (IsTileType(tile, MP_TREES) && GetTreeGrowth(tile) > 2) { ///< 3 and up means all fully grown trees /* found a tree */ - Backup cur_company(_current_company, OWNER_NONE); + Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); _industry_sound_ctr = 1; _industry_sound_tile = tile; @@ -1372,7 +1372,7 @@ static CommandCost CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTil } /* Clear the tiles as OWNER_TOWN to not affect town rating, and to not clear protected buildings */ - Backup cur_company(_current_company, OWNER_TOWN); + Backup cur_company(_current_company, OWNER_TOWN, FILE_LINE); CommandCost ret = DoCommand(cur_tile, 0, 0, DC_NONE, CMD_LANDSCAPE_CLEAR); cur_company.Restore(); @@ -1484,7 +1484,7 @@ static bool CheckIfCanLevelIndustryPlatform(TileIndex tile, DoCommandFlag flags, /* _current_company is OWNER_NONE for randomly generated industries and in editor, or the company who funded or prospected the industry. * Perform terraforming as OWNER_TOWN to disable autoslope and town ratings. */ - Backup cur_company(_current_company, OWNER_TOWN); + Backup cur_company(_current_company, OWNER_TOWN, FILE_LINE); TILE_LOOP(tile_walk, size_x, size_y, cur_tile) { curh = TileHeight(tile_walk); @@ -1788,7 +1788,7 @@ CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uin if (_game_mode != GM_EDITOR && _settings_game.construction.raw_industry_construction == 2 && indspec->IsRawIndustry()) { if (flags & DC_EXEC) { /* Prospected industries are build as OWNER_TOWN to not e.g. be build on owned land of the founder */ - Backup cur_company(_current_company, OWNER_TOWN); + Backup cur_company(_current_company, OWNER_TOWN, FILE_LINE); /* Prospecting has a chance to fail, however we cannot guarantee that something can * be built on the map, so the chance gets lower when the map is fuller, but there * is nothing we can really do about that. */ @@ -1890,7 +1890,7 @@ static const byte _numof_industry_table[]= { */ static void PlaceInitialIndustry(IndustryType type, bool try_hard) { - Backup cur_company(_current_company, OWNER_NONE); + Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); IncreaseGeneratingWorldProgress(GWP_INDUSTRY); @@ -2414,7 +2414,7 @@ void IndustryDailyLoop() return; // Nothing to do? get out } - Backup cur_company(_current_company, OWNER_NONE); + Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); /* perform the required industry changes for the day */ for (uint16 j = 0; j < change_loop; j++) { @@ -2439,7 +2439,7 @@ void IndustryDailyLoop() void IndustryMonthlyLoop() { Industry *i; - Backup cur_company(_current_company, OWNER_NONE); + Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); FOR_ALL_INDUSTRIES(i) { UpdateIndustryStatistics(i); diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index a0177fea38..7a032b813a 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -523,7 +523,7 @@ public: return; } - Backup cur_company(_current_company, OWNER_NONE); + Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); _generating_world = true; _ignore_restrictions = true; diff --git a/src/misc_cmd.cpp b/src/misc_cmd.cpp index 20a1103759..f4cc0534b8 100644 --- a/src/misc_cmd.cpp +++ b/src/misc_cmd.cpp @@ -230,7 +230,7 @@ CommandCost CmdGiveMoney(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 if (flags & DC_EXEC) { /* Add money to company */ - Backup cur_company(_current_company, dest_company); + Backup cur_company(_current_company, dest_company, FILE_LINE); SubtractMoneyFromCompany(CommandCost(EXPENSES_OTHER, -amount.GetCost())); cur_company.Restore(); } diff --git a/src/openttd.cpp b/src/openttd.cpp index 500ab077b0..0fca283a59 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -1216,7 +1216,7 @@ void StateGameLoop() /* All these actions has to be done from OWNER_NONE * for multiplayer compatibility */ - Backup cur_company(_current_company, OWNER_NONE); + Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); AnimateAnimatedTiles(); IncreaseDate(); diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index e7f99c2040..58d1f51911 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -642,7 +642,7 @@ bool FloodHalftile(TileIndex t) TrackBits to_remove = lower_track & rail_bits; if (to_remove != 0) { - Backup cur_company(_current_company, OWNER_WATER); + Backup cur_company(_current_company, OWNER_WATER, FILE_LINE); flooded = DoCommand(t, 0, FIND_FIRST_BIT(to_remove), DC_EXEC, CMD_REMOVE_SINGLE_RAIL).Succeeded(); cur_company.Restore(); if (!flooded) return flooded; // not yet floodable diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 67fa291efd..f8afb71785 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -1160,7 +1160,7 @@ static Trackdir FollowPreviousRoadVehicle(const RoadVehicle *v, const RoadVehicl static bool CanBuildTramTrackOnTile(CompanyID c, TileIndex t, RoadBits r) { /* The 'current' company is not necessarily the owner of the vehicle. */ - Backup cur_company(_current_company, c); + Backup cur_company(_current_company, c, FILE_LINE); CommandCost ret = DoCommand(t, ROADTYPE_TRAM << 4 | r, 0, DC_NONE, CMD_BUILD_ROAD); diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 59c7430120..5b9553be36 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -1571,7 +1571,7 @@ bool AfterLoadGame() if (IsBuoyTile(t) || IsDriveThroughStopTile(t) || IsTileType(t, MP_WATER)) { Owner o = GetTileOwner(t); if (o < MAX_COMPANIES && !Company::IsValidID(o)) { - Backup cur_company(_current_company, o); + Backup cur_company(_current_company, o, FILE_LINE); ChangeTileOwner(t, o, INVALID_OWNER); cur_company.Restore(); } diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 8cc3c59d9b..e0e5e00349 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -516,7 +516,7 @@ static void TileLoop_Town(TileIndex tile) } } - Backup cur_company(_current_company, OWNER_TOWN); + Backup cur_company(_current_company, OWNER_TOWN, FILE_LINE); if ((hs->building_flags & BUILDING_HAS_1_TILE) && HasBit(t->flags, TOWN_IS_FUNDED) && @@ -1297,7 +1297,7 @@ static bool GrowTown(Town *t) }; /* Current "company" is a town */ - Backup cur_company(_current_company, OWNER_TOWN); + Backup cur_company(_current_company, OWNER_TOWN, FILE_LINE); TileIndex tile = t->xy; // The tile we are working with ATM @@ -2383,7 +2383,7 @@ static bool DoBuildStatueOfCompany(TileIndex tile, TownID town_id) return false; } - Backup cur_company(_current_company, OWNER_NONE); + Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); CommandCost r = DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); cur_company.Restore(); diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 30bd2f74b4..7e97c465f4 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -773,7 +773,7 @@ void CallVehicleTicks() } } - Backup cur_company(_current_company); + Backup cur_company(_current_company, FILE_LINE); for (AutoreplaceMap::iterator it = _vehicles_to_autoreplace.Begin(); it != _vehicles_to_autoreplace.End(); it++) { v = it->first; /* Autoreplace needs the current company set as the vehicle owner */ @@ -1112,7 +1112,7 @@ void VehicleEnterDepot(Vehicle *v) } if (t.IsRefit()) { - Backup cur_company(_current_company, v->owner); + Backup cur_company(_current_company, v->owner, FILE_LINE); CommandCost cost = DoCommand(v->tile, v->index, t.GetRefitCargo() | t.GetRefitSubtype() << 8, DC_EXEC, GetCmdRefitVeh(v)); cur_company.Restore(); diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index 6912d07eca..ae8d522716 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -882,7 +882,7 @@ void DoFloodTile(TileIndex target) bool flooded = false; // Will be set to true if something is changed. - Backup cur_company(_current_company, OWNER_WATER); + Backup cur_company(_current_company, OWNER_WATER, FILE_LINE); Slope tileh = GetTileSlope(target, NULL); if (tileh != SLOPE_FLAT) { @@ -942,7 +942,7 @@ void DoFloodTile(TileIndex target) */ static void DoDryUp(TileIndex tile) { - Backup cur_company(_current_company, OWNER_WATER); + Backup cur_company(_current_company, OWNER_WATER, FILE_LINE); switch (GetTileType(tile)) { case MP_RAILWAY: