I am trying to implement my version of __cxa_allocate_exception
and __cxa_free_exception
to avoid memory allocation on throw
.
So I implemented a memory pool which seems to work fine. But when testing with nested exceptions, the destructor of the exceptions was not called in all cases, and therefore __cxa_free_exception
was not called either, causing the memory pool to fill up over time.
See the following example code:
class MyException {
public:
MyException() {
std::cout << "MyException constructed." << std::endl;
}
~MyException() {
std::cout << "MyException destroyed." << std::endl;
}
};
void * __cxa_allocate_exception(size_t thrown_size)
{
const auto mem = malloc(thrown_size); //Not part of the example
std::cout << "allocate: " << mem << std::endl;
return mem;
}
void __cxa_free_exception(void *thrown_object)
{
std::cout << "free: " << thrown_object << std::endl;
free(thrown_object); //Not part of the example.
}
void non_rec() {
try {
throw MyException();
} catch(...) {
try {
throw MyException();
} catch(...) {
//...
}
}
}
int main() {
while(true) {
non_rec();
std::cout << "-----------" << std::endl;
}
}
The output of this program is:
allocate: 0x8cbc20
MyException constructed.
allocate: 0x8cc030
MyException constructed.
MyException destroyed.
free: 0x8cc030
MyException destroyed.
free: 0x8cbc20
-----------
allocate: 0x8cbc20
MyException constructed.
allocate: 0x8cc030
MyException constructed.
MyException destroyed.
free: 0x8cc030
-----------
allocate: 0x8cc030
MyException constructed.
allocate: 0x8cc440
MyException constructed.
MyException destroyed.
free: 0x8cc440
-----------
allocate: 0x8cc440
MyException constructed.
allocate: 0x8cc850
MyException constructed.
MyException destroyed.
free: 0x8cc850
It works correctly the first time. But after that the two exceptions are constructed and allocated in every loop iteration but only one is freed and destroyed.
I am using g++ 5.4.0 on Ubuntu 16.04.