cortex-M cpp destructor problem

Asked by Jonathan Dumaresq

Hi,

We use this compiler Version 4.6u4 and we have found an interesting problem.

First we use cpp classes in our application. Some are created with NEW and some are global. From what I see, the newlib default __libc_init_array create all the global classes (call constructor) automaticaly.

BUT also create a destructor table in case of problem (__atexit). On embedded platform like cortex-M, we never exit the code. This will use RAM (dynamicaly allocated) but will never used.

We have also found a probem in the function __register_exitproc from __atexit.c of newlib 1.20.0. I have no Idea from where this function is called, but from what I can see, the arg 'args = p->_on_exit_args_ptr;' is not initialised to something before calling the __register_exitproc. Then the args contain a bad value (mostly something that is on the memory pointed by p->_on_exit_args_ptr. Then if the contain of this memory is not Zero or a valid address range for the cortex, the cortex Hardfault.

For now we have created an empty __cxa_atexit function in our code to not create the destructor table.

I would like to know if there is something special to pass on compiler line to not use the destructor table , and not using exit function at all.

Regards

Jonathan

Question information

Language:
English Edit question
Status:
Solved
For:
GNU Arm Embedded Toolchain Edit question
Assignee:
No assignee Edit question
Solved by:
Joey Ye
Solved:
Last query:
Last reply:
Revision history for this message
Joey Ye (jinyun-ye) said :
#1

Jonathan,

Can you please try newlib-nano of 4.7, which excludes __atexit for C program. For C++ it still do something for atexit due to __cxa_atexit.

Basically what newlib-nano does is making atexit weak symbol, and dynamically allocating atexit data structure when needed. If atexit doesn't linked in or run, RAM won't be allocated for it.

- Joey

Revision history for this message
Jonathan Dumaresq (jdumaresq) said :
#2

Hi Joey,
> Jonathan,
>
> Can you please try newlib-nano of 4.7, which excludes __atexit for C
> program. For C++ it still do something for atexit due to
> __cxa_atexit.
>
> Basically what newlib-nano does is making atexit weak symbol, and
> dynamically allocating atexit data structure when needed. If atexit
> doesn't linked in or run, RAM won't be allocated for it.
>

Right now we are at the end of a project. So we will stay at 4.6 series. I
will try the new 4.7 series in a couple a weeks. The trick now is to define
the __cxa_atexit in our code and do nothing. I have also a couple of other
cxa function that we have redifined.

__extension__ typedef int __guard __attribute__((mode (__DI__)));
extern "C" int __cxa_atexit ( void (*f)(void *), void *p, void *d );
extern "C" int __cxa_guard_acquire(__guard *);
extern "C" void __cxa_guard_release (__guard *);
extern "C" void __cxa_guard_abort (__guard *);
extern "C" void __cxa_pure_virtual(void);

int __cxa_guard_acquire(__guard *g) {return !*(char *)(g);};
void __cxa_guard_release (__guard *g) {*(char *)g = 1;};
void __cxa_guard_abort (__guard *) {};
void __cxa_pure_virtual(void) {while(1);}
int __cxa_atexit ( void (*f)(void *), void *p, void *d ){return 0;};

Whith thoses function in our code, we reduce considerably our code size.
Since the exception are not used.

I don't know if we should redefined more cxa__ function ?

Regards

Jonathan

Revision history for this message
Best Joey Ye (jinyun-ye) said :
#3

No others as I know
On Feb 6, 2013 9:25 PM, "Jonathan Dumaresq" <
<email address hidden>> wrote:

> Question #221105 on GCC ARM Embedded changed:
> https://answers.launchpad.net/gcc-arm-embedded/+question/221105
>
> Status: Answered => Open
>
> Jonathan Dumaresq is still having a problem:
> Hi Joey,
> > Jonathan,
> >
> > Can you please try newlib-nano of 4.7, which excludes __atexit for C
> > program. For C++ it still do something for atexit due to
> > __cxa_atexit.
> >
> > Basically what newlib-nano does is making atexit weak symbol, and
> > dynamically allocating atexit data structure when needed. If atexit
> > doesn't linked in or run, RAM won't be allocated for it.
> >
>
> Right now we are at the end of a project. So we will stay at 4.6 series. I
> will try the new 4.7 series in a couple a weeks. The trick now is to define
> the __cxa_atexit in our code and do nothing. I have also a couple of other
> cxa function that we have redifined.
>
> __extension__ typedef int __guard __attribute__((mode (__DI__)));
> extern "C" int __cxa_atexit ( void (*f)(void *), void *p, void *d );
> extern "C" int __cxa_guard_acquire(__guard *);
> extern "C" void __cxa_guard_release (__guard *);
> extern "C" void __cxa_guard_abort (__guard *);
> extern "C" void __cxa_pure_virtual(void);
>
> int __cxa_guard_acquire(__guard *g) {return !*(char *)(g);};
> void __cxa_guard_release (__guard *g) {*(char *)g = 1;};
> void __cxa_guard_abort (__guard *) {};
> void __cxa_pure_virtual(void) {while(1);}
> int __cxa_atexit ( void (*f)(void *), void *p, void *d ){return 0;};
>
> Whith thoses function in our code, we reduce considerably our code size.
> Since the exception are not used.
>
> I don't know if we should redefined more cxa__ function ?
>
> Regards
>
> Jonathan
>
> --
> You received this question notification because you are an answer
> contact for GCC ARM Embedded.
>

Revision history for this message
Jonathan Dumaresq (jdumaresq) said :
#4

Thanks Joey Ye, that solved my question.