🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Segmentation fault with dictionary retrieve to auto

Started by
6 comments, last by WitchLord 6 years, 5 months ago

Hi,

When I have this line in a script: `auto compoundData = data.compounds[compound.internalName];` I get a segmentation fault.

Here:


0  in asCArray<int>::GetLength() const of /home/hhyyrylainen/Projects/thrive/build/bin/libEngine.so
1  in asCCompiler::CompileOverloadedDualOperator2(asCScriptNode*, char const*, asCExprContext*, asCExprContext*, bool, asCExprContext*, bool, asCDataType const&) of /home/hhyyrylainen/Projects/thrive/build/bin/libEngine.so
2  in asCCompiler::CompileOperatorOnHandles(asCScriptNode*, asCExprContext*, asCExprContext*, asCExprContext*, eTokenType) of /home/hhyyrylainen/Projects/thrive/build/bin/libEngine.so
3  in asCCompiler::CompileOperator(asCScriptNode*, asCExprContext*, asCExprContext*, asCExprContext*, eTokenType, bool) of /home/hhyyrylainen/Projects/thrive/build/bin/libEngine.so
4  in asCCompiler::CompilePostFixExpression(asCArray<asCScriptNode*>*, asCExprContext*) of /home/hhyyrylainen/Projects/thrive/build/bin/libEngine.so
5  in asCCompiler::CompileExpression(asCScriptNode*, asCExprContext*) of /home/hhyyrylainen/Projects/thrive/build/bin/libEngine.so
6  in asCCompiler::CompileCondition(asCScriptNode*, asCExprContext*) of /home/hhyyrylainen/Projects/thrive/build/bin/libEngine.so
7  in asCCompiler::CompileAssignment(asCScriptNode*, asCExprContext*) of /home/hhyyrylainen/Projects/thrive/build/bin/libEngine.so
8  in asCCompiler::CompileIfStatement(asCScriptNode*, bool*, asCByteCode*) of /home/hhyyrylainen/Projects/thrive/build/bin/libEngine.so
9  in asCCompiler::CompileStatement(asCScriptNode*, bool*, asCByteCode*) of /home/hhyyrylainen/Projects/thrive/build/bin/libEngine.so
10 in asCCompiler::CompileStatementBlock(asCScriptNode*, bool, bool*, asCByteCode*) of /home/hhyyrylainen/Projects/thrive/build/bin/libEngine.so
11 in asCCompiler::CompileStatement(asCScriptNode*, bool*, asCByteCode*) of /home/hhyyrylainen/Projects/thrive/build/bin/libEngine.so
12 in asCCompiler::CompileForStatement(asCScriptNode*, asCByteCode*) of /home/hhyyrylainen/Projects/thrive/build/bin/libEngine.so
13 in asCCompiler::CompileStatement(asCScriptNode*, bool*, asCByteCode*) of /home/hhyyrylainen/Projects/thrive/build/bin/libEngine.so
14 in asCCompiler::CompileStatementBlock(asCScriptNode*, bool, bool*, asCByteCode*) of /home/hhyyrylainen/Projects/thrive/build/bin/libEngine.so
15 in asCCompiler::CompileStatement(asCScriptNode*, bool*, asCByteCode*) of /home/hhyyrylainen/Projects/thrive/build/bin/libEngine.so
16 in asCCompiler::CompileForStatement(asCScriptNode*, asCByteCode*) of /home/hhyyrylainen/Projects/thrive/build/bin/libEngine.so
17 in asCCompiler::CompileStatement(asCScriptNode*, bool*, asCByteCode*) of /home/hhyyrylainen/Projects/thrive/build/bin/libEngine.so
18 in asCCompiler::CompileStatementBlock(asCScriptNode*, bool, bool*, asCByteCode*) of /home/hhyyrylainen/Projects/thrive/build/bin/libEngine.so
19 in asCCompiler::CompileFunction(asCBuilder*, asCScriptCode*, asCArray<asCString>&, asCScriptNode*, asCScriptFunction*, sClassDeclaration*) of /home/hhyyrylainen/Projects/thrive/build/bin/libEngine.so
20 in asCBuilder::CompileFunctions() of /home/hhyyrylainen/Projects/thrive/build/bin/libEngine.so
21 in asCBuilder::Build() of /home/hhyyrylainen/Projects/thrive/build/bin/libEngine.so
22 in asCModule::Build() of /home/hhyyrylainen/Projects/thrive/build/bin/libEngine.so
23 in CScriptBuilder::Build of /home/hhyyrylainen/Projects/leviathan/build/ThirdParty/include/add_on/scriptbuilder/scriptbuilder.cpp:520
24 in CScriptBuilder::BuildModule of /home/hhyyrylainen/Projects/leviathan/build/ThirdParty/include/add_on/scriptbuilder/scriptbuilder.cpp:117

If I change the line to (change auto to int): `int compoundData = data.compounds[compound.internalName];` I get an compile error "Can't implicitly convert from 'dictionaryValue' to 'int'" instead of a segmentation fault.

I know that the above example shouldn't compile either, but it would be nice to have an error message instead of a crash.

Advertisement

You're absolutely correct. The compiler should be giving an error message rather than crashing. I'll have it fixed.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

I haven't been able to reproduce the problem. I need more information from you in order to reproduce and fix this problem.

The backtrace you're showing for the seg fault is not compatible with the script statement you say is causing the problem.

The script statement is a declaration of a variable. It is actually a valid statement, as the 'auto' in this case assumes the type of 'dictionaryValue'. 

The backtrace shows that the seg fault happens when compiling the condition for an if statement, which is located in a double nested for-loop. 

Can you show me the full function that is being compiled when the seg fault happens? 

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

After going back in git history and playing around a bit I got this function to cause the crash:


void setupSpecies(CellStageWorld@ world){

    auto keys = STARTER_MICROBES.getKeys();

    for(uint i = 0; i < keys.length(); ++i){

        const string name = keys[i];

        MicrobeTemplate@ data = cast<MicrobeTemplate@>(STARTER_MICROBES[name]);

        ObjectID speciesEntity = world.CreateEntity();
        
        SpeciesComponent@ speciesComponent = world.Create_SpeciesComponent(speciesEntity,
            name);

        speciesComponent.avgCompoundAmounts = dictionary();

        ProcessorComponent@ processorComponent = world.Create_ProcessorComponent(
            speciesEntity);
    
        speciesComponent.colour = data.colour;

        // iterates over all compounds, and sets amounts and priorities
        uint64 compoundCount = SimulationParameters::compoundRegistry().getSize();
        for(uint a = 0; a < compoundCount; ++a){

            auto compound = SimulationParameters::compoundRegistry().getTypeData(a);

            // int compoundData;
            // bool valid = data.compounds.get(compound.internalName, compoundData);
            auto compoundData = data.compounds[compound.internalName];

            if(compoundData !is null){
                int amount = compoundData.amount;
                speciesComponent.avgCompoundAmounts[formatUint(a)] = amount;
            }
        }
    }
}

Changing around the commented lines to this stops the crashing:


            int compoundData;
            bool valid = data.compounds.get(compound.internalName, compoundData);
            // auto compoundData = data.compounds[compound.internalName];

From my testing it seems that this line is also important in making the crash happen: "if(compoundData !is null){"

That uses quite a few other classes and registered application functions so if they are needed for this to crash I can post a link to a tag in a repository with all the files.

Yes, the line 'if( compoundData !is null)' is consistent with the backtrace.

I'll give it another try with this code and let you know if I can reproduce the problem. I probably won't need to see your registered classes, as it appears to be just a problem related to the combination of 'auto' and the script dictionary add-on (or more specifically types registered with the asOBJ_ASHANDLE flag). 

 

In the meantime, can you answer the following? 

  • Are you using the latest 2.32.0 release? If not, which version are you using?
  • Have you made any custom modifications on the dictionary add-on? If yes, can you share the modifications?

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

I'm using version 2.32.0 from svn:


URL: http://svn.code.sf.net/p/angelscript/code/tags/2.32.0
Relative URL: ^/tags/2.32.0
Repository Root: http://svn.code.sf.net/p/angelscript/code
Repository UUID: 404ce1b2-830e-0410-a2e2-b09542c77caf
Revision: 2463

and I haven't made any changes to the add-ons

I've fixed the crash now in revision 2465.

 

The problem was due to the dictionaryValue type not having opEquals operators, and when the compiler then attempted to look for valid opEquals operators on the right hand expression (null), there was a null pointer access failure due to 'null' not having any specific type associated with it.

With the fix, your script will produce a compiler error message "No appropriate opEquals method found" on the if-condition. 

The error message is a bit too cryptic to my liking, as it is not immediately clear why there are no opEquals methods. I'll see if I can improve this in the future.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

This topic is closed to new replies.

Advertisement