virtual Release / AddRef methods cause crash

Started by
12 comments, last by WitchLord 12 years, 11 months ago
I know this is REALLY late, but I just got it recreated in a test program. Attaching the test problem to this post.

Some stuff that might be of interest:

virtual void AddRef()=0;
virtual void Release()=0;

Commenting out these make it all work!


class cMyType : public cExtraBase, public cBaseType
{

Swapping position of cExtraBase and cBaseType (so that a pointer to BaseType has 0 memory offset), makes it all work.

I think there must be some memory problem and that when calling AddRef and Release, not the correct adress is used.


NOTE: I Saw that my first post contained code snipped (the last one) that was exactly the same as the first, and thus must have made the post extra confusion. Really sorry about that!
Advertisement
I tested your code on Visual 2008, and I crash directly after where AddRef should be called.
Actually it's ExtraTesting that is called instead of AddRef. It still seems a lot like pointer arithmetic issues to me. I tried to trace in AngelScript, there is a loooot of manipulation on methods pointers to finally end up to the call in CallObjectMethod. In there the code is different for MSVC and GCC(?) compilers. The last one seems to do some specific tricks to reach the right method via the vtable, but on MSVC it doesn't. My guess is that there is something wrong in here but tbh I have no clue how it could be solved.
Hope the search I did will benefit anyway.
The problem is a bug in AngelScript.

With the sample you provided it only took me 5 minutes to find the problem. When AngelScript is calling the AddRef/Release methods it doesn't use the code in as_callfunc_xxx.cpp, instead it calls the method directly by casting the function pointer to a known function signature, which is a lot faster than the more generic code in as_callfunc_xxx.cpp. Unfortunately in this code I had forgotten to properly adjust the this pointer for class methods on classes with multiple inheritance, hence the crash.

To fix the problem, please add the following line of code to as_scriptengine.cpp in CallObjectMethod (line 2851):


obj = (void*)(size_t(obj) + i->baseOffset);


It's funny how some bugs can live on for so long in the code without being detected. This particular bug is more than 5 years old. :rolleyes:

Thanks a lot for the code that reproduces the problem. I'll be sure to add this to the regression test suite, and also check for problems in the other methods that call class methods directly.

Regards,
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

Fix has been checked into the SVN (rev 879)

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