PDA

View Full Version : Getting random double free or corruption in the same line of code!



qlands
16th September 2011, 07:31
Hi,

I am writing a program with QT and for some reason in a piece of code sometimes I get double free or corruption error but not in 100% of the cases, I would say I get it 3 times a week. The code that produce the error is the following:


void manureman::on_BitBtn3_clicked()
{
mnrmanothprods *otherprods = new mnrmanothprods(this,database,currentSystem); //Create the subWindow
moduleSubScreen m_dialogWindow; //Create the dialog for the subwindow
m_dialogWindow.loadSubScreen(otherprods); //Add the subwindow to the dialog... Basilly a MainLayout->addWidget
m_dialogWindow.setWindowTitle("Purchased products for manure management");
qDebug() << "Loading window";
m_dialogWindow.exec();
qDebug() << "After loading window";

qDebug() << "Exiting clicked";
}


mnrmanothprods is a QWidget descendant class that create internally 4 QWidget pointers all with mnrmanothprods as parent:


void mnrmanothprods::loadForm()
{
..
m_colModel = new fieldInColModel(this);
...
m_periodModel = new periodTableModel(this);
...
}

QAbstractItemDelegate* mnrmanothprods::constructCustomDelegator(QString, QString field)
{
if (field == "COLLECTED")
{
imageCheckDelegate *ckhdelegate = new imageCheckDelegate(this);
ckhdelegate->setCheckPixMap(QPixmap(":/images/ok.png"));
ckhdelegate->setUnCheckPixMap(QPixmap(":/images/nocheck.png"));
return ckhdelegate;
}
if (field == "ava")
{
imageCheckDelegate *ckhdelegate = new imageCheckDelegate(this);
ckhdelegate->setCheckPixMap(QPixmap(":/images/ok.png"));
ckhdelegate->setUnCheckPixMap(QPixmap(":/images/nocheck.png"));
ckhdelegate->addIgnoredColumn(0);
return ckhdelegate;
}
return 0;
}

The moduleSubScreen class only adds mnrmanothprods to a layout with:


void moduleSubScreen::loadSubScreen(impgenmaint *child)
{
m_child = child;
connect(m_child,SIGNAL(closeCalled()),this,SLOT(cl ose()));
ui->MainLayout->addWidget(child);
}

I put debug info in each destructor of my classes so I can see what is getting destroyed and the order. For example after I close the dialog I normallly get:


Debug: After loading window
Debug: Exiting clicked
Debug: Before destroy moduleSubScreen UI
Debug: After destroy moduleSubScreen UI
Debug: After m_child = 0
Debug: Before destroy mnrmanothprods UI
Debug: After destroy mnrmanothprods UI
Debug: Destroy: fieldInColModel
Debug: Destroy imageCheckDelegate
Debug: Destroy: periodTableModel
Debug: Destroy imageCheckDelegate

However when it crashes I get a partial destroy output:


Debug: After loading window
Debug: Exiting clicked
Debug: Before destroy moduleSubScreen UI
Debug: After destroy moduleSubScreen UI
Debug: After m_child = 0
Debug: Before destroy mnrmanothprods UI
Debug: After destroy mnrmanothprods UI
Debug: Destroy: fieldInColModel

Seem likes it fails after Destroy: fieldInColModel as it does not reach Destroy imageCheckDelegate

I ran it with valgrind --leak-check=full --log-file=./mleaks.log ./myprogram ... but I did not get any significant error besides 2 minor memory leaks in an unrelated section of code.... I though Valgrind was not able to trace it so I created a control problem in the same lines where I usually get the crash and Valgrind showed the controlled problem...

I tried to dump some info with this->dumpObjectInfo();
this->dumpObjectTree(); but even though my program is not on release I don't get any output from those dumps.

Any idea what else can I check?

Many thanks,
Carlos.

stampede
16th September 2011, 07:55
Build a debug version and use debugger, for example gdb - after the crash you can examine the call stack, check the value of each variable, even call methods on objects. Read more here: Debugging with gdb (http://www.delorie.com/gnu/docs/gdb/gdb_toc.html).
After you addWidget() to layout, be sure you dont try to delete it yourself, because The ownership of item is transferred to the layout, and it's the layout's responsibility to delete it.
Another thing, don't store pointers to QObjects, QWidgets in C-style ( by QObject * m_object, I assume the m_child is declared as QWidget * ), use QPointer, its much safer - it will be NULL-ed automatically when the objects is deleted, so the possibility of double-deletion is reduced.

qlands
16th September 2011, 08:20
QTCreator give me: &"warning: GDB: Failed to set controlling terminal: Invalid argument\n"

Is this fine or I may change something?

stampede
16th September 2011, 08:21
I don't know, can you run it from the command line (gdb "path/to/app.exe") ?