CvDLLButtonPopup - bug

Ferocca

Warlord
Joined
Nov 21, 2011
Messages
179
Hi folks,

I finally have come to the point that I can compile a (debug) DLL and use it. On the other hand, I am still a nobody at the actual coding. So I can provide all the necessary information on the bug, but have no idea how to fix the bug. That's where I ask your help :)
The message I get when the bug occurs:

Assert Failed
File: CvGlobals.cpp
Line: 1169
Expression: e > -1
Message:

In the callstack I could read that it had to do with the popup when you have to choose what to produce next - the bug occurs after finishing a production, and if you for example make a list of productions, the game won't crash after finishing the productions in the list, till you finish the last production: for this causes the production-choose popup to appear, and this, for some reason, crashes the game.

This mod is RevDCM with some new Civs, Leaders, UBs and UUs I added myself. No missing art files though (checked with CivCheck) and I really don't see how pure XML-additions can crash the game in the SDK.

If you need to know more or need me to do something, no problem of course, if you are ready to help me then I really should be ready to help you with helping me!
 
I don't have plain RevDCM to make sure that what the assert is happening for is the same as for regular BtS, so this will likely be wrong if it is not related to EntityEventTypes...

The thing that comes to mind is that it is unit related, but possibly indirectly.

Perhaps a worker that specifies and invalid build type, but that doesn't seem likely for this error. More likely is a build (in CIV4BuildInfos.xml) that has an invalid EntityEvent value. If you didn't modify that file then this is probably not it.

Another possibility is that it could be an invalid FormationType entry on a unit. I think it could also happen if you specify a valid formation type, but specify a number of units in the UnitMeshGroups which the formation type does not support. Or, if you added a formation type, it may refer to an invalid EventType entity. This sort if thing is probably the most likely thing (of the couple of thing's I've though of), especially if you did not modify the build infos.

Pure XML changes can crash the game if it leads to an invalid value being used by the DLL or EXE for something that does not validate the number it is trying to use. A lot of times this is from looking up a value for a key that does not exist (like SOMETYPE_SOMETHING) which leads to it using the value -1 (which is what it uses for the "no such thing" value) and then trying to use that value as the index into an array. Arrays do not have an index of -1 (well, not normally), but C++ will let you try anyway. What it ends up doing in such a case is using whatever happens to be in memory just before the start of the array. This can cause it to fail in a number of different ways. One such way is that he array is an array of pointers so the value right before the actual start of the array is interpreted as an address where there is supposed to be some data. That address may not be valid at all, referring to a memory range which has never been allocated or that is allocated to the system part of the virtual memory instead of the user part (normally in 32-bit windows the 4GB of virtual memory space is split between 2GB for user and 2GB for system, the "3GB switch" changes that to 3GB and 1GB for user and system). Things like that can crash the program from simple, but wrong, XML changes.

Ideally, from a stability standpoint, every value passed to every function would be validated by the function (this is what the Asserts are doing, but they only function when the DLL is compiled as a Debug version and they are not used everywhere they could be even then) and if the value is not valid some reasonable default setting would be used to produce a valid (if not necessarily appropriate) result - or some useful error message indicating the exact problem would be produced (which is not always practical since a function does not know why it was called or where the data it was passed came from, leading to the need for error handling that could get a bit complex if you really wanted to do this). However all this takes time resulting in slower, possibly much slower, software. So the Civ4 DLL only does a very limited amount of validation when compiled as Release, and more when compiled as Debug but still not completely checking everything everywhere. In your case the checking it does in Debug mode did spot the problem, popping up the assert failure message, but what is causing it was not clear to you.
 
Thank you, God-Emperor for this explanation! It is useful for me as well to understand an error that I have, similar to this one:

CvGlobals.cpp, line 1985, FAssert(eBuildingNum > -1);

The line refers to K-Mod as I'm trying to "merge" Pie's Ancient Europe with Karadoc's K-Mod. "Merge" might not be the appropriate term for the DLL since Pie's Ancient Europe doesn't have a custom one.

Here, same as well, no clue what really triggers it but it leads automatically to a crash in mid-term game (probably because before a certain tech you can't build it).

I came to the conclusion that it comes indeed from a building by using the vanilla ones instead. I could then continue a save game that crashed before. Now I have to find which building!

Still, I don't understand why the building is accepted by vanilla dll and not by K-Mod's one, but that's another question.

Thanks again, really helpful. And thanks to Ferocca for bringing this up!
 
Thank you for the explanation God-Emperor, this should give me a clue where/how to look - let's see if I can fix it now or at least find out what causes the crash;)
 
Ferocca, if you are interested to see the result of my investigations, see my post on page 118 of PAE. It was a conflict between BuildingInfos.xml and CivilizationInfos.xml. It might not be the same problem as yours though.
 
Back
Top Bottom