How to put a debug DLL to good use?

Maniac

Apolyton Sage
Joined
Nov 27, 2004
Messages
5,588
Location
Gent, Belgium
I've got a couple debug DLL related questions.

1)
I added this new AI type for sea colonies which uses the CvUnitAI::AI_seaColonyMove() function. Unfortunately Sea Colony Pods just stay put in the base they're built instead of moving out and do some useful stuff. I'd like to find out why that is, where the CvUnitAI::AI_seaColonyMove() function returns. Unfortunately I can't figure out how to find this out using a debug DLL. I can of course set a breakpoint at CvUnitAI::AI_seaColonyMove(), but that just tells me that the function is being accessed. It doesn't tell me where it returns. Does anyone know how to do this?

2)
Before trying out Microsoft Visual C++ 2008 Express Edition for debugging purposes, I have always used (and am still mainly using) Codeblocks. With that program, as long as you don't change header files, if you only change cpp files and then compile the DLL, it will only spend time recompiling the changed cpp files. If you change a header file, it will recompile all files. To find out if files are changed, it looks at the date stamp.

I can't figure out how it works in Microsoft Visual C++ 2008 Express Edition. Today I tried out the same as I usually do with Codeblocks - simply drop the changed cpp and header files in the project folder - but then Microsoft Visual C++ 2008 Express Edition gives an error whe trying to compile. So this program seems to use another method than Codeblocks to figure out what files are changed and which it needs to recompile. Does anyone know what this method is? Am I forced to always 'Rebuild Solution' (which recompiles all files) instead of merely 'Build Solution'?

3)
I end the turn using the debug DLL. At the start of my next turn... all citizens of of all cities of all players (both me and AIs) have been turned into Citizen specialists instead of working the fields.

When playing with an assert (not debug) DLL, I have also noticed that the AI city governor simply does not place its free specialists - you can still place them manually though. When you then click on the city tile within the city screen (which lets the AI decide plot worker placement) the free specialists disappear again.

It appears that using these assert and debug DLLs causes some parts of the AI to malfunction/not function.

Has anyone else experience this before, or does anyone know what's causing this?

Thanks!

Edit: Attached vanilla BtS debug DLL
 
1) When a breakpoint triggers, you can look at the Call Stack, and it shows you the current function at the top of the list, and progressing down the list are the functions which have brought you to this location. You can double click on any of them to go to the line which calls the next function up.

You can also use "Step Out" commmand (SHIFT+F11 I think) to let the current function run all the way through and you'll then be looking at the code which called the function originally, but now that call is complete and you can continue stepping through the code from there to watch it (F10 or F11, depending on the detail you want to step with)

2) I am not sure what you mean by "drop the changed files in to the project folder" if you mean purely in Explorer you copy of your files, that should still work perfectly fine. In VS it will only recompile the specific files which you changed when you choose Build Solution, so you must choose to Rebuild Solution manually if you make a Header change which is important to other files (most header changes will be)

3) That's kinda wierd. I'd say something is wrong with the code if it behaves differently under Debug or Assert builds. They should change nothing, otherwise they defeat their own purpose.
 
Thanks!

So if I only change cpp file, Build Solution should be fine? And if I change a header file, it's Rebuild Solution?

I'll try out the Step Out command. In due time I'll also compile a DLL for vanilla BtS and see if the problem occurs there too.
 
Can someone put a debug dll here, for BtS mods that have no other dll's?

Sorry to use your thread.:blush:

You're seriously limiting the chances that someone will see your request. If you posted a new thread with a descriptive title, far more people would be likely to read it. Just a thought as someone has probably already done this at some point but may not read this thread.
 
This is a 50 Civ, otherwise unaltered 3.19 debug dll.

50 Civ otherwise unaltered BtS 3.19 debug dll

I really can't see why you'd need an 18 civ dll, unless you need to check a specific save game. If so, it takes hours for me to build a debug dll on this machine (about 2 and a half hours actually) so I'm really not motivated to do that.
 
3) That's kinda wierd. I'd say something is wrong with the code if it behaves differently under Debug or Assert builds. They should change nothing, otherwise they defeat their own purpose.

What code could cause different results from CvCityAI::AI_assignWorkingPlots, AI_juggleCitizens, AI_removeWorstCitizen, AI_addBestCitizen or whatever else may be involved? I didn't change those functions. :(
 
Hard to decide on those, AI's overall strategy should be considered when deciding priority of each yield type, so that would be factored into those functions in a roundabout manner, and the strategy is slightly connected to most parts of the code.
 
I found the problem.

I was adding to a value (iValue += ...) before having given an initial value to the value (iValue = ...). Thus iValue (the value for the citizen specialist) became quasi-infinitely high.

I don't understand why this problem only showed up under Debug though. I've made this mistake once before, and then it gave me a huge pile of cash while popping a unity pod.
 
Ah, I had totally forgotten about this. Under debug builds, compilers tend to leave variables uninitialized. They start with whatever garbage happened to be in that memory location assigned to the variable. This is so that you get weird behavior and can figure out you forgot to initialize a variable. Under release builds, new variables are zeroed out.
 
In my experience it is not safe to rely on the contents of a variable you have not initialized. In fact, since performing the initialization takes time, it is likely that optimized production builds will not set variables to zero for you.

I am not sure what the Windows equivalent is, but many commercial programmers use "valgrind" for linux or a commercial tool "purify" to find uninitialized variables.
 
In my experience it is not safe to rely on the contents of a variable you have not initialized.

You should always, always initialize your variables and data structures before accessing them. Always! In fact, in Python and Java you must or you get an exception or compiler error.

In fact, since performing the initialization takes time, it is likely that optimized production builds will not set variables to zero for you.

Most C/C++ compilers let you set the initialization to one of three types: do nothing, assign zero, assign random data.
 
Interesting. Seems like it should be easy to add a warning message for uninitialized variables though. Silly compiler programs. :shake:
 
Seems like it should be easy to add a warning message for uninitialized variables though.

Code:
int x;
int *p = &x;

*p = 2;
[B]x += 5;[/B]

Should this line receive a warning because x is uninitialized? Sure, here you can tell that p points to x and thus x gets initialized, but this is a simple example. It can get more complicated pretty quick.

Code:
struct data {
    int x;
    int y;
}

data d;
int *p = &d.y;
p--;
*p = 2;
[B]d.x += 5;[/B]

How about now? :D
 
Here we go into compiler philosopy again.

A real C++ compiler such as gcc/g++ will catch simple uninitialized variables. For example, "gcc -Wall" (all Warnings) would catch the OP problem. I have no idea if codeblocks or visual studio 2003 can do this, probably there is an option.

I doubt any compiler would catch the initialization of --p. However, runtime analysis tools such as valgrind or purify would catch this.
 
Top Bottom