Jump to content

  • Log In with Google      Sign In   
  • Create Account

- - - - -

Assertion failure in as_configgroup.cpp


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
25 replies to this topic

#1 _Vicious_   Members   -  Reputation: 240

Like
0Likes
Like

Posted 21 January 2012 - 05:36 AM

Hello Andreas,

I hit the following assertion failure upon config group shutdown (v 2.2.2): http://www.foopics.c...844c3d87c9d3257
It seems to be related to string factory method/function somehow. What this assertion failure might indicate?

Sponsor:

#2 Andreas Jonsson   Moderators   -  Reputation: 3444

Like
0Likes
Like

Posted 21 January 2012 - 09:27 AM

It means that something didn't go as I had expected when writing the code. It is quite possible a bug in my code, though as it is in the ValidateNoUsage() method it is possible it doesn't affect your application if you compile the library in release mode.

Do you know how to reproduce the problem? I'll need to know this in order to debug it and fix the code.

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

#3 _Vicious_   Members   -  Reputation: 240

Like
0Likes
Like

Posted 21 January 2012 - 02:11 PM

Basically, it happens upon each time I close the app in Debug mode. No special steps are required..

#4 Andreas Jonsson   Moderators   -  Reputation: 3444

Like
0Likes
Like

Posted 21 January 2012 - 02:36 PM

It never happens for me, and I always test in debug mode.

I'll need help to narrow it down. As it is now I have no idea what the problem might be.

Is it possible for you to create a small test that reproduce the problem?
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

#5 _Vicious_   Members   -  Reputation: 240

Like
0Likes
Like

Posted 21 January 2012 - 03:09 PM

On a side note, I've also hit an assertion failure in as_array.h:
asASSERT(index < length);

in asCArray<T>::operator []

The values for index and length are 388 and 76 respectively.

This is the faulty line:
return registeredGlobalFuncs[id];

in asCScriptEngine::GetGlobalFunctionByDecl

#6 Andreas Jonsson   Moderators   -  Reputation: 3444

Like
0Likes
Like

Posted 21 January 2012 - 03:32 PM

This one is easier. The faulty line should be changed to:

return scriptFunctions[id];

I've checked in this fix in revision 1115.

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

#7 _Vicious_   Members   -  Reputation: 240

Like
0Likes
Like

Posted 21 January 2012 - 04:08 PM

I think the reason for the first error was that I was trying to do something unexpected for the AS :)
Basically, I wanted to be able to call function pointer in this manner:
other.pain( other, ent, 10.9, 10.0 );

for objects that had the .pain callback set in the C code (in the game not all of the game objects are controlled through scripting). For that, I created a proxy function:
void G_CallPain( edict_t *ent, edict_t *attacker, float kick, float damage )
{
    if( ent->pain )
        ent->pain( ent, attacker, kick, damage );
    else if( ent->scriptSpawned && ent->asPainFunc )
        G_asCallMapEntityPain( ent, attacker, kick, damage );
}
, registered it in AS as a global function and then set the asPainFunc function pointer in AddRef method like this:
if( !obj->scriptSpawned ) {
obj->asPainFunc = asEntityCallPainFuncPtr;

The key thing is that asPainFunc also holds the .pain function pointer set from the script.

#8 Andreas Jonsson   Moderators   -  Reputation: 3444

Like
0Likes
Like

Posted 21 January 2012 - 04:35 PM

This should work.

I'll make some new tests with this info and see if it allows me to reproduce the problem.



How is the G_CallPain function registered? It is a global function in the application but you seem to call it as if it was an object method in the script.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

#9 Andreas Jonsson   Moderators   -  Reputation: 3444

Like
0Likes
Like

Posted 21 January 2012 - 04:55 PM

I'm still not able to reproduce the problem. I wrote the following test in the hopes that a funcdef in a dynamic config group may have been the cause.


{
  asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);

  engine->BeginConfigGroup("gr");
  engine->RegisterObjectType("type", 0, asOBJ_REF);
  engine->RegisterObjectBehaviour("type", asBEHAVE_FACTORY, "type @f()", asFUNCTION(Type::Factory), asCALL_CDECL);
  engine->RegisterObjectBehaviour("type", asBEHAVE_ADDREF, "void f()", asMETHOD(Type,AddRef), asCALL_THISCALL);
  engine->RegisterObjectBehaviour("type", asBEHAVE_RELEASE, "void f()", asMETHOD(Type,Release), asCALL_THISCALL);
  engine->RegisterFuncdef("void fun(type @, int)");
  engine->RegisterObjectProperty("type", "fun @callback", asOFFSET(Type,callback));
  engine->EndConfigGroup();

  asIScriptModule *mod = engine->GetModule("mod", asGM_ALWAYS_CREATE);
  mod->AddScriptSection("s", 
    "void func(type @, int) {} \n"
    "void main() \n"
    "{ \n"
    "  type t; \n"
    "  @t.callback = func; \n"
    "  t.callback(t, 1); \n"
    "} \n");

  int r = mod->Build();
  if( r < 0 )
    TEST_FAILED;

  r = ExecuteString(engine, "main()", mod);
  if( r != asEXECUTION_FINISHED )
    TEST_FAILED;

  engine->Release();
}

The test passed without any problems, so I'm obviously missing something.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

#10 _Vicious_   Members   -  Reputation: 240

Like
0Likes
Like

Posted 22 January 2012 - 03:44 AM

Yes, G_CallPain is a global function but I'm actually calling it as an object method there. Or even, I'm not calling it at all, but rather assign a pointer holding object's 'pain' funcdef property to it. After all, a function pointer is a function pointer, isn't it? ;)

#11 Andreas Jonsson   Moderators   -  Reputation: 3444

Like
0Likes
Like

Posted 22 January 2012 - 07:38 AM

I tried assigning a registered function to the function pointer and call that instead of the script function. This didn't work as there was a bug in the VM when executing the asBC_CallPtr instruction in that it failed to recognize that the function was a registered function instead of a script function.

However, after fixing that bug, in revision 1117, I'm still not able to reproduce the problem you have. :(
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

#12 _Vicious_   Members   -  Reputation: 240

Like
0Likes
Like

Posted 23 January 2012 - 02:00 AM

Thanks, I'll update our svn copy to include the fix from rev 1117 and report back on the issue.

#13 _Vicious_   Members   -  Reputation: 240

Like
0Likes
Like

Posted 24 January 2012 - 01:26 PM

Not sure what's changed but now I'm getting a crash in asCScriptEngine::CallObjectMethod:
  void (asCSimpleDummy::*f)() = p.mthd;
  obj = (void*)(size_t(obj) + i->baseOffset);
  [b](((asCSimpleDummy*)obj)->*f)();[/b]

Unwinding the stack a bit:
   // Release previous object held by destination pointer
   if( *d != 0 )
	[b]engine->CallObjectMethod(*d, beh->release);[/b]
   // Increase ref counter of wanted object
   if( s != 0 )
	engine->CallObjectMethod(s, beh->addref);

The crash is triggered by setting object's function pointers to global functions in the AddReference behavior:
  obj->asThinkFunc = asEntityCallThinkFuncPtr;
  obj->asTouchFunc = asEntityCallTouchFuncPtr;
  obj->asUseFunc = asEntityCallUseFuncPtr;
  obj->asStopFunc = asEntityCallStopFuncPtr;
  obj->asPainFunc = asEntityCallPainFuncPtr;
  obj->asDieFunc = asEntityCallDieFuncPtr;

All of those asEntityCall*FuncPtr are of type void * and hold return values of asGetGlobalFunctionByDecl.

#14 _Vicious_   Members   -  Reputation: 240

Like
0Likes
Like

Posted 24 January 2012 - 01:30 PM

Ah, if I change this part of the code:
  obj->asThinkFunc = asEntityCallThinkFuncPtr;
  obj->asTouchFunc = asEntityCallTouchFuncPtr;
  obj->asUseFunc = asEntityCallUseFuncPtr;
  obj->asStopFunc = asEntityCallStopFuncPtr;
  obj->asPainFunc = asEntityCallPainFuncPtr;
  obj->asDieFunc = asEntityCallDieFuncPtr;

to

//  obj->asThinkFunc = asEntityCallThinkFuncPtr;
//  obj->asTouchFunc = asEntityCallTouchFuncPtr;
  obj->asUseFunc = asEntityCallUseFuncPtr;
//  obj->asStopFunc = asEntityCallStopFuncPtr;
//  obj->asPainFunc = asEntityCallPainFuncPtr;
//  obj->asDieFunc = asEntityCallDieFuncPtr;

I then hit the assertion from the first post. I'm quite sure the use function is never called though.

#15 Andreas Jonsson   Moderators   -  Reputation: 3444

Like
0Likes
Like

Posted 24 January 2012 - 04:35 PM

That's the second time you mentioned setting the function pointers in the AddRef behaviour. What exactly do you mean with this?

The method you register with asBEHAVE_ADDREF is not supposed to change anything but the internal reference counter of the object.

The crash you're getting looks like it is caused by a previous invalid pointer cast, e.g. you do a C style cast (or reinterpret_cast) where a static_cast/dynamic_cast is needed to re-evaluate the pointer.

Try setting a break point in the function where you're setting the function pointers and verify that the object pointer is really pointing to what you think it is. I believe you'll find that it is pointing to something else. If I'm right you'll need to track down where the object pointer was misinterpreted as something it was not and fix that.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

#16 _Vicious_   Members   -  Reputation: 240

Like
0Likes
Like

Posted 28 January 2012 - 06:46 AM

Hm... In release build program execution simply stops with 'Pure virtual function call' message. I'll try to investigate this further.

Ok, nvm, fixed this. The assertion failure is still there though. It seems to hit several functions and behavoirs, involving several classes.

I now believe this is somehow related to setting a funcdef property in the script in this manner:

void trigger_capture_area_think( cEntity @ent )
{
}

void trigger_capture_area( cEntity @ent )
{
@ent.think = trigger_capture_area_think;
}

when both 'trigger_capture_area' and the think function are called from the application.

#17 _Vicious_   Members   -  Reputation: 240

Like
0Likes
Like

Posted 28 January 2012 - 08:38 AM

In the aforementioned case, in ValidateNoUsage, asCObjectType *type is going to reference the 'cEntity' class and 'asCScriptFunction *func', trigger_capture_area_think.

Maybe trigger_capture_area_think isn't removed because it is still being referenced by an object through a funcdef?

#18 Andreas Jonsson   Moderators   -  Reputation: 3444

Like
0Likes
Like

Posted 28 January 2012 - 09:58 AM

It's possible. I'll make a test and see if I can reproduce the problem with this new information.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

#19 Andreas Jonsson   Moderators   -  Reputation: 3444

Like
0Likes
Like

Posted 28 January 2012 - 08:00 PM

Yes! Finally I was able to reproduce the problem with the following code:


{
  asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);

  engine->BeginConfigGroup("gr");
  engine->RegisterObjectType("type", 0, asOBJ_REF);
  engine->RegisterObjectBehaviour("type", asBEHAVE_ADDREF, "void f()", asMETHOD(Type,AddRef), asCALL_THISCALL);
  engine->RegisterObjectBehaviour("type", asBEHAVE_RELEASE, "void f()", asMETHOD(Type,Release), asCALL_THISCALL);
  engine->RegisterFuncdef("void fun(type @)");
  engine->RegisterObjectProperty("type", "fun @callback", asOFFSET(Type,callback));
  engine->EndConfigGroup();

  asIScriptModule *mod = engine->GetModule("mod", asGM_ALWAYS_CREATE);
  mod->AddScriptSection("s",
	"void func(type @) {} \n"
	"void main(type @t) \n"
	"{ \n"
	"  @t.callback = func; \n"
	"} \n");

  int r = mod->Build();
  if( r < 0 )
	TEST_FAILED;

  Type *t = new Type();

  // Call the function that sets the callback on the object
  asIScriptFunction *m = mod->GetFunctionByName("main");
  asIScriptContext *ctx = engine->CreateContext();
  ctx->Prepare(m);
  ctx->SetArgObject(0, t);
  r = ctx->Execute();
  if( r != asEXECUTION_FINISHED )
	TEST_FAILED;
  ctx->Release();

  // Release the engine, while the object holding the callback is still alive
  engine->Release();

  t->Release();
}

The problem happens because the cEntity object is still alive when the engine is released. If you release the cEntity object before releasing the engine then you should be able to avoid the problem in your game.

I'll investigate what needs to be done to fix the bug in the library.


Thanks for helping me figure out how to reproduce the problem.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

#20 _Vicious_   Members   -  Reputation: 240

Like
0Likes
Like

Posted 29 January 2012 - 03:51 AM

Yeah, I had the same conclusion in my mind. Thanks for being so patient with me Posted Image

However, releasing objects prior to AS shutdown is somewhat problematic due to objects cross-referencing each other, I'm pretty sure that'd totally fuck up AS reference counting.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS