Jump to content

  • Log In with Google      Sign In   
  • Create Account


- - - - -

Access to NULL-Pointer when releasing engine


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
16 replies to this topic

#1 Friggle   Members   -  Reputation: 133

Like
0Likes
Like

Posted 01 May 2012 - 05:44 AM

Hi,

I just dropped in AngelScript 2.23.1 (as replacement for 2.23.0) and now my application crashes when I finally want to release the engine. I'm using VC9 under Win7.

When stepping down starting from the following call
mpEngine->Release();
the code line
asDELETE(const_cast<asCScriptEngine*>(this),asCScriptEngine);
calls the destructor of the engine:
asCScriptEngine::~asCScriptEngine()
The last line of the destructor calls
asCThreadManager::Release();
which tries to lock a crit section object:
void asCThreadCriticalSection::Enter()
{
#if defined AS_POSIX_THREADS
pthread_mutex_lock(&criticalSection);
#elif defined AS_WINDOWS_THREADS
EnterCriticalSection(&criticalSection);
#endif
}
The pointer '&criticalSection' is NULL, that's where the code crashes.

Any ideas to this?

Many thanks and regards,
Thomas

Edited by Andreas Jonsson, 01 May 2012 - 04:13 PM.


Sponsor:

#2 Friggle   Members   -  Reputation: 133

Like
0Likes
Like

Posted 01 May 2012 - 06:03 AM

Here's some additional info:

When entering the code
void asCThreadManager::Release()
{
// It's necessary to protect this section so no
// other thread attempts to call AddRef or Release
// while clean up is in progress.
ENTERCRITICALSECTION(criticalSection);
if( --threadManager->refCount == 0 )
{
  // The last engine has been destroyed, so we
  // need to delete the thread manager as well
  asDELETE(threadManager,asCThreadManager);
  threadManager = 0;
}
LEAVECRITICALSECTION(criticalSection);
}
The expression threadManager->refCount is 1 which seems to be plausible to me.
When looking at the section where the (static) instance of the csritical section should be created:
#ifndef AS_NO_THREADS
static DECLARECRITICALSECTION(criticalSection)
#endif
It seems that I do not define 'AS_NO_THREADS', i.e. this should be fine, too.
Still, the static 'criticalSection' can't be resolved by the debugger...

#3 Andreas Jonsson   Moderators   -  Reputation: 3288

Like
0Likes
Like

Posted 01 May 2012 - 12:35 PM

Do you use multiple script engines in parallel? Perhaps this is what triggers the problem.

When you debug you need to check in which scope you're looking at the criticalSection. The global static criticalSection is of the type asCThreadCriticalSection. That class in itself as a member also called criticalSection (poorly named, I know). It is possible the debugger is seeing one or the other depending on where you're checking.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

#4 Friggle   Members   -  Reputation: 133

Like
0Likes
Like

Posted 01 May 2012 - 01:00 PM

Do you use multiple script engines in parallel? Perhaps this is what triggers the problem.

No, I'm just using one single script engine instance, created through the following code:
mpEngine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
I'll check again with the scope of the criticalSection during the debug session and post again.

Regards,
Thomas

#5 Andreas Jonsson   Moderators   -  Reputation: 3288

Like
0Likes
Like

Posted 01 May 2012 - 01:16 PM

I checked in a minor change in 1291 where I renamed the criticalSections. The global one is now prefixed with 'g_' and the member is prefixed with 'm_'.

I made a test with multiple engines, but it seems to be working properly too.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

#6 Friggle   Members   -  Reputation: 133

Like
0Likes
Like

Posted 01 May 2012 - 01:40 PM

OK, here's some more information:
I renamed the global criticalSection object (statically allocated in as_Thread.cpp) to 'gCriticalSection'.
In the following code:
void asCThreadCriticalSection::Enter()
{
#if defined AS_POSIX_THREADS
pthread_mutex_lock(&criticalSection);
#elif defined AS_WINDOWS_THREADS
EnterCriticalSection(&criticalSection);
#endif
}
I have a breakpoint on the 'ENterCriticalSection...' line.
My watch window output is attached.
Does that help?

Thanks so much and regards,
Thomas

Attached Thumbnails

  • Watch.jpg


#7 Friggle   Members   -  Reputation: 133

Like
0Likes
Like

Posted 01 May 2012 - 01:44 PM

OK, we had the same idea it seems... Anyway, I guess there's no much use trying your renamed version, too?
Regards,
Thomas

#8 Friggle   Members   -  Reputation: 133

Like
0Likes
Like

Posted 01 May 2012 - 02:00 PM

One more observation:
The criticalSection member is initialized during the constructor of asCThreadCriticalSection:
#ifndef AS_NO_THREADS
asCThreadCriticalSection::asCThreadCriticalSection()
{
#if defined AS_POSIX_THREADS
pthread_mutex_init(&criticalSection, 0);
#elif defined AS_WINDOWS_THREADS
InitializeCriticalSection(&criticalSection);
#endif
}
For the global gCriticalSection there is no call to 'InitializeCriticalSection(...)'. Could this be an issue?

Regards,
Thomas

#9 Andreas Jonsson   Moderators   -  Reputation: 3288

Like
0Likes
Like

Posted 01 May 2012 - 02:05 PM

Not yet. I haven't done any fixes in the new revision.

But there is definitely something wrong. When I set a breakpoint on EnterCriticalSection in my test bed I get the following values in the member criticalSection:

DebugInfo -> address of an object that holds valid information
LockCount -> -1

The rest of the members are 0.

It looks like the criticalSection in your application has somehow become corrupt. Probably some memory invasion that overwrote the global memory.

I suggest setting a memory break point on the gCriticalSection->criticalSection->DebugInfo to see when the address changes. It should only change once, when the InitializeCriticalSection() is called on start up.
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 Andreas Jonsson   Moderators   -  Reputation: 3288

Like
0Likes
Like

Posted 01 May 2012 - 02:07 PM

One more observation:
The criticalSection member is initialized during the constructor of asCThreadCriticalSection:

#ifndef AS_NO_THREADS
asCThreadCriticalSection::asCThreadCriticalSection()
{
#if defined AS_POSIX_THREADS
pthread_mutex_init(&criticalSection, 0);
#elif defined AS_WINDOWS_THREADS
InitializeCriticalSection(&criticalSection);
#endif
}
For the global gCriticalSection there is no call to 'InitializeCriticalSection(...)'. Could this be an issue?

Regards,
Thomas


It is the constructor of the global gCriticalSection that calls InitializeCriticalSection() on the member.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

#11 Friggle   Members   -  Reputation: 133

Like
0Likes
Like

Posted 01 May 2012 - 02:22 PM

It is the constructor of the global gCriticalSection that calls InitializeCriticalSection() on the member.

Certainly, I mixed it up again with the struct CRITICAL_SECTION. Seems it's too late today already, I'm getting numb ;-)

I'll post again when I have news from the memory breakpoint.

#12 Friggle   Members   -  Reputation: 133

Like
0Likes
Like

Posted 01 May 2012 - 02:27 PM

When I set a breakpoint on EnterCriticalSection in my test bed I get the following values in the member criticalSection:

Did you also try to enable the breakpoint only after the last line of the desctructor of asCScriptEngine has been reached:
asCThreadManager::Release();
Only in this case I got the strange values and the crash. All preceding calls go fine.

#13 Friggle   Members   -  Reputation: 133

Like
0Likes
Like

Posted 01 May 2012 - 02:39 PM

I think now I know what to look at a bit closer:
I've incorporated the AngelScript engine in a class that is a Singleton and which is itself statically allocated. During this classes' destructor the mpEngine->Release() call is made. I guess at this point the also statically allocated asCThreadCriticalSection object (gCriticalSection) is already dead... Simply a question of the order of destructor calls by the compiler, possibly. I'll look into this some more and probably may decide to call the Release() method somewhere else, i.e. earlier.

Regards,
Thomas

#14 Andreas Jonsson   Moderators   -  Reputation: 3288

Like
0Likes
Like

Posted 01 May 2012 - 02:42 PM

ah.

Do you by any chance keep the engine pointer in a singleton, i.e. a global object where the destructor of that object is the one that releases the engine? If that is so, it might be that the destructor of the global critical section has been called before the destructor of your singleton, which would explain why you get the crash.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

#15 Andreas Jonsson   Moderators   -  Reputation: 3288

Like
0Likes
Like

Posted 01 May 2012 - 02:46 PM

:)

We came to the same conclusion at the same time. I remember seeing this before in an earlier version of AngelScript where I had also allocated the thread manager globally, and the same kind of crashes happened for others who like you stored the engine in a singleton.

I'll have to find a way to avoid storing the critical section in the global memory. It has to be created with the first engine instance and destroyed with the last one. The problem will just be in how to do this in a multithreaded environment where multiple engines might get created at the same time.
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 Andreas Jonsson   Moderators   -  Reputation: 3288

Like
0Likes
Like

Posted 01 May 2012 - 04:09 PM

I've removed the global criticalSection in revision 1293, it is now a member of the thread manager instead. You should no longer face the crash with this version.

For version 2.24.0 I'll add two new global functions to deal with the problem that led me to create the global criticalSection in the first place. These new global functions will only be required for those applications that uses multiple engines in multiple threads, so most projects will probably not even need to know about them.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

#17 Friggle   Members   -  Reputation: 133

Like
0Likes
Like

Posted 02 May 2012 - 11:48 AM

Perfect, just tried out rev 1293 and the crash is gone.

Many thanks again for the great and super fast support!

Regards,
Thomas




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