Linux/ALPHA bug: Destructor called twice for the same object instance.

Rolf Fokkens rolf@flits102-126.flits.rug.nl
Sun Aug 9 23:15:00 GMT 1998


The appended piece of code illustrates a bug in egcs1.0.2 for alpha,
which is not present in egcs 1.0.2 for i386.
On alpha a destructor is sometimes called twice for the same object
instance.

This bug makes NetStreamer (a software package I'm working on) crash on
Linux-Alpha.

Example code:

//
// This code demonstrates a bug in egcs 1.0.2. The Bug results in twice
// the destruction of the same object.
//
// This Bug is only present in egcs for Alpha, not in egcs for i386!!!
//
// Rolf Fokkens
// 10 Aug 1998
//
// This code declares the following class hierarchy.
//
//    ClassA
//     |  |
// CassB  ClassC
//     |  |
//    ClassD
//
//    ClassP
//
// Both class ClassB and class ClassC are derived from ClassA. ClassD is

// multiple inherited from both ClassB and ClassC. All inheritance is
// virtual public.
//
// ClassP is not part of the hierarchy, it's passed as a parameter to
// demonstrate the multiple destruction of the same object. It writes
tracing
// output on both constructor en destructor calls. It has two
constructors:
// a plain constructor and a copy-constructor, which both generate their
own
// tracing output.
// Every instance of ClassP gets an Id, which is auto-generated: every
next
// instance of ClassP gets the next number, starting with 0.
//
// ClassA has a virtual member function Process, which is inherited by
// all descendents from ClassA.
// ClassD routes Process to ClassC, which is needed 'cause ClassD
inherits
// Process from both ClassB and ClassC.
//
// ClassD also has a member function InitBug which calls Process while
// passing on an object of type ClassP.
//
// This program generates the folowing output on:
//
// RH51 for Alpha with egcs 1.0.2:
//
//    C1:0
//    C2:1
//    C2:2
//    D :2
//    D :1
//    D :1
//    D :0
//
//    Which means that object 1 is destroyed twice!!
//
// RH51 for i386 with egcs 1.0.2:
//
//    C1:0
//    C2:1
//    C2:2
//    D :2
//    D :1
//    D :0
//
//    Which is the correct behaviour
//

#include <iostream.h>
#include "EzString.h"

class ClassP {
private:
    static int IdCount;
    int Id;
public:
    ~ClassP (void);
    ClassP (void);
    ClassP (ClassP &Orig);
};

int ClassP::IdCount = 0;

ClassP::~ClassP (void)
{
    cout << "D :" << Id << endl;
};

ClassP::ClassP (void)
{
    Id = IdCount++;

    cout << "C1:" << Id << endl;
};

ClassP::ClassP (ClassP &Orig)
{
    Id = IdCount++;

    cout << "C2:" << Id << endl;
};

class ClassA  {
public:
    virtual void Process (ClassP Text);
};

class ClassB : virtual public ClassA {
};

class ClassC : virtual public ClassA {
};

class ClassD : virtual public ClassB, virtual public ClassC {
public:
    virtual void Process (ClassP Text) { ClassC::Process (Text); };
    void InitBug ();
};

void ClassA::Process (ClassP Text)
{
};

void ClassD::InitBug ()
{
    ClassP Xxx;

    Process (Xxx);
};

int main (void)
{
    ClassD VarD;

    VarD.InitBug ();

    return 0;
};




More information about the Gcc-bugs mailing list