Why does debug mode cause my game to crash?

Discussion in 'Programming' started by SupernaturalCow, Jan 11, 2019.

  1. SupernaturalCow

    SupernaturalCow Member

    Joined:
    Sep 11, 2016
    Posts:
    39
    Ok so I don't really know how to broach this issue, and I'll probably have to send in a request to YoYo, but I thought I might start here first.

    I use a lot of data strucs in my project, and rely on them heavily for nearly everything in the game. I only use maps and lists, and each are nested within each other using the DS 'mark_as' or 'add_as' functions. I can ensure that every map or list is created in this way, as the function I use to create maps and lists uses the nesting function after it. I mention this despite knowing its relevance, because honestly I have no idea why GameMaker might be doing this. The only other thing that I do, that might be out of the ordinary, is that I have been using 'ds_map_create()' as a function parameter for 'ds_list_set'.

    As for the issue:
    My game runs fine when I run it normally. All the DS' are created and handled as expected, and there are no 'undefined' or 'ds_map doesn't exist!' errors. The problem occurs when I run in Debug Mode. For some reason, it doesn't get past the first few steps, and breaks as soon as it tries to reference a DS it's created previously. The way that it breaks differs occasionally, but it always gets stuck on a DS it's trying to read, saying it doesn't exist. Again, this issue doesn't occur when I run it normally (F5).

    Here's the error dump that I'm getting currently:
    Code:
    ############################################################################################
    ERROR in
    action number 1
    of  Step Event0
    for object sys:
    
    Data structure with index does not exist.
     at gml_Script_scr_update_class_inheritance (line 31) - sv[? "my_parent"] = _par_class_id;
    ############################################################################################
     
  2. Tsa05

    Tsa05 Member

    Joined:
    Jun 21, 2016
    Posts:
    525
    Offhand hard to say--perhaps objects are being created in a different order or something.

    To debug, create a log script that opens a file for append-writing, and whenever you get to that script, log the value of sv, and anything else about it; basically you have the reverse problem to usual--we'd step through your code with breakpoints in debug mode. So, output values in a log, then step through in debug to see what's not lining up.
     
    SupernaturalCow likes this.
  3. chamaeleon

    chamaeleon Member

    Joined:
    Jun 21, 2016
    Posts:
    783
    And you have of course used the debugger or show_debug_message() to verify the return value of ds_map_create() is assigned to sv before you get to this line, and that the sv variable is not overwritten with a non-ds_map value? That error message is what I get if I try to use the ds_map accessor in that manner with a variable that has just been assigned a value of 0 instead of a ds_map.
     
  4. SupernaturalCow

    SupernaturalCow Member

    Joined:
    Sep 11, 2016
    Posts:
    39
    Okay, I'm on a lunch break so unfortunately I can't get into much atm, but after a brief spat of digging, I discovered that upon reading it, 'sv' is a list not a map.
    Code:
    var sv = master_map[? "map of state vars"];
    sdm(dr_get_type(master_map[? "map of state vars"])==ds_type_list);  // result: true
    // later ...
    sdm(sv,", ",,dr_get_type(sv)==ds_type_list);  // result: 8, true
    sv[? "my_parent"] = _par_class_id;  // error occurs here.
    I went to have a look at how I'm creating master_map[? "map of state vars"], and all looks fine so far...
    Code:
    var sv = dr_map_create(); 
    dr_map_add_map(master_map, "map of state vars", sv);
    sdm(dr_get_type(master_map[? "map of state vars"])==ds_type_list);  // result: false 
    So logically, something seems to be overwriting the value of master_map[? "map of state vars"], and changing it from a map to a list. However, I don't see how this could be possible, considering that I designed it specifically so that I never actually write directly to "map of state vars". I always reference it first as 'sv'. Here's a Search Output of master_map[? "map of state vars"]:
    Code:
    Searching for 'master_map[? "map of state vars"]'...
    scr_update_class_inheritance at line 13:     var sv = master_map[? "map of state vars"];
    scr_update_class_inheritance at line 14:     sdm(dr_get_type(master_map[? "map of state vars"])==ds_type_list);
    instance-Step at line 3:     var    sv = master_map[? "map of state vars"],
    sys-Create at line 130:     sdm(dr_get_type(master_map[? "map of state vars"])==ds_type_list);
    sys-Step at line 4:     sv = master_map[? "map of state vars"],
    state_up at line 21:     var sv = master_map[? "map of state vars"];
    Search Complete (6 results)
    Regardless of all this, isn't it strange that running the game normally doesn't crash it? But debug mode does?
     
    Last edited: Jan 11, 2019
  5. Tsa05

    Tsa05 Member

    Joined:
    Jun 21, 2016
    Posts:
    525
    Not strange at all; side note, it's not a matter of GMS changing types on you.

    Suppose you do the following:
    myList = ds_list_create();

    Now you do this:
    myMap = ds_map_create();

    What is the value of myList? Zero.
    What is the value of myMap? Zero.

    Here's a fun one. Given the following:
    Code:
    myList = ds_list_create();
    ds_list_add(myList, 10);
    
    myMap = ds_map_create();
    ds_map_add(myMap, "value", "ABC");
    This is a valid function call:
    Code:
    ds_list_find_value(myMap, 0);
    Weird, right? Looking for list index value zero in a map???? But really, GameMaker is just a pass-by-reference system.

    What's happening for you is that you have a mix-up somewhere in your code that is doing one of the following 2 things:
    1) You might be accidentally passing a list into something that wants a map, or vice versa
    2) More likely, you create a map and it is destroyed or overwritten later.

    #2 is more likely, so, why the difference in behavior?
    Remember, allllll ds things are "sorta" global.
    If object0 creates a map, that might be map number zero.
    When object1 creates a map, that might be map number one.
    Unless map number zero was destroyed already, in which case the new map is likely map number zero.

    Even though data structures are being created across multiple objects, the reference number system is globally managed by gameMaker (and there's separate numbering for each ds type, so the number zero can refer to both a map and a list at the same time).

    What's happening here is that GameMaker doesn't absolutely guarantee the order in which object events are executed (two objects with the same priority that both have a Step event will perform their Step events in arbitrary order; same with any event). It sounds as though the order is reasonably consistently one way in your debug mode and a consistently different way on normal run. That's behaving as intended, basically, because the order isn't guaranteed.... (There's an instance create order thing in the room editor that can help though).

    Anyways--the inconsistent order isn't the actual issue, by the sound of it--it's merely causing the symptom to appear. It sounds like somewhere in your game, you have a variable holding on to a number that once used to hold a data structure....but now does not. This is a programming error. You can get really, really lucky, though, if a new map or a substitute map, or similar map happens to get created in the exact same number slot...causing your debugger version to behave normally. It's like back when Game Maker used to treat all undefined variables as zero--sometimes, it happened to line up perfectly with circumstances where a value should have been zero--sometimes it caused nightmarishly confusing bugs.

    Hope that clarifies ><
    Basically, got to track where that map was created, and where it might have been destroyed or overwritten.
     
    IndianaBones and SupernaturalCow like this.
  6. SupernaturalCow

    SupernaturalCow Member

    Joined:
    Sep 11, 2016
    Posts:
    39
    Ahh, I see. Thanks for going into such depth, I didn't realize a few of those points. Especially the one about the instance order! When I get home I'll start by tracing the happenings of my state vars map. I'd gutted out all functions that destroy maps while debugging, so I'm fairly certain it's not due to the map being destroyed. It'd be much easier to fix if I could use the Debug Mode, so I might start by trying to set the instance order manually (to the one that works). It gets pretty convoluted pretty quickly though, doesn't it? There must be a better way of keeping track of these data structures. For example, it would be nice to have a list of all the references to a map.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice