Advertisement

Possible Bug In Asrun Example

Started by July 19, 2016 06:08 PM
1 comment, last by WitchLord 8 years, 4 months ago

As I played with various AS concepts in a small program that I based on "asrun" sample I started getting segfaults, which I tracked to be caused by adding a simple destructor to a class that was instantiated, called some method that caused exception to be set and then exited.

Took me a while, but I think I found the problem and it's probably worth fixing. This example uses callbacks to request and return context from/to a global context pool.

#0 0x000000000044f666 in asCContext::SetObject(void*) ()

#1 0x00000000004950d8 in asCScriptObject::CallDestructor() ()

#2 0x0000000000494ef6 in asCScriptObject::Release() const ()

#3 0x000000000047ae27 in asCScriptEngine::CallObjectMethod(void*, asSSystemFunctionInterface*, asCScriptFunction*) const ()

#4 0x000000000047ad07 in asCScriptEngine::CallObjectMethod(void*, int) const ()

#5 0x000000000045b059 in asCContext::CleanStackFrame() ()

#6 0x0000000000459f8c in asCContext::CleanStack() ()

#7 0x000000000044edac in asCContext::Unprepare() ()

#8 0x000000000040779a in ReturnContextCallback(asIScriptEngine*, asIScriptContext*, void*) ()

#9 0x000000000046cf8b in asCScriptEngine::ReturnContext(asIScriptContext*) ()

#10 0x000000000044a21b in CContextMgr::DoneWithContext(asIScriptContext*) ()

#11 0x000000000040718d in ExecuteScript(asIScriptEngine*, char const*, bool) ()

Key thing probably is exception and destructor and how ReturnContextCallback function returns context to the pool. Here is the function:


void ReturnContextCallback(asIScriptEngine *engine, asIScriptContext *ctx, void * /*param*/)
{
	g_ctxPool.push_back(ctx);
	// Unprepare the context to free any objects it may still hold (e.g. return value)
        ctx->Unprepare();
}

Seems like the context is first returned to the pool as "ready to use", and only then unprepared. In my situation (after exception thrown) this causes context to be cleared of objects, which causes that destructor to be called. To call destructor, it has to fetch context, which it does through callback "ReturnContextCallback" and it yields the very same context as the one that's being unprepared.

I think I fixed this by just moving ctx->Unprepare() above the line that pushes the context back to the pool.

The script I used to reproduce this is simple, it just has to throw exception at some point, while also having a destructor.


class Player
{
   ~Player()
   {
      print("destructor\n");
   }
   
   void foo()
   {
      int x = 0;
      int y = 1 / x;
   }
}

int main()
{
   Player player();
   player.foo();                 
   return 1;
}

Btw, is this correct place to fill some possible bugs/requests or there is some system for this?


Where are we and when are we and who are we?
How many people in how many places at how many times?

Yes, I believe you're right. The context should be unprepared before being made available for reuse. I'll have this fixed.

Posting about bugs on the forum is the preferred method. I keep track of the bug reports and other feedback.

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

Advertisement

I've fixed this in revision 2336

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