This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
IDE Netbeans 7.2 GDB: 7.3.50.20111026-cvs (cygwin-special) GCC: 4.5.3 (for cygwin) Assembly language and register values included as an attachment. Each section is separated by '========'. There are are five section; {1} operator new() source code, given below, {2} disassembly of code when a virtual base class destructor is used; (3) register values immediately before the failure; (4) disassembly of code when a virtual base class destructor is not used; (5) register values before the final call. I have a direct call to a concrete destructor (delete header) in a derived class. The code generated when the base class constructor is virtual is different then when the base class destructor is not virtual. The code generated fails when the base class destructor is virtual and works correctly when the base class destructor is not virtual. Without going into too much detail, I am reimplementing Weizenbaum's SLIP in C++. I use my own memory allocator. When memory is deleted it is put at the end of a list of available space. Allocation is from the front of the available space list. A sublist contains a pointer to the header of a list. During allocation when the allocated space refers to a sublist then the associated header contained in the sublist is deleted. The failure occurs in the inline code associated with 'delete header'. Assembly language 'call' statement used register eax which contains a zero, generating a fault on the call. It is quite possible that I haven't implemented or understood the care and feeding of virtual destructors. But a single line change causing this type of damage is baffling, and all the non-sublist deletes seem to work correctly. Sigh. If I haven't said things correctly or if the things said are muddled and lack reason, please correct me, don't punish me. The base class destructor is ~SlipCell() { } in the base class header file. The allocation code in the file SlipCell.cpp is; "operator new(size_t size); void * SlipCellBase::operator new(size_t size) { // Create a new SLIP cell SlipCellBase* link; do { if (avsl.top == NULL) { SlipCellBase::getAVSLSpace(); } link = (SlipCellBase*)avsl.top; avsl.top = avsl.top->rightLink; avsl.avail--; } while((long)link == TEMPORARY ); SlipOp* op = *(SlipOp**)link->getOperator(); if (op->isSublist()) { SlipHeader* header = *(SlipHeader**)getSublistHeader(*link); cout << link->dump() << endl << header->dump() << endl << flush; delete header; // <== point of failure } /* Zero Cell */ link->setOperator((void*)undefinedOP); link->rightLink = link->leftLink = (SlipCellBase*)UNDEFDATA; link->resetData(); return link; }; // void * SlipCellBase::operator new(size_t size) The inline delete method in the file SlipHeader.h is: ~SlipHeader() { deleteHeader(); }; // ~SlipHeader() void deleteHeader() { if (*(getHeadRefCnt()) <= 1) { addAVSLCells( this // pointer to first cell , getLeftLink()); // pointer to last cell } else *(getHeadRefCnt()) -= 1; }; // void deleteHeader()
Attachment:
disasembly.txt
Description: Text document
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |