release build crashes, debug build fine

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

release build crashes, debug build fine

2,169 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by bmentink on Tue Nov 23 18:16:30 MST 2010
Hi All,

I have an application running just fine in debug configuration (compile flags -g3 -O0) but when I do a release build (compile flags -O1 or -Os etc) then my program goes off into the weeds.

To investigate I did a build with -g3 -O1 options and managed to track it to the first time that memcpy() was used. I have checked the arguments and they are all valid pointers in memory range and the count is fine also. But soon as memcpy executes it dies ..:confused:

I am stuck, I have tried different clib's i.e Redlib,Newlib or the standard clib, but all do the same thing.

Anyone got a clue on this?

Many Thanks,
Bernie
0 Kudos
Reply
9 Replies

2,076 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Fri Nov 26 08:27:33 MST 2010

Quote: bmentink
Yes, using -fno-builtin fixes the issue also, what does this option do, I find it hard to get information on it in the gcc documentation.



Pointer to built in and online gcc docs....
http://support.code-red-tech.com/CodeRedWiki/GCCdocs

Pointer to actual page containing details of -fno-built-in...
http://gcc.gnu.org/onlinedocs/gcc-4.3.3/gcc/C-Dialect-Options.html#C-Dialect-Options
0 Kudos
Reply

2,076 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by bmentink on Thu Nov 25 11:38:36 MST 2010
Hi,

Yes, using -fno-builtin fixes the issue also, what does this option do, I find it hard to get information on it in the gcc documentation.

I do think that my local version (which does get in-lined ok) would work faster than the non-inlined standard cLib version of memcpy.

However, I will try to duplicate this bug in a standalone function, so that you can verify it ... will do that shortly ..

Cheers,
Bernie
0 Kudos
Reply

2,076 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Thu Nov 25 03:42:04 MST 2010
What you are seeing is the compiler optimising out the call to memcpy and replacing it with inline code. (This is why you see the issue when linking against both Redlib and Newlib, as the issue is not within the library at all).

The compiler actually only does this memcpy inlining in a fairly limited number of cases, and by default with projects built using the LPCXpresso IDE will not do it at all.

As a first step, I suggest that you look to see if your build script uses the "[FONT=Courier New][SIZE=1]-fno-builtin[/SIZE][/FONT]" option, as IDE projects do. This should then disable any possibility of the compiler inlining memcpy. This should hopefully solve your problem.

In my testing, I have so far been unable to provoke a faulty inlining of memcpy such as you have seen. In order to investigate this any further, I will really need:

[LIST]
[*]A compilable piece of code which shows up the problem (ie a cut down, standalone version of the function in your code in which you see this issue occuring).
[*]All the command line options you using to build that code.
[/LIST]
Regards,
CodeRedSupport
0 Kudos
Reply

2,076 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by bmentink on Wed Nov 24 13:48:12 MST 2010
Oops looks like we overlapped again ... thanks for that last response confirmed what I was thinking ..:)

I could not use your optimize-per-file option, as my project is a makefile project and also since I use memcpy() everywhere in my code, would be pointless(I would have to do too many files).

As a workaround, I have replaced the cLib memcpy() with my own version, which does not get optimized with the LDMIA instruction and that works fine.

However, my memcpy would be slower than the optimized cLib version so the solution is not ideal.
This seems to me like a bug in the GCC compiler ... if optimizations produce an unusable memcpy().

I would like a better solution to my own memcpy(), is there a better way?

Cheers,
Bernie
0 Kudos
Reply

2,076 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by bmentink on Wed Nov 24 13:35:24 MST 2010

Quote: CodeRedSupport
In that case, have you read....

http://support.code-red-tech.com/CodeRedWiki/DebugHardFault

To be honest, without actually seeing your code there is little further help we can provide here. You probably need to try single stepping though your code, looking at registers and memory in order to identify what exactly is triggering the hard fault.

Regards,
CodeRedSupport.



I have shown you the relevant code, even the assembly, what more do you want?

I repeat, it is failing on the execution of memcpy() I cannot supply the code to that as it is a clib function, I can only show you the parameters passed, and I have done that in spades ....

My only observation is the line:

00003b06: ldmia r5!, {r0, r1, r2, r3}

r5 has the value 0x10005a1e which is an odd address, is the problem one of data alignment, and if so how do I ensure the pointer (pFrame) is aligned?

Regards,
Bernie
0 Kudos
Reply

2,076 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Wed Nov 24 13:32:36 MST 2010
Just noticed that you updated your last post, after I posted.

Well I can see what is causing the hard fault. An LDMIA has to be to a word aligned address - and r5 is pointing to a half word boundary. This hence causes a fault, as per the following extract for the ARM v7M Architecture Reference Manual...

A3.2.1    Alignment behavior
Address alignment affects data accesses and updates to the PC.

Alignment and data access
The following data accesses always generate an alignment fault:

[LIST]
[*] Non halfword-aligned LDREXH and STREXH
[*]Non word-aligned LDREX and STREX
[*]Non word-aligned LDRD, LDMIA, LDMDB, POP, LDC, VLDM, and VPOP
[*]Non word-aligned STRD, STMIA, STMDB, PUSH, STC, VSTM, and VPUSH.
[/LIST]

[Pointer to the ARM ARM at http://support.code-red-tech.com/CodeRedWiki/ArmCpuInfo]

I can't explain at this point exactly why the compiler  inlining the memcpy call in this way (I don't currently have access to the tools to test this out), but would suspect that your cast is fooling it in some way. I'll have a look at this tomorrow (UK time).

In the meantime, as a temporary workaround, I would suggest simply turning off optimisation for this particular file, as per the FAQ:

http://support.code-red-tech.com/CodeRedWiki/PerFileProperties

Regards,
CodeRedSupport
0 Kudos
Reply

2,076 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Wed Nov 24 12:32:14 MST 2010
In that case, have you read....

http://support.code-red-tech.com/CodeRedWiki/DebugHardFault

To be honest, without actually seeing your code there is little further help we can provide here. You probably need to try single stepping though your code, looking at registers and memory in order to identify what exactly is triggering the hard fault.

Regards,
CodeRedSupport.
0 Kudos
Reply

2,076 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by bmentink on Wed Nov 24 12:03:45 MST 2010
Thanks for the response ... I will look into the "volatile" aspect as pointed out in that link.

As to your question of where in the weeds my program goes ... as soon as it gets to the memcpy() function, it goes into a hard fault.

Edit: Here is some more detail

The function I am calling at the time this happens is called like this:

Quote:
memcpy ((U8 *)(pQueue->pTail), (U8 *)pFrame, 20);



pQueue->pTail address in the debugger is 0x10003290 and pFrame is 0x10005a1e, size = 20.

Soon as I step into/over that function I get a hard fault, and this is reported in GDB.


Quote:
Warn : Block read error address 0x10008000
Warn : lpc1766.cpu -- clearing lockup after double fault
Warn : Block read error address 0xfffffff8



Into the assembly code:


Quote:
42             memcpy ((U8 *)(pQueue->pTail), (U8 *)pFrame, sizeof(CAN_MSG));
                   00003b02:   ldr.w r4, [r6, #4004]   ; 0xfa4
--- FAILS HERE --> 00003b06:   ldmia r5!, {r0, r1, r2, r3}
                   00003b08:   stmia r4!, {r0, r1, r2, r3}
                   00003b0a:   ldr r3, [r5, #0]
                   00003b0c:   str r3, [r4, #0]



r5 has 0x10005a1e and r4 has 0x10003290

Still don't see why it fails.


Cheers,
Bernie
0 Kudos
Reply

2,076 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Wed Nov 24 01:18:42 MST 2010
There are a couple of basic suggestions to check out in such circumstances in the our compiler optimization FAQ:

http://support.code-red-tech.com/CodeRedWiki/CompilerOptimization

Beyond that, where in the weeds do you actually go? Do you end up in the hard fault handler, another exception handler? If not, if you pause execution are you somewhere in your code, somewhere in library code, somewhere else?

If you have traced this down to a particular point in your code, look at the disassembly and core registers, and try to see what is happening at the instruction level rather than source level. Instruction single stepping can often help here.

The following FAQs on disassembly may be of help:

[B]Displaying assembly instructions when debugging[/B]
http://support.code-red-tech.com/CodeRedWiki/DebugViewAsm

[B]Disassembling objects and executables[/B]
http://support.code-red-tech.com/CodeRedWiki/DisassObsjExes

Regards,
CodeRedSupport
0 Kudos
Reply