free() crashing - M5223X project

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

free() crashing - M5223X project

3,359 Views
mjbcswitzerland
Specialist V
Hi All

I have been avoiding any libraries but have had to use malloc and free so added the C_TRK_4i_CF_SZ_MSL.a libray (as is used in M52235 demo projects).

I set up the heap in the linker to be restricted to 1024 bytes rather than spanning from the end of BSS to (initial stack pointer - stack size).

There are the relevant linker delivered values which are as expected.
#>00000400          HEAP_SIZE (linker command file)
#>200006D0          ___HEAP_START (linker command file)
#>20000AD0          ___HEAP_END (linker command file)
#>200006D0          ___heap_addr (linker command file)
#>00000400          ___heap_size (linker command file)
#>20008000          __SP_INIT (linker command file)

When I call [test = malloc(100)] all is well. I get memory within the expected range.

When I call free (test) I get an exception. Using the debugger I see the following calls:
- void _MSL_CDECL __FREE(void* ptr)
-     __pool_free(get_malloc_pool(), ptr);
-         deallocate_from_var_pools(pool_obj, ptr);
-     Block_link(bp, sb);
In this routine there is an instruction sequence which I can't relate back to the src code:
lea (-4,a5,d7.l),a6  (a6 gets the value 0x000003FE - somewhere in the startup code)
movea.l (a6),a1     (a1 gets the value 0xffff0000)
tst.l a1
beq.s _block_link
move.l 8(a1),d0   (exception caused here)



So my questions. How is it possible that free() can crash - does it require something which I haven't done?
Am I using the correct library for my M52235 application?

Best regards

Mark Butcher

www.uTasker.com


Labels (1)
0 Kudos
8 Replies

445 Views
mjbcswitzerland
Specialist V
Hi All

I have some new news. [No using library C_4i_CF_SZ_MSL.a for malloc]
I have analysed the complete code and also stepped through it in assembler to try to find out what is going wrong. It turns out that it is not free which is causing the error but malloc. And the malloc functions perfectly up to the point when the pointer to the chunk is returned.
The library routine is returning it in A0 but the code calling the library function is using the value in D0.

I did a lot of stepping and analysing to get to the return where it is finally all going wrong!! But at least it is clear now.

But I can't see why the application code is not compatible with the library. The malloc prototype is correct so the code knowns that it is a pointer and not a value being returned. Is this a compiler set up incompatibility?

I tried with standard and compact parameter passing - compact passing [which I use as standard] produces smaller code but the result was the same. Register passing didn't work - presumably because the library would have to be built for this.

But I haven't been able to find a way yet to get the compiler to use returned pointers from A0 rather than D0.

Any ideas????

Regards

Mark Butcher


0 Kudos

445 Views
CrasyCat
Specialist III
Hello
 
Which version of Code Warrior for Coldfire are you using?
  To retrieve that info:
    - Start CodeWarrior
    - Select Help -> About Freescale CodeWarrior
    - Click on "Install Products"
    - CodeWarrior version used is displayed on top in the Installed Products dialog.
The issue you are facing seems to indicate that you are using the function malloc, but have no prototype for the function prior to invoking it.
 
Did you include stdlib.h at the beginning of the source file?
 
Did you check the warning generated while building the source file?
 
CrasyCat
0 Kudos

445 Views
mjbcswitzerland
Specialist V
Hi CrazyCat

Version is CW6.3 build 14 (IDE 5.7.0 Build 2015).

The project is set up with "Require function prototypes" and compiles with zero warnings. <stdlib.h> is included and if removed there is an error.
Therefore I am quite sure that it is due to the compiler setup. I checked other routines which return pointers in the application part (i.e. the part which  is compiled and not taken from a library) and these all return the pointers in D0. Therefore it is almost certainly the case that the compiler is passing everything back in D0 and not distinguishing between values and pointers.

I studied some documentation (Coldfire build tool reference.pdf) and found the pragmas POINTERS_IN_D0 and POINTERS_IN_A0. It seems therefore that the project is being compiled with POINTERS_IN_D0 while the library was built with POINTERS_IN_A0.
But I can't get the main code to compile any differently when using the A0 pragma. I found that it would accept it without any warnings or errors when written like this:
  #pragma pointers_in_a0 on
  #pragma pointers_in_d0 off
but there is no change in the use of the registers. Other pragmas are displayed in blue when they are recognised by CW but these remain black so I do think that they are not recognised.

Of course I could solve the problem by rebuilding the library with the same compiler but would prefer to solve it by making the project compatible with the pre-built libraries.

Thanks for any futher tips.

Regards

Mark


0 Kudos

445 Views
CrasyCat
Specialist III
Hello
 
OK I do not have a CodeWarrior for Coldfire V6.3 installed, but I did some test with V6.4.
 
Basically I have created a project from a stationery for CF_M52230DEMO board in C.
 
I added the include stdio.h and invoked malloc in my main application.
I am reading the return value from A0 (Which seems to be correct).
Actually I get following assembly code.
 
Code:
;   16:  ptr= malloc (100); ;   17:   ;0x00000014  0x2EBC00000064   move.l   #100,(a7)             ; '...d'0x0000001A  0x4EB900000000   jsr      _malloc0x00000020  0x23C800000000   move.l   a0,_ptr

 I assume the problem comes from your project settings or command line options.
 You may want to submit a service request around that.
 
To log the issue please go to following URL:
    http://www.freescale.com/TechSupport
and click on "Submit a service request"
 
Make sure to attach a reproducible case to the SR.
 
CrasyCat
0 Kudos

445 Views
mjbcswitzerland
Specialist V
Hi CrasyCat

I did the same but the result is different. I can't believe that CW6.3 doesn't work so it must be something local. I have just ordered a new M52223EVB so I am hoping that it will be delivered with CW6.4 Special edition - then I will make a new installation.

Here's the code:

#include <stdlib.h>

int main()
{
    unsigned char *ptr;
    ptr = malloc(100);
    free(ptr);
    return 0;
}


and the assembler
20000500: 4E560000        link     a6,#020000504: 598F            subq.l   #4,a720000506: 2EBC00000064    move.l   #100,(a7)2000050C: 4EB9200012A0    jsr      _malloc (0x200012a0)    ; 0x200012a020000512: 2040            movea.l  d0,a0 <--- overwrites correct a0 !!20000514: 2E88            move.l   a0,(a7)20000516: 4EB9200012B4    jsr      _free (0x200012b4)      ; 0x200012b42000051C: 7000            moveq    #0,d02000051E: 4E5E            unlk     a620000520: 4E75            rts20000522: 4E71            nop

It crashes in free since ptr is corrupted (as expected).

Here I have tried with various optimisations but otherwise left the stationary set up as it was created.

It seems too obviously wrong to set up a service request...

Regards

Mark
0 Kudos

445 Views
CrasyCat
Specialist III
Hello
 
Note that you can download an evaluation version of CodeWarrior for Coldfire V6.4 from Freescale CodeWarrior web page:
 
This grant you access to the software for 2 weeks after installation.
 
I took exactly the code you have submitted below and I get following code generated at optimization level 0:
 
Code:
0x20000500  0x4E560000         link     a6,#00x20000504  0x4FEFFFF4         lea      -12(a7),a7;;   15:     ptr = malloc(100); ;   16:      ;0x20000508  0x7064             moveq    #100,d00x2000050A  0x2E80             move.l   d0,(a7)0x2000050C  0x4EB920001294     jsr      0x20001294            ; 0x200012940x20000512  0x2D48FFFC         move.l   a0,-4(a6)0x20000516  0x202EFFFC         move.l   -4(a6),d00x2000051A  0x2D40FFF8         move.l   d0,-8(a6);;   17:     free(ptr);     ;0x2000051E  0x202EFFF8         move.l   -8(a6),d00x20000522  0x2E80             move.l   d0,(a7)0x20000524  0x4EB9200012A8     jsr      0x200012a8            ; 0x200012a8

 So I really suspect something weird in your project...
 Did you look at the preprocessor listing file? This might bring some light around the reason for the problem?
 
To generate the preprocessor listing select the source file in the .mcp window and select preprocess.
Then in the preprocessor listing file, check:
  1- Whether you have several prototypes for malloc
  2- Whether the pragma pointers_in_D0 is specified somewhere.
 
CrasyCat
0 Kudos

445 Views
mjbcswitzerland
Specialist V
Hi CrazyCat

I have used this technique before but hadn't though about it here.

And it has indeed shown that the header "mwerks.h" is delivering this elusive pragma!!!!!

/* * Force functions to return values in D0 */#pragma pointers_in_D0
 

I checked mwerks.h in all M5223X CW projects and they all do it. Other devices don't have it.
Therefore someone must have really removed it in the CW6.4 package!!

I changed the "mwerks.h" header to use #pragma pointers_in_A0 and now - as if by magic - everything works just perfectly...

So my conclusion seems to be that it is not possible to use libraries in the CW6.3 version (for M5223X) without doing the same modification to the delivered files, which I find hard to believe!!! Perhaps there is a more logical explanation somewhere but the most important thing is that the problem is understood and the solution is known.

Many thanks!!

Regards

Mark



Message Edited by mjbcswitzerland on 2007-06-21 02:07 PM
0 Kudos

445 Views
CrasyCat
Specialist III
Hello
 
I am glad we find this one out.
 
I will make sure our Coldfire people know about that issue, but as it is fixed in V6.4 (Which is the current release), I am not sure I can do much more here.
 
CrasyCat
0 Kudos