1. We have added a Gift Upgrades feature that allows you to gift an account upgrade to another member, just in time for the holiday season. You can see the gift option when going to the Account Upgrades screen, or on any user profile screen.
    Dismiss Notice

A short guide to debugging the exe

Discussion in 'Civ4 - Modding Tutorials & Reference' started by billw2015, Sep 7, 2019.

  1. billw2015

    billw2015 King

    Joined:
    Jun 22, 2015
    Messages:
    837
    This is something I quickly wrote after a couple of recent successes tracking down and fixing crashes that happen in the Civ4 BtS exe (due to our changes), using the disassembly window:

    https://github.com/caveman2cosmos/Caveman2Cosmos/wiki/Debugging-the-Disassembly

    I will add more later as I learn more about it. If there are other guides out there covering this or similar topics I would be interested in looking at them as well.
     
    MattCA, f1rpo and Nightinggale like this.
  2. Nightinggale

    Nightinggale Deity

    Joined:
    Feb 2, 2009
    Messages:
    4,556
    Reading this I came up with another approach to figure out which class the pointer points to. We can add code to the DLL to aid us in figuring this out. If we add a CvString as the first variable in CvUnit and let the constructor set it to CvUnit, then if we assume the pointer to point to a unit, the watch window will tell us instantly if we guessed correctly because the first line would be CvUnit. Now do the same with CvPlot. If we assume CvUnit on a plot pointer, the first variable is still a CvString and it will say CvPlot. Fill out a bunch of classes and wrong guesses will tell us what we should have written. There are a few classes where this won't work, like CvPlayer due to virtual pointers and the info classes. However the info classes all have the type string at the same location meaning if you figure out it's an info class, it's not tricky to figure out which one as long as you named your classes in a sane manner like maintaining the vanilla approach of UNIT_ etc prefixes.

    If we add #ifdef EXE_DEBUG, then we can bloat the DLL with help text like this and not feel bad about it. Maybe it can be done with const char pointers too. I haven't actually tried this, but I don't see any reason why it shouldn't work.

    It's a great article (particularly the Tips and Tricks section), but it still leaves me with one big question: what should we do if we uncover a bug in the exe itself? What if we need to change branch if not equal to branch if equal? The reason I ask this is because I have found a bug in the Colonization exe (also in BTS? Not sure) where the AI can offer peace, but the exe will not display the diplo screen unless !isAtWar(). The check inside the exe is inverted.
     
    MattCA likes this.
  3. billw2015

    billw2015 King

    Joined:
    Jun 22, 2015
    Messages:
    837
    Yeah I actually was thinking about doing this as well, just not sure what the requirements are for existing object layouts. Ideally we could put it at the same offset in all classes, +8 or something, but I guess like you say some classes have layout requirements. OR (just occurred to me) we could put it at -4 using the memory allocator override. That is probably the way actually isn't it.

    Yeah it would be better, use static memory would be preferable.

    Beg firaxis to release the source code? :D
    Only other options are run time patch the code (dunno how to do this in an exe), or some how detect in the DLL callbacks when you are in the broken function are return the corrected value, although how to do this robustly is another question. You could look at the callstack and find out where you were called from for instance, but I would prefer not to do this kind of hacking personally, if there is any other way to address the issue!
     
    MattCA likes this.
  4. billw2015

    billw2015 King

    Joined:
    Jun 22, 2015
    Messages:
    837
    @Nightinggale You might be interested, I just added MemTrack to our code base for tracking memory usage. It works exactly like I described above, by allocating extra space for a meta data chunk, and it also automatically gets the typeid as a string. Its entirely non intrusive (as far as changes to existing code is concerned), and worked pretty much out of the box.
     
    MattCA likes this.

Share This Page