[SOLVED] cocos2d-x 2.1.1. Android. SIGSEGV. dynamic_cast

Hello.

I’me getting random and hard to reproduce crashes on Android, with a quite simple game I writting.
Using cocos2d-x 2.1.1

From logcat I know that it is caused by a segmentation fault (SIGSEGV), but the stack trace shows a single stack frame; something like:

I/DEBUG ( 31): #00 pc 0035c520 ..xxx/libgame.so I/DEBUG ( 31): #01 lt 00000000

There is no “#02” entry, just #00 and #01, which seems odd to me.
ndk-stack didn’t help:

“Unable to locate routine information for address 35c520 in module libgame.so”

So I tried using addr2line:

arm-linux-androideabi-addr2line -f -e obj/local/armeabi/libgame.so 35c520

and I get:
libgcc2.c __dynamic_cast

I also generated a map file, to double check the above. Address 35c520 falls inside __dynamic_cast.

I use dynamic_cast a few times in my code, to get objects from a CCArray, which I’m absolutetly sure they are CCSprite.
When crashing, sometimes dynamic_cast returns NULL, but some others return some address.
Anyway, it should not return NULL,…

I’ve read in the forum that some time ago people were getting SIGSEGV when using dynamic casting on Android, which was solved by linking against gnustl_static.

I’m using gnustl_static, as it is by default in cocos2d-x 2.1.1.

Any ideas of how can I proceeed?

Thank you

the following piece of code was the culprit:

   CCARRAY_FOREACH( _pendingRemoves, obj1 )
   {
      CCSprite *spr = dynamic_cast( obj1 );
      if (spr)
      {
         removeFromEngine( obj1 );
         _pendingRemoves->removeObject( obj1 );
      }
   }//endForeach

For anyone who reads this: never remove objects from a CCArray while inside a FOREACH on that array.
Even though I get this clear, I just missed it out this time.
After removing an item, the array indexes change for the next iteration, and “obj1” could point to an already released object.
Anyway, I supposed that dynamic_cast would just return NULL, not crash.

You may be able to use the CCARRAY_FOREACH_REVERSE macro here if it doesn’t matter which object gets removed first.

As a side note dynamic_cast (and any other function) will cause undefined behaviour (i.e. possibly crash) if it reads or writes invalid memory.
The cast cannot verify that the memory you try to access is no longer valid.
If you are on Linux you could try to use valgrind (http://valgrind.org/) to spot exactly these kind of errors (among other ones like memory leaks, using uninitialized variables, etc…)

Thank you, I didn’t think about using CCARRAY_FOREACH_REVERSE before.

Also about the side note. Very useful to bear in mind.
dynamic_cast returns safelly NULL is conversion is not possible, but can crash if the memory points yo a non-valid object or memory space.