I was getting "__dso_handled" not found, which was an operand to a call to __cxa_atexit.
When I set the flag as per above the dso_handled went away, exposing my real problem (unrelated to this issue- using a module from my PC codebase generated a default destructor which chained down to an explicit destructor which had a 'delete' in it which dragged in malloc.o but I have removed the heap from my microcontroller specific code so malloc.o is unhappy)
I did this just be adding the code above my main() function (with extern "C" wrappers, if main() is in a .cpp file)
One advantage to doing this is it gives you a debugging hook into the base C++ code which is registering these destructors. You don't have to fill-in the function __cxa_atexit() either, just write an empty function. After all, its unlikely that your embedded project will ever have to deal with calling global destructors (unless you are implementing a full-blown OS w/ applications).
The article also gives a good point that these registered destructors don't have to be from classes. You could register your own function which would then be called along with the class destructors, allowing C code to perform some clean-up task(s).
Comments
2 comments
I was getting "__dso_handled" not found, which was an operand to a call to __cxa_atexit.
When I set the flag as per above the dso_handled went away, exposing my real problem (unrelated to this issue- using a module from my PC codebase generated a default destructor which chained down to an explicit destructor which had a 'delete' in it which dragged in malloc.o but I have removed the heap from my microcontroller specific code so malloc.o is unhappy)
An alternative *may* be to provide your own support for static global constructors/destructors as per this Wiki Reference;
http://wiki.osdev.org/C_PlusPlus
I did this just be adding the code above my main() function (with extern "C" wrappers, if main() is in a .cpp file)
One advantage to doing this is it gives you a debugging hook into the base C++ code which is registering these destructors. You don't have to fill-in the function __cxa_atexit() either, just write an empty function. After all, its unlikely that your embedded project will ever have to deal with calling global destructors (unless you are implementing a full-blown OS w/ applications).
The article also gives a good point that these registered destructors don't have to be from classes. You could register your own function which would then be called along with the class destructors, allowing C code to perform some clean-up task(s).
eg.
// Mandatory global methods for C++ support
extern "C" void __cxa_pure_virtual()
{
// Do nothing or print an error message.
}
void *__dso_handle = 0;
extern "C" int __cxa_atexit(void (*destructor) (void *), void *arg, void *dso)
{
arg;
dso;
return 0;
}
extern "C" void __cxa_finalize(void *f)
{
f;
}
- Richard
Please sign in to leave a comment.