Please note that I do not want to solve any problems with my question - I thought about the likelihood of what happened, and therefore I wondered:
What exactly happens if you delete the object and use gcc as a compiler?
Last week, I investigated a crash when a race condition caused the object to be deleted twice.
The accident occurred when the virtual destructor of the object was called, because the pointer to the virtual function table was already overwritten.
Is a virtual function pointer overwritten by the first delete?
If this is not the case, is this the second safe safe, unless a new memory allocation is allocated?
I am wondering why the problem that I had was not recognized before, and the only exception is that either the virtual function table is overwritten immediately during the first deletion, or the second deletion is not reset.
(The first means that an accident always occurs in the same place if a "race" occurs - the second, which usually does not happen when a race occurs - and only if the third thread overwrites the delete object, in the meantime, a problem arises.)
Edit / Update:
I ran a test, the following code will fail using segfault (gcc 4.4, i686 and amd64):
class M { private: int* ptr; public: M() { ptr = new int[1]; } virtual ~M() {delete ptr;} }; int main(int argc, char** argv) { M* ptr = new M(); delete ptr; delete ptr; }
If I remove the "virtual" from dtor, the program will be interrupted by glibc because it detects a double release. In a "virtual" failure, an indirect function is called when the destructor is called, because the pointer to the virtual function table is invalid.
On both amd64 and i686, the pointer points to a valid memory area (heap), but the value is invalid there (counter? Is it very low, for example, 0x11 or 0x21), so the "call" (or "jmp" when the compiler performed the optimization of return) goes to invalid area.
SIGSEGV program signal,
Segmentation error. 0x0000000000000021
in ?? () (gdb)
# 0 0x0000000000000021 in ?? ()
# 1 0x000000000040083e in main ()
Thus, with the above conditions, the pointer to the virtual function table is ALWAYS overwritten by the first deletion, so the next deletion will go to nirvana if the class has a virtual destructor.