Problems with EXC_BAD_ACCESS in CCBReader

Hi guys,

I’ve found problems using the CCBReader when deploying my game to an iPhone 4.
There are several potential lines in CCBReader where the game will crash due to memory misalignment.

in CCBReader::readHeader()

int magicBytes = *((int*)(this->mBytes + this->mCurrentByte));

should be

int magicBytes;
unsigned char* pData = ( this->mBytes + this->mCurrentByte );
memcpy( &magicBytes, pData, sizeof( int ) );

in CCBReader::readFloat() there is something really dangerous

float * pF = (float*)(this->mBytes + this->mCurrentByte);
float f = 0;
memcpy(&f, pF, sizeof(float));

should be

float f;
unsigned char* pData = ( this->mBytes + this->mCurrentByte );
memcpy( &f, pData, sizeof( float ) );

The ARM processor which is inside all iPhones, iPads, etc. Doesn’t like memory
misalignment! so be careful doing castings with memory which could be misalignment
after the casting!

You can find more info about this issue here:


Hi Óscar,

Thank you very much. I’ve got crash on my device (see bellow). Your post helped me to save couple days of my life.

I hope cocos2d-x developers will include the fix in the further version.

Best regards,
Fedor

OS Version: iOS 6.0.1 (10A523)
Report Version: 104

Exception Type: EXC_BAD_ACCESS (SIGBUS)
Exception Codes: EXC_ARM_DA_ALIGN at 0x00a6919f
Crashed Thread: 0

Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 Daniel 0x00046ec8 cocos2d::extension::CCBReader::readFloat() (CCBReader.cpp:520)
1 Daniel 0x0004bb26 cocos2d::extension::CCNodeLoader::parsePropTypePosition(cocos2d::CCNode**, cocos2d::CCNode**, cocos2d::extension::CCBReader**, char const**) (CCNodeLoader.cpp:346)
2 Daniel 0x0004ae3a cocos2d::extension::CCNodeLoader::parseProperties(cocos2d::CCNode**, cocos2d::CCNode**, cocos2d::extension::CCBReader*) (CCNodeLoader.cpp:108)
3 Daniel 0x00046468 cocos2d::extension::CCBReader::readNodeGraph(cocos2d::CCNode*) (CCBReader.cpp:610)
4 Daniel 0x000467d4 cocos2d::extension::CCBReader::readNodeGraph(cocos2d::CCNode*) (CCBReader.cpp:719)
5 Daniel 0x000467d4 cocos2d::extension::CCBReader::readNodeGraph(cocos2d::CCNode*) (CCBReader.cpp:719)
6 Daniel 0x000467d4 cocos2d::extension::CCBReader::readNodeGraph(cocos2d::CCNode*) (CCBReader.cpp:719)
7 Daniel 0x000467d4 cocos2d::extension::CCBReader::readNodeGraph(cocos2d::CCNode*) (CCBReader.cpp:719)
8 Daniel 0x00045c02 cocos2d::extension::CCBReader::readFileWithCleanUp(bool, cocos2d::CCDictionary*) (CCBReader.cpp:358)
9 Daniel 0x00045a8a cocos2d::extension::CCBReader::readNodeGraphFromData(cocos2d::extension::CCData**, cocos2d::CCObject**, cocos2d::CCSize const&) (CCBReader.cpp:279)
10 Daniel 0x000455c8 cocos2d::extension::CCBReader::readNodeGraphFromFile(char const**, cocos2d::CCObject**, cocos2d::CCSize const&) (CCBReader.cpp:256)
11 Daniel 0x000454a0 cocos2d::extension::CCBReader::readNodeGraphFromFile(char const*) (CCBReader.cpp:231)

Hi Fedor,

It’s nice to hear that my work serves to someone!
I don’t know why the guys behind Cocos2d-x are not including this bugfix…

Let’s see if in new releases the bug is fixed…

Cheers!

Thanks for your feedback, we will check it.

Óscar García wrote:

Hi guys,
>
I’ve found problems using the CCBReader when deploying my game to an iPhone 4.
There are several potential lines in CCBReader where the game will crash due to memory misalignment.
>
in CCBReader::readHeader()
>
int magicBytes = *((int*)(this->mBytes + this->mCurrentByte));
>
should be
>
int magicBytes;
unsigned char* pData = ( this->mBytes + this->mCurrentByte );
memcpy( &magicBytes, pData, sizeof( int ) );
>
in CCBReader::readFloat() there is something really dangerous
>
float * pF = (float*)(this->mBytes + this->mCurrentByte);
float f = 0;
memcpy(&f, pF, sizeof(float));
>
should be
>
float f;
unsigned char* pData = ( this->mBytes + this->mCurrentByte );
memcpy( &f, pData, sizeof( float ) );
>
The ARM processor which is inside all iPhones, iPads, etc. Doesn’t like memory
misalignment! so be careful doing castings with memory which could be misalignment
after the casting!
>
You can find more info about this issue here:
>
http://stackoverflow.com/questions/3243146/why-does-this-exc-bad-access-happen-with-long-long-and-not-with-int
http://stackoverflow.com/questions/7788216/exc-bad-access-and-char-pointer-to-float-pointer-cast

Dear all:

According to what Óscar said,after modify ,the CocosBuilder test case can run ,but when enter the CocosBuilderTestCase ,

ther background is always flashing.

Hi Shimin,

When I modify the CCBReader was in 2.0.4 version of cocos2d-x. I don’t know If there are more changes since that version.
So I have plenty of cocosbuilder scenes working in my current game ( I’m using cocosbuilder 2.1 ) an everything it’s working ok.
As well the bugfix is for iOS devices… but I think It should work in other devices as well.

The only thing the code does it’s just rely on memcpy to do the memory alignament.

Cheers!

Hi,

Same problem here. App rejected from Apple because it crashed on ipad 3rd.

I test the game on other iDevices and all goes fine but in ipad 3rd it crash.

Cheers

Hi kerker,

What was the problem? it crashed because of EXC_BAD_ACCESS?

I have a lot of cocos builder scenes working in my game and my game
works properly in any iOS device ( iPad3, iPhone5, iPhon4S, etc )

Cheers!

Hi,

Yes EXC_BAD_ACCESS. Here is the crashlog:

Exception Type: EXC_BAD_ACCESS (SIGBUS)
Exception Codes: EXC_ARM_DA_ALIGN at 0x1e248647
Crashed Thread: 0

Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 TrivialJokoa 0x000c1388 cocos2d::extension::CCBReader::readFloat() (CCBReader.cpp:422)
1 TrivialJokoa 0x000c6442 cocos2d::extension::CCNodeLoader::parsePropTypePosition(cocos2d::CCNode**, cocos2d::CCNode**, cocos2d::extension::CCBReader**, char const**) (CCNodeLoader.cpp:318)
2 TrivialJokoa 0x000c5c5e cocos2d::extension::CCNodeLoader::parseProperties(cocos2d::CCNode**, cocos2d::CCNode**, cocos2d::extension::CCBReader*) (CCNodeLoader.cpp:79)
3 TrivialJokoa 0x000c16dc cocos2d::extension::CCBReader::readNodeGraph(cocos2d::CCNode*) (CCBReader.cpp:526)
4 TrivialJokoa 0x000c188c cocos2d::extension::CCBReader::readNodeGraph(cocos2d::CCNode*) (CCBReader.cpp:586)
5 TrivialJokoa 0x000c0fae cocos2d::extension::CCBReader::readFileWithCleanUp(bool) (CCBReader.cpp:689)
6 TrivialJokoa 0x000c0f58 cocos2d::extension::CCBReader::readNodeGraphFromData(cocos2d::extension::CCData**, cocos2d::CCObject**, cocos2d::CCSize const&, cocos2d::extension::CCBAnimationManager**) (CCBReader.cpp:230)
7 TrivialJokoa 0x000c0eea cocos2d::extension::CCBReader::readNodeGraphFromFile(char const**, cocos2d::CCObject**, cocos2d::CCSize const&, cocos2d::extension::CCBAnimationManager**) (CCBReader.cpp:213)
8 TrivialJokoa 0x000c0de4 cocos2d::extension::CCBReader::readNodeGraphFromFile(char const**, cocos2d::CCObject**) (CCBReader.cpp:192)

This is the log that apple sent to me when it test on an iPad 3rd without applying your patch. I’m going to resend the app with the patch.

Cheers

Hi all,
I merged a Pull Request(https://github.com/cocos2d/cocos2d-x/pull/1967) which to fix for unaligned memory access crash in CCBReader::readFloat().
Could you test it? I have tested it on my iOS device(touch3). It works ok now. Let me know whether you guys also make it works.
Thanks. :slight_smile:

Fantastic news James!

I think I fixed the bug around 2 months ago! and I post the solution here but nobody cares about it…
So could tell me a better way to warn about new bugs?

Thanks!

Cheers!

You could make issues on github ( https://github.com/cocos2d/cocos2d-x/issues/new ).

Óscar García wrote:

Fantastic news James!
>
I think I fixed the bug around 2 months ago! and I post the solution here but nobody cares about it…
So could tell me a better way to warn about new bugs?
>
Thanks!
>
Cheers!

this is really good post. Thank you very much.

I’m building a game using Marmalade SDK and the above fix didn’t work for me. This however did:

@

float * pF = (float**);
void**pp = static_cast<void *>(pF);

union hackFloat
{
unsigned char c[4];
float f;
} ;

hackFloat hf;

hf.c[0] = ((unsigned char *)pp)[0];
hf.c[1] = ((unsigned char *)pp)[1];
hf.c[2] = ((unsigned char *)pp)[2];
hf.c[3] = ((unsigned char *)pp)[3];

this->mCurrentByte += 4;
return hf.f;
@

Hi Óscar,
Great finding bro …I was facing this issue when I read ccbi in android game (APP_OPTIM := release in application.mk ) was going to crash . But now it is solved .
Thanks again.