Jump to content
  • Advertisement
Boost113

Segmentation fault with dictionary retrieve to auto

Recommended Posts

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.

Share this post


Link to post
Share on other sites
Advertisement

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

Share this post


Link to post
Share on other sites

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? 

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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?

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!