Bug: Cpp Example - Global Object with new/malloc in Construct

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

Bug: Cpp Example - Global Object with new/malloc in Construct

3,594 Views
RuiFaria
Contributor III

Hello!

I am using TWRK70 + MQX 4.0.1 + CW10.4 Windows XP + g++.

I created a new MQX 4.0 project by selecting a Example application named cplus and changed the "HelloWorld" Class to use operator new in Constructor methods of Class, see the changed in below as BOLD:

class HelloWorld {

private:

   int check_init;

   const char *id;

  

   void* pointer;

public:

   HelloWorld() {

      check_init = 0x1234567;

     

      pointer = new int;

   }

   ~HelloWorld() {

      _io_printf("%s: deallocation\n",id);

     

      delete (int*)pointer;

      pointer = NULL;

   }

   void print(const char *x) {

      id = x;

      if (check_init == 0x1234567) {

         _io_printf("%s: Constructed OK\n",id);

      } else {

         _io_printf("%s: Constructor not called\n",id);

      }

   }

};

And it is created a Global Object with the name "global"

static HelloWorld global;

Then Crashed!!

I noticed that the C++ static initializers is called before of MQX initialization and the allocation of HEAP memory.

My quick fix was:

  • comment the following line in __thumb_startup function, in __arm_start.c source file in ARM_GCC_Support\ewl\EWL_Runtime\src\arm folder and recompile it.

          //__call_static_initializers();

  • added the following lines in init_bsp.c source file in mqx\source\bsp\twrk70f120m folder

          #if BSPCFG_ENABLE_CPP

          extern void __init_cpp(void);

          #endif

  • added the following lines in _bsp_enable_card function, in init_bsp.c source file in mqx\source\bsp\twrk70f120m folder

          #if BSPCFG_ENABLE_CPP

             /* initialize C++ constructors */    

              __init_cpp();

          #endif

  • recompile MQX Kernel

Seems to work properly but i don't know if it is missing some detail. Anyone can help me?

Thanks.

Tags (4)
0 Kudos
8 Replies

1,085 Views
KJFPE
Contributor III

Hi Rui,

This may be of some interest I had the same problem using IAR rather than CW and I had to change some linker options

--redirect __iar_dlmalloc=malloc
--redirect __iar_dlcalloc=calloc
--redirect __iar_dlfree=free
--skip_dynamic_initialization

And then, first thing in my main function before any tasks etc I had to issue the following

__iar_dynamic_initialization();   // initialize c++ initialized data

I know this isn’t the same for CW but thought it may at least be helpful and may help in were to look

Kevin    

0 Kudos

1,085 Views
RuiFaria
Contributor III

Hi Kevin,


I could find or try some of those linker options in CW, specially the "--skip_dynamic_initialization" and only call it after the initialization of MQX and memory. Because i didn't want to change the sources of ARM_GCC_Support provided by CW.

Thank you for the attention.

Best Regards,

Rui Faria

0 Kudos

1,085 Views
c0170
Senior Contributor III

Hello,

I have received an answer from one of our engineers:

  1. Existing MQX/C++ support depends on third-part toolchain startup routines.All of the supported toolchains invoke static object constructors before the main function – which starts the MQX. It means that you are not allowed to use new, malloc, alloc, … or any MQX system functions. Static constructors should setup only constant values to attributes. The number of static object constructors is also limited to 32. The information about restrict C++ usage is missing in the MQX documentation, it will be updated in the next release.

  1. Your modification allows to use new/malloc operator in static constructors and also allow to use “unlimited” number of static object constructors,but you might violate the C++ standard - the initialization process of static object constructors is implementation-defined and you moved it from before-main to inside-main. Thus it is non-portable solution across other toolchains.

Thanks for your feedback! We will consider to provide full C++ support in the future.

Regards,

0xc0170

0 Kudos

1,085 Views
RuiFaria
Contributor III

Hi Martin!

I know that it is not standard, i shouldn't change the sources of ARM_GCC_Support provided by CW but is it only a limitation of Kinetics?

I already use new/malloc in Constructors in Coldfire MCF52259 without problems and now i am porting to Kinetic K70.

Thank you for the attention.

Best Regards,

Rui Faria

0 Kudos

1,085 Views
davemcgahey
Contributor I


I am having a similar problem when I attempt to declare a constant string in a header file as follows:

static const std::string x = "123456789123456789123456789";

I was thinking that the size of this string would be known at compile time and it would be placed in the constants code section. Instead what happens is the static initializer calls the string constructor code. The constructor invokes the memory allocator when the string size is greater than a predetermined value (which this case is). Since mqx was not initialized the program crashes.

I have no problems doing this on other systems, so I believe this is a bug.

Dave

0 Kudos

1,085 Views
RuiFaria
Contributor III

Hi,

I also believe that it is a bug.

The initialization of MQX in Kinectics is wrong.

We have to wait and hope for full C++ support.

0 Kudos

1,085 Views
KJFPE
Contributor III

Hi I am not sure I agree with your response here is a section copied from the MQXUG.pdf


6.3 Global Constructors

I need to initialize some global constructors, which use the 'new' operator, before I call 'main'; that is, before I start MQX. The 'new' operator calls malloc(), which I redefine to call the MQX function _mem_alloc(). How do I do this?

Initialize the constructors from _bsp_enable_card() (in init_bsp.c), which MQX calls after it initializes the memory management component.

0 Kudos

1,085 Views
c0170
Senior Contributor III

Hello Rui Faria,

we will look into it. I'll share this with the team.

I'll inform you with any changes.

Regards,

0xc0170

0 Kudos