-fno-use-cxa-atexit
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
GNU Arm Embedded Toolchain |
Invalid
|
Undecided
|
Liviu Ionescu |
Bug Description
The GCC manual states:
-fuse-cxa-atexit
Register destructors for objects with static storage duration with the __cxa_atexit function rather than the atexit function.
The actual behaviour is correct, with the small notice that, in the ARM compiler case, when -fuse-cxa-atexit is requested, not __cxa_atexit but _aeabi_atexit() is used for all static destructors, either global variables or static variables inside a function.
When -fno-use-cxa-atexit is requested, the ARM compiler behaves somehow strangely and unexpected, for global variables generates code for the .fini section (which is good) but for static variables it calls atexit().
For example something like:
---
class C; // ...
C c1;
void f(void)
{
static C c2;
// ...
}
---
generates atexit only for c2:
---
void f(void)
{
800172c: b508 push {r3, lr}
static C c;
800172e: 4b06 ldr r3, [pc, #24] ; (8001748 <f()+0x1c>)
8001730: 681b ldr r3, [r3, #0]
8001732: f013 0f01 tst.w r3, #1
8001736: d105 bne.n 8001744 <f()+0x18>
8001738: 2201 movs r2, #1
800173a: 4b03 ldr r3, [pc, #12] ; (8001748 <f()+0x1c>)
800173c: 601a str r2, [r3, #0]
800173e: 4803 ldr r0, [pc, #12] ; (800174c <f()+0x20>)
8001740: f000 f84a bl 80017d8 <atexit>
8001744: bd08 pop {r3, pc}
8001746: bf00 nop
8001748: 20000224 .word 0x20000224
800174c: 0800169d .word 0x0800169d
---
The problem is that on tight embedded systems, atexit() might not be available, since normally it requires dynamically allocated array of pointers, and the use of malloc() sometimes is prohibited.
My expectation was that once I enable -fno-use-
Could you check what should be the correct behaviour?
Thank you,
Liviu
Changed in gcc-arm-embedded: | |
status: | New → Invalid |
assignee: | nobody → Liviu Ionescu (ilg) |
another problem with the approach of having part of the destructors executed by .fini and part by atexit() is that the expected order ("the reverse order of the constructors") cannot be guaranteed, the exit() procedure usually executes the atexit() array and then the .fini array().