Sign in to follow this  
ruphert

Crash on exit (binding wrong?)

Recommended Posts

Hey, I'm experiencing a crash in free() on exit. I'm lost, so maybe you can tell me if I did something wrong in the bindings?

 

struct Tile
{
    b2Fixture* edgeN, *edgeS, *edgeW, *edgeE;
    u16 blobid1, blobid2;
    u16 backblobid1, backblobid2;
    TileType type;
	u16 flags;
    u8 support;
    u8 dirt;
    u8 light;
    u8 noise;
    u8 damage;

	Tile();
	Tile( const TileType t );
	Tile( Tile& t );

	Tile& operator=(const Tile& t) 
	{ 
		type = t.type;
		support = t.support;
		dirt = t.dirt;
		light = t.light;
		flags = t.flags;
		noise = t.noise;
		damage = t.damage;
		return *this;
	}	

	bool operator==(const Tile& rhs)
	{
		return (type == rhs.type);	  // legacy
	}	
	bool operator==(const Tile& rhs) const
	{
		return (type == rhs.type);	  // legacy
	}	

	enum TileFlags {
		SPARE_0 = 0x01,
		BACKGROUND = 0x02,
		SOLID = 0x04,
		LADDER = 0x08,
		LIGHT_PASSES = 0x10,
		WATER_PASSES = 0x20,
		FLAMMABLE = 0x40,
		PLATFORM = 0x80,
		LIGHT_SOURCE = 0x100,
		MIRROR = 0x200,
		FLIP = 0x400,
		ROTATE = 0x800,
		SPARE_1 = 0x1000,
		SPARE_2 = 0x2000,
		SPARE_3 = 0x4000,
		SPARE_4 = 0x8000
	};
};

The binding:

    r = engine->RegisterObjectType("Tile", sizeof(Tile), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_CA); assert(r >= 0);
    // Set Vec2f behaviour.
    // Initialisation and deinitialisation
    r = engine->RegisterObjectBehaviour("Tile", asBEHAVE_CONSTRUCT, "void f()", asFUNCTIONPR(constructorTile,
                                        (void*), void), asCALL_CDECL_OBJLAST); assert(r >= 0);
    r = engine->RegisterObjectBehaviour("Tile", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(deconstructorTile),
                                        asCALL_CDECL_OBJLAST); assert(r >= 0);

	r = engine->RegisterObjectProperty("Tile", "TileType type", asOFFSET(Tile, type)); assert(r >= 0);
	r = engine->RegisterObjectProperty("Tile", "u8 support", asOFFSET(Tile, support)); assert(r >= 0);
	r = engine->RegisterObjectProperty("Tile", "u8 dirt", asOFFSET(Tile, dirt)); assert(r >= 0);
	r = engine->RegisterObjectProperty("Tile", "u8 light", asOFFSET(Tile, light)); assert(r >= 0);
	r = engine->RegisterObjectProperty("Tile", "u16 flags", asOFFSET(Tile, flags)); assert(r >= 0);
	r = engine->RegisterObjectProperty("Tile", "u8 damage", asOFFSET(Tile, damage)); assert(r >= 0);
	r = engine->RegisterObjectProperty("Tile", "u8 noise", asOFFSET(Tile, noise)); assert(r >= 0);
	r = engine->RegisterObjectProperty("Tile", "u16 blobid1", asOFFSET(Tile, blobid1)); assert(r >= 0);
	r = engine->RegisterObjectProperty("Tile", "u16 blobid2", asOFFSET(Tile, blobid2)); assert(r >= 0);
	r = engine->RegisterObjectProperty("Tile", "u16 backblobid1", asOFFSET(Tile, backblobid1)); assert(r >= 0);
	r = engine->RegisterObjectProperty("Tile", "u16 backblobid2", asOFFSET(Tile, backblobid2)); assert(r >= 0);
	r = engine->RegisterObjectMethod("Tile", "Tile& opAssign(const Tile &in)",
		asMETHODPR(Tile, operator=, (const Tile&), Tile&),
		asCALL_THISCALL); assert(r >= 0);

	r = engine->SetDefaultNamespace("Tile"); assert( r >= 0 );
	r = engine->RegisterEnum("TileFlags"); assert( r >= 0 );
	r = engine->RegisterEnumValue("TileFlags", "SPARE_0", Tile::SPARE_0); assert( r >= 0 );
	r = engine->RegisterEnumValue("TileFlags", "SOLID", Tile::SOLID); assert( r >= 0 );
	r = engine->RegisterEnumValue("TileFlags", "BACKGROUND", Tile::BACKGROUND); assert( r >= 0 );
	r = engine->RegisterEnumValue("TileFlags", "LADDER", Tile::LADDER); assert( r >= 0 );
	r = engine->RegisterEnumValue("TileFlags", "LIGHT_PASSES", Tile::LIGHT_PASSES); assert( r >= 0 );
	r = engine->RegisterEnumValue("TileFlags", "WATER_PASSES", Tile::WATER_PASSES); assert( r >= 0 );
	r = engine->RegisterEnumValue("TileFlags", "FLAMMABLE", Tile::FLAMMABLE); assert( r >= 0 );
	r = engine->RegisterEnumValue("TileFlags", "PLATFORM", Tile::PLATFORM); assert( r >= 0 );
	r = engine->RegisterEnumValue("TileFlags", "LIGHT_SOURCE", Tile::LIGHT_SOURCE); assert( r >= 0 );
	r = engine->RegisterEnumValue("TileFlags", "MIRROR", Tile::MIRROR); assert( r >= 0 );
	r = engine->RegisterEnumValue("TileFlags", "FLIP", Tile::FLIP); assert( r >= 0 );
	r = engine->RegisterEnumValue("TileFlags", "ROTATE", Tile::ROTATE); assert( r >= 0 );
	r = engine->RegisterEnumValue("TileFlags", "SPARE_1", Tile::SPARE_1); assert( r >= 0 );
	r = engine->RegisterEnumValue("TileFlags", "SPARE_2", Tile::SPARE_2); assert( r >= 0 );
	r = engine->RegisterEnumValue("TileFlags", "SPARE_3", Tile::SPARE_3); assert( r >= 0 );
	r = engine->RegisterEnumValue("TileFlags", "SPARE_4", Tile::SPARE_4); assert( r >= 0 );
	r = engine->SetDefaultNamespace(""); assert( r >= 0 );

 

And some functions that use it:

    r = engine->RegisterObjectMethod("CMap", "void server_SetTile(Vec2f pos, const Tile &in tile)",
                                     asMETHODPR( CMap, server_SetTile, (Vec2f, const Tile&), void),
                                     asCALL_THISCALL); assert(r >= 0);

    r = engine->RegisterObjectMethod("CMap", "Tile getTile( Vec2f pos ) const",
                                     asMETHODPR( CMap, getTile, (Vec2f) const, Tile),
                                     asCALL_THISCALL); assert(r >= 0);
    r = engine->RegisterObjectMethod("CMap", "Tile getTileFromTileSpace( Vec2f pos ) const",
                                     asMETHODPR( CMap, getTile_Vec2f, (Vec2f) const, Tile),
                                     asCALL_THISCALL); assert(r >= 0);
    r = engine->RegisterObjectMethod("CMap", "Tile getTile( u32 offset ) const",
                                     asMETHODPR( CMap, getTile, (u32) const, Tile),
                                     asCALL_THISCALL); assert(r >= 0);

Share this post


Link to post
Share on other sites

What version of AngelScript are you using now? On which platform does the crash happen? Does it matter?

 

The only thing I see that could potentially be wrong is that it appears that your Tile class has a copy constructor, which means it should be registered with the flag asOBJ_APP_CLASS_CAK. On gnuc based compilers the existance of the copy constructor influences how the object is passed by value to/from the application (though with the size of the Tile class I don't think it should matter).

 

Does the crash only happen after calling one of the functions that take or return the Tile type?

Share this post


Link to post
Share on other sites

Visual Studio 2010

Angelscript 2.26.2

 

The crash happens on next map (after resources are freed, and only in the release mode). I'm not sure now this is the reason for the crash, so lets leave it.

However I have a memory leak (might be related) and I need some help figuring out what causes this.

The leak happens on every single script in the game. What do you think it is leaking ?

 d:\transhuman\kag\3rd\angelscript\sdk\angelscript\source\as_builder.cpp (3529): (Module name unavailable)!asCBuilder::GetParsedFunctionDetails + 0x14 bytes
    d:\transhuman\kag\3rd\angelscript\sdk\angelscript\source\as_builder.cpp (3595): (Module name unavailable)!asCBuilder::RegisterScriptFunctionFromNode
    d:\transhuman\kag\3rd\angelscript\sdk\angelscript\source\as_builder.cpp (658): (Module name unavailable)!asCBuilder::RegisterNonTypesFromScript + 0x1E bytes
    d:\transhuman\kag\3rd\angelscript\sdk\angelscript\source\as_builder.cpp (569): (Module name unavailable)!asCBuilder::ParseScripts
    d:\transhuman\kag\3rd\angelscript\sdk\angelscript\source\as_builder.cpp (231): (Module name unavailable)!asCBuilder::Build
    d:\transhuman\kag\3rd\angelscript\sdk\angelscript\source\as_module.cpp (222): (Module name unavailable)!asCModule::Build + 0xB bytes
    d:\transhuman\kag\trunk\scripting\angelscript\add_on\scriptbuilder\scriptbuilder.cpp (651): (Module name unavailable)!CScriptBuilder::Build + 0x17 bytes
    d:\transhuman\kag\trunk\scripting\angelscript\add_on\scriptbuilder\scriptbuilder.cpp (143): (Module name unavailable)!CScriptBuilder::BuildModule
    d:\transhuman\kag\trunk\scripting\asscript.cpp (201): (Module name unavailable)!asScript::loadScript + 0xB bytes
    d:\transhuman\kag\trunk\scripting\asscriptmanager.cpp (371): (Module name 

Share this post


Link to post
Share on other sites

Version 2.27.0 had a bug fix that may be related to the crash you're seeing. The bug was that AngelScript didn't allocate enough space for value types if the size of the type was not evenly divisable with 4. What is the size of the Tile structure?

 

Would it be possible to upgrade to the latest release of AngelScript (2.27.1) to see if the problem goes away?

 

I'm not sure about the memory leak. Have you tried turning on MSVC memory debug routines to identify the memory that is being leaked?

 

#include <crtdbg.h>
 
// In the main function
_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF|_CRTDBG_ALLOC_MEM_DF);
_CrtSetReportMode(_CRT_ASSERT,_CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_ASSERT,_CRTDBG_FILE_STDERR);
 
// Use _CrtSetBreakAlloc(n) to find a specific memory leak
_CrtSetBreakAlloc(924);

 

If you can run the application on Linux I recommend using valgrind to find any memory problems. It will detect not only leaks but also writing to or reading from unallocated memory.

Share this post


Link to post
Share on other sites

Does this mean that the only problem you're having now is the memory leak?

 

I reviewed the code in asCBuilder::GetParsedFunctionDetails that Visual Leak Detector showed as the offending leak, and I identified a potential for memory leaks if there are errors in the script, e.g. a name conflict on a function with default arguments. I'll have that fixed as soon as possible.

 

Are you seeing memory leaks even when there are no compiler errors?

Share this post


Link to post
Share on other sites

It turns out it didn't require a compiler error to hit the memory leak. Any shared functions with default arguments would leak in the second and following modules they were compiled in.

 

I've fixed this leak in revision 1719. 

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

Sign in to follow this