PDA

View Full Version : Release version: QList Destructor



Taxi
20th April 2012, 15:08
Hi,

I'm trying to get a release version from my program called Tivoli. In debug mode, everything works fine (as ussual) but when working in the release mode, I recieve an error I can't figure out.

After setting up the release mode with debug information, I get the following call stack:

Tivoli.exe!QList<CPlot *>::~QList<CPlot *>() Line 716 + 0x13 bytes C++
00f69bf0()
kernel32.dll!76eb14dd()
Tivoli.exe!free(void * pBlock=0x00fc92f0) Line 110 C
Tivoli.exe!QModelIndex::`scalar deleting destructor'() + 0x21 bytes C++
Tivoli.exe!QList<QModelIndex>::node_destruct(QList<QModelIndex>::Node * from=0x00fc973c, QList<QModelIndex>::Node * to=0x00fc9780) Line 418 + 0x2f bytes C++
Tivoli.exe!QList<QModelIndex>::free(QListData::Data * data=0x00fc9728) Line 744 C++
Tivoli.exe!QList<QModelIndex>::~QList<QModelIndex>() Line 718 C++


The message in bold gives me my fatal error. Now the strange thing is that I do not call the destructor for QList<CPlot*> ..... I even cant call the destructor for this member because I need the data that's on it. Yet, in debug it works so where the hell does this come from?!

The program code is verry long so I can not put some code online here.

Qt version: 4.7.1

Spitfire
23rd April 2012, 12:30
I'm guessing you can't see it in debug mode because debug is more forgiving than release due to optimizations done in release mode.

Turn off code optimization in release mode and see if it works, if does, then enable optimization in debug and try to find the reason.

Or you're not rebuilding project correctly. Try clearing it and build it from a scratch.

d_stranz
23rd April 2012, 17:27
The message in bold gives me my fatal error. Now the strange thing is that I do not call the destructor for QList<CPlot*>

No, you aren't calling it. But the stack traceback seems to say that the QList<QModelIndex> destructor *is* calling it. I think that's a red herring.

The last function reference before the crash is very suspicious: 00f69bf0()

This is referencing the same area of memory occupied by your QList<QModelIndex>. That's telling me that by the time it gets to the apparent crash, the stack has already been corrupted and the crash is just the random section of memory that happened to be on the stack when it was corrupted. The program thinks that memory is code, and it has leaped off into wherever it thinks it is telling it to go (which looks like the middle of the QList<CPlot *> destructor).

So figure out what is going wrong in the QList<QModelIndex> destructor. Why do you have this list in the first place? If you read the docs on QModelIndex, you will see all sorts of warnings about the fact that they are not persistent, so storing them in collections is not recommended unless you take special measures (like retrieving persistent QModelIndex instances). So, my guess would be that your QList contains QModelIndex references that are completely invalid, and the QList destructor is happily trying to destroy something that doesn't exist.

Taxi
16th May 2012, 09:50
I think I have found out in the source where this is coming from.

I have a function called autoSelected with the following code:


void CBrowserDoc::autoSelectFiles()
{
//Select each entry in the file table view
m_pbrowserView->getFileTableView()->selectAll();

//If this browser document has no file selection model yet, create a raw data profile and a file selection model and activate it
if(m_selectionTableModels.isEmpty())
{
if(!m_rawDataProfile)
{
m_rawDataProfile = new CRawDataProfile(this);
}
CFileSelectionModel* fileSelectionModel = new CFileSelectionModel(this);
fileSelectionModel->setActive(true);
fileSelectionModel->setLinkedToBrowser(true);
m_rawDataProfile->addSelectionModel(fileSelectionModel);
}
emit toConsole(QString("The following files were automatically added to selection ").append(QString::number(getActiveSelection()->getId())),STANDARD);

//Get the indexes of the file table entries that are selected and then clear the selection
QModelIndexList indexes = m_pbrowserView->getSelectedInFileTable();
qSort(indexes);
m_pbrowserView->getFileTableView()->clearSelection();

CTableModel* tableModel = (CTableModel*)m_fileTableModel->sourceModel();

if(!getActiveSelection()) return;
CFileSelectionModel* activeSelection = getActiveSelection();
CFileTableEntry* temp;
int row = -1;

for(int i=0;i<indexes.size();i++)
{
QModelIndex index;
if(row != (index = indexes.value(i)).row())
{
row = index.row();
if (temp = tableModel->getTableEntry(index))
{
//if the entry passes the filter options add the entry to the active file selection model
//and add its coordinates to the raw data profile
if(tableModel->getFilterOptions()->passesFilter(temp))
{
emit toConsole(temp->getFileName(),STANDARD);
activeSelection->addEntry(temp);
int selectionModelIndex = m_rawDataProfile->getSelectionModelIndex(activeSelection);
CPlotData* plotData = m_rawDataProfile->getPlotData(selectionModelIndex);
double x = temp->getX();
double RsqAll = temp->getRsqAll();
plotData->addPoint(x,RsqAll);
}
}
}
}
} // If I put a breakpoint here running in release: It still works. After it fails.

So what i think is happing at the moment the program leaves this code, it will destroy the object/variables inside it. So I persume something will go wrong when it tries to delete QModelIndexList indexes.

The output window gives the following:

'Tivoli.exe': Loaded 'C:\Windows\winsxs\x86_microsoft.windows.gdiplus_6 595b64144ccf1df_1.1.7601.17825_none_72d273598668a0 6b\GdiPlus.dll'
First-chance exception at 0x7578b9bc in Tivoli.exe: Microsoft C++ exception: CExcept at memory location 0x0062c640..
Tivoli.exe has triggered a breakpoint


I have some more information from the call stack:

> msvcr90d.dll!operator delete(void * pUserData=0x24cccff0) Line 52 + 0x51 bytes C++
Tivoli.exe!QModelIndex::`scalar deleting destructor'() + 0x21 bytes C++
Tivoli.exe!QList<QModelIndex>::node_destruct(QList<QModelIndex>::Node * from=0x24c60e14, QList<QModelIndex>::Node * to=0x24c60fd8) Line 418 + 0x2f bytes C++
Tivoli.exe!QList<QModelIndex>::free(QListData::Data * data=0x24c60e00) Line 744 C++
Tivoli.exe!QList<QModelIndex>::~QList<QModelIndex>() Line 718 C++
Tivoli.exe!CBrowserDoc::autoSelectFiles() Line 487 + 0xf bytes C++
Tivoli.exe!CMainFrame::onAutoSelect() Line 2394 C++


So I believe, like d_stranz set, at this point, there all ready is a problem. Any clues? The destructor that has been called by the program happens after the entire function has been called...

Optimization turned off, same result. Clean solution and rebuilding: same result.. :)
From debug to release can be a pain the ass! :D

Spitfire
16th May 2012, 10:45
Is autoSelectFiles() a slot?

What's CMainFrame::onAutoSelect()? A slot?

What if you avoid selecting/deselecting entries in the view and instead take them from the model (you're getting every index anyway)?

Taxi
16th May 2012, 11:52
No it is not a slot. It is a plain function that will be called from the slot CMainFrame:onAutoSelect()...

Euhm ok, I cant try to take them from the model for this function. But besides this autoSelect (which will take all the cells in the table), I also have a manuel select function, which more or less contains the same source code. So here I will need to use the view to get to the right results...

It's difficult to rewrite this because I am not the creator of this part of the source code. I'm working on a project that will have multiple workyears. I'm the second workyear as here I am stuck with this problem caused from the programmer from the first workyear.

Spitfire
16th May 2012, 17:00
One thing I forgot to ask, what do you do to cause the app to crash?

Does it crash in both cases when you use auto and manual select? You're saying that the code is the same so I would expect so.

Taxi
16th May 2012, 17:06
It crashes when using this function. Well actually, both the functions do what they need to do, but when leaving the function, then the crash happens...
Also worth mentioning: debug version works proper, release gives this crash.

amleto
16th May 2012, 19:46
have you made sure you are linking the correct release version libraries.

that call stack doesnt make much sense going from QModleIndex dtor to QList<CPlot*> dtor

Taxi
16th May 2012, 20:04
Yes, I verified that I use the right libraries. A lot of people on the internet have the same problem but for them, it seems that they use the debug libraries in stead of the release running in the release mode.. But I verified that i use the right one....

amleto
16th May 2012, 22:18
please humour us and show us... pro file or studio project settings etc. :)

There is no way that a QModelIndex has a member QList<CPlot*>


You know that if you provided a compilable example, then other people could test as well... you could possibly make a smaller example that uses the suspect code path.

Taxi
16th May 2012, 22:54
I would like to give you a compilable example, but the project is quite large and, well, it is a project for a company for students for multiple years... With afterwards the intention to sell the product. If there is not emmidiatly a solution, I can give you (in private) a compilable example..

Here is the pro file (gerenated bu the Qt Visual Studio Plug-In):



# ----------------------------------------------------
# This file is generated by the Qt Visual Studio Add-in.
# ------------------------------------------------------

TEMPLATE = app
TARGET = Tivoli
DESTDIR = ./Release
QT += core gui webkit svg
CONFIG += debug
DEFINES += QT_LARGEFILE_SUPPORT QT_DLL QT_SVG_LIB
INCLUDEPATH += ./GeneratedFiles \
./GeneratedFiles/Release \
.
LIBS += -lqwt5 \
-lc:/Qt/qwt-5.2.1/lib/qwt5
DEPENDPATH += .
MOC_DIR += ./GeneratedFiles/release
OBJECTS_DIR += release
UI_DIR += ./GeneratedFiles
RCC_DIR += ./GeneratedFiles
include(C:/Users/Taxi/Desktop/Tivoli.pri)
win32:RC_FILE = Tivoli.rc

amleto
17th May 2012, 00:02
I'll leave it to someone who knows more about pro files to say if anything is off. I'm suspicious. if you upload the studio project file I can give a more confident opinion.

Taxi
17th May 2012, 11:06
Ok, here is the .vcproj file: http://www.mediafire.com/download.php?67fbyr5yxjnzug6
I had to upload it to MediaFire (qtcentre gives me errors while trying to upload here).

Any thoughts?

Spitfire
17th May 2012, 11:46
#9 CONFIG += debug // should this be release?

Taxi
17th May 2012, 13:07
#9 CONFIG += debug // should this be release?

True... Did not noticed it. This is wierd because in the Qt Project Settings from the Visual Add In, not one option says something about this CONFIG += DEBUG rule. I'll try to create my own .pro file!

Added after 24 minutes:

Still the same crash :)

Added after 48 minutes:

Ok guys.. I have installed the Qt libraries 4.8.1 for Windows VS2008 AND Qt Creator. Copied the source code, created the .pro file, build the Release version.... and IT WORKS!
So why in the hell does it work with Qt Creator, but not with VS2008 and Qt libraries v4.7.3...

With this in my mind: I set Qt Creator to use the qmake from the VS Studio, build the release and... yes, it works without a crash! After, I used VS2008 with Qt lib's version 4.8.1 but .... release crashed.

Ain't this verry, verry wierd? What am I missing? Settings wrong in the project settings from VS?

amleto
17th May 2012, 14:21
Ok, here is the .vcproj file: http://www.mediafire.com/download.php?67fbyr5yxjnzug6
I had to upload it to MediaFire (qtcentre gives me errors while trying to upload here).

Any thoughts?

in release you are ignoring msvcrt.lib, but it is not ignored in debug
(linker->input)

code generation is not equivalent
debug: mt debug dll
release: mt

you have different library includes for debug and release - notably qwt is missing from release. this could be a problem if you have a debug lib path on your PATH env var.

Taxi
17th May 2012, 14:48
Correct. I started with the entire same settings but changed a couple of things for testing. Also the qwt that you saw was missing, was defined in the code at the appropriate places.

But if you look at my previous post, the proble must be lying here somewhere...

Spitfire
17th May 2012, 15:59
Look at the compiler output from qt creator and compare it to msvs output and figure out what you've messed up :)

amleto
17th May 2012, 17:08
in Qt settings in studio you can specify which Qt version to use. make sure it is the same one that QTDIR variable points to?

Taxi
17th May 2012, 17:39
in Qt settings in studio you can specify which Qt version to use. make sure it is the same one that QTDIR variable points to?

Jip, tried that. Also removed the QTDIR variable and replaced it with the links itself to the right Qt version + folder. :)

amleto
17th May 2012, 18:39
Take the pro file that *does* work in release when built by Creator, and use MSVS + Qt Addin to make a vcproj from it. Run it and... what happens? Make sure to to a full clean before building.

Taxi
18th May 2012, 10:10
Release version... Works!!!! :-)

I created an entire new project and now it works fine!

Thank you guys for your help!!