ctd - FAssertMsg(eTeam != NO_TEAM, "eTeam is not assigned a valid value")

keldath

LivE LonG AnD PrOsPeR
Joined
Dec 20, 2005
Messages
7,578
Location
israel
hi,

i have a ctd happening in my mod cause of this part:

any ideas?

bool CvPlot::isNetworkTerrain(TeamTypes eTeam) const
{
FAssertMsg(eTeam != NO_TEAM, "eTeam is not assigned a valid value");
FAssertMsg(getTerrainType() != NO_TERRAIN, "TerrainType is not assigned a valid value");

if (GET_TEAM(eTeam).isTerrainTrade(getTerrainType()))
{
return true;
}

if (isWater())
{
if (getTeam() == eTeam)
{
return true;
}
}

return false;
}
 
The problem is that something calls this function with the argument NO_TEAM and that will crash the game when reaching GET_TEAM(). Since the problem is with the caller and not this function, it is impossible to tell what went wrong based on this thread.

What should be done is to attach a debugger to a debug dll, trigger the assert and use the stack to see who called this and where the argument is generated. Sometimes it is trivial to fix once you know where it was called from and sometimes it's real detective work to track where each variable is set and why.
 
Thanks for the answer,
So, ive spent over 4 hours on this problem,
You say that sonething that calls for the function is the problem, from what you explained, i can gather thar the problem might be some missing tag in the xml for instance?

Ill fallow what youve written at your help thread.
 
i can gather thar the problem might be some missing tag in the xml for instance?
It's plausible as some xml tags can trigger asserts and even crashes if set incorrectly. However I can't think of anything in xml, which would set team incorrectly. Using the debugger to get the call stack seems to be the only way to figure out what caused the argument to become wrong.
 
ok, ive used the call stack, and ive learnt to use the watch,

i foudn the source ! its that mod again that you fixed for me nnightinggale,

this is the problematic code - any ideas how to fix? the bold part is the cause.

Code:
//Shqype Vicinity Bonus Start
		bRequiresBonus = false;
		bNeedsBonus = true;

		for (iI = 0; iI < GC.getNUM_BUILDING_PREREQ_OR_BONUSES(); iI++)
		{
			if (kBuilding.getPrereqOrVicinityBonuses(iI) != NO_BONUS)
			{
				bRequiresBonus = true;

				for (int iJ = 0; iJ < NUM_CITY_PLOTS; ++iJ)
				{
					CvPlot* pLoopPlot = plotCity(getX_INLINE(), getY_INLINE(), iJ);
					if (pLoopPlot->getBonusType() == kBuilding.getPrereqOrVicinityBonuses(iI))
					{[B][U]
						CvCity* pCity = GC.getMapINLINE().findCity(getX_INLINE(), getY_INLINE(), getOwnerINLINE(), NO_TEAM, false);[/U][/B]
						if (pLoopPlot->isHasValidBonus() && pLoopPlot->isConnectedTo(pCity))
						{
			                bNeedsBonus = false;
							return true;
						}
					}
				}
				bNeedsBonus = true;
			}
		}

		if (bRequiresBonus && bNeedsBonus)
		{
			return false;
		}
//Shqype Vicinity Bonus End

i have tried to implement the fix you gave me a while back, but it didnt help :( :

Code:
CvPlot* pLoopPlot = plotCity(getX_INLINE(), getY_INLINE(), iI);
				if (pLoopPlot != NULL && pLoopPlot->getBonusType() == kBuilding.getPrereqVicinityBonus())
				{
					CvCity* pCity = GC.getMapINLINE().findCity(getX_INLINE(), getY_INLINE(), getOwnerINLINE(), NO_TEAM, false);
					if (pLoopPlot != NULL && pLoopPlot->isHasValidBonus() && pLoopPlot->isConnectedTo(pCity))
					{
						return true;
 
Code:
CvCity* pCity = GC.getMapINLINE().findCity(getX_INLINE(), getY_INLINE(), getOwnerINLINE(), NO_TEAM, false);[/U][/B]
if (pLoopPlot->isHasValidBonus() && pLoopPlot->isConnectedTo(pCity))
Now that I think about that section, I wonder why it isn't just written like this:
Code:
if (pLoopPlot->isHasValidBonus() && pLoopPlot->isConnectedTo([B]this[/B]))
this is the pointer to the object itself, in this case since it is CvCity, it is a pointer to the city, which called canConstruct() in the first place.

I'm still not sure why it crashes on the line, which searches for the city, but if that line can be avoided entirely, then the bug will go away. Also just using an existing pointer rather than searching for a city will be faster. Somehow I wonder if it would be worth it to make a modcomp of the Shqype Vicinity Bonus feature while reviewing every single line. This is the second time it caused a crash and both blocks of //Shqype Vicinity Bonus Start in CvCplayer.cpp seem to suffer from not using this. It's clearly not the best written code I have seen. The idea for it is great though.
 
humm....

i saw the "this" suggestion over the original mod thread, but it didnt work also.

second time indeed, for now i removed the code, and the ctd is gone (same save file), so ill guess ill have to let go of this mod part, luckily , platyping have created a python mod that uses python callbacks, and presents with a varsity of requirement tags, such as the vicinity tag.
ill have to use this then.

thanks my friend.


edit:
well your simple "this" worked....though, not sure ill keep this unstable mod :)
 
luckily , platyping have created a python mod that uses python callbacks, and presents with a varsity of requirement tags, such as the vicinity tag.
well your simple "this" worked....though, not sure ill keep this unstable mod :)
The problem with python is that it is slow and canConstruct is not a rarely used function. The best solution would likely be to review all the source code and do it right in the DLL. It would appear that the feature does work, but it isn't protected against borderline cases.
 
Back
Top Bottom