PDA

View Full Version : Random crashes with dynamic tabs



scuba
12th September 2015, 19:07
Hi,

I am working on an application, where tabs are opened and closed dynamically - just like in webbrowsers. The problem is that, I keep experiencing random but regular crashes when closing a tab. I made a very short piece of code to demonstrate the problem:


#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QtWidgets>
#include <mytab.h>

class MainWindow : public QMainWindow
{
Q_OBJECT

QWidget *central;

QListWidget *listWidget;

QTabWidget *tabWidget;

QGridLayout *layout;

bool deleteBusy = false;

public:
MainWindow(QWidget *parent = 0);
~MainWindow();

public slots:

void newTab();
void closeTab(int);

};

#endif // MAINWINDOW_H




#ifndef MYTAB_H
#define MYTAB_H

#include <QWidget>
#include <QtWidgets>


class myTab : public QWidget
{
Q_OBJECT
public:
explicit myTab(QWidget *parent = 0);


QTableWidget *tableWidget;
QTableWidget *tableWidget2;
QGridLayout *layout;

signals:

public slots:

};

#endif // MYTAB_H


#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();

return a.exec();
}




#include "mainwindow.h"


MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{

central = new QWidget(this);
setCentralWidget(central);

listWidget = new QListWidget();

for (int a = 0; a < 14 ; a++) // Just to make the listWidget easier to click
{
new QListWidgetItem(tr("Click here"), listWidget);
}


tabWidget = new QTabWidget();

layout = new QGridLayout(central);
layout->addWidget(listWidget, 0, 0);
layout->addWidget(tabWidget, 1, 0);

tabWidget->addTab(new myTab, tr("Tab"));

QObject::connect(listWidget, SIGNAL(clicked(QModelIndex)), this, SLOT(newTab()) );
QObject::connect(tabWidget, SIGNAL(tabBarClicked(int)), this, SLOT(closeTab(int)) );


}

MainWindow::~MainWindow()
{

}

void MainWindow::newTab()
{

tabWidget->addTab(new myTab, tr("Tab"));

}

void MainWindow::closeTab(int)
{

if (deleteBusy == true)
QMessageBox::information(0, "Information", "Another tab is closing!" );
deleteBusy = true;

if (tabWidget->count() < 1)
QMessageBox::information(0, "Information", "No tabs!" );

QWidget *tab = tabWidget->currentWidget();

tabWidget->removeTab(tabWidget->currentIndex());

if (tab != NULL)
{
delete tab;
tab = NULL;
}
else
{
QMessageBox::information(0, "Information", "Tab is null!" );
}


deleteBusy = false;

}




#include "mytab.h"

myTab::myTab(QWidget *parent) :
QWidget(parent)
{

tableWidget = new QTableWidget();
tableWidget2 = new QTableWidget();

layout = new QGridLayout(this);
layout->addWidget(tableWidget, 0, 0);
layout->addWidget(tableWidget2, 0, 1);

for (int a = 0; a<1000; a++) // Adding some content to the tab...
{
tableWidget->insertRow(0);
tableWidget2->insertRow(0);
}


}


If I VERY quickly open 3-4 tabs and close them, and then reopen, etc, the program will sometimes crash (about 1 case from 4). In my actual application the problem is more evident. Any ideas why this is happening? Suspecting some kind on heap/stack problem, but as far as I understand it, I can't point the error.

d_stranz
12th September 2015, 19:37
Try using "tab->deleteLater()" instead of "delete tab". This defers actual deletion until the next time the event loop runs, which allows Qt to remove the widget and clean up.

Setting "tab = NULL" in the next line really does nothing except to set the value of your local variable that contains the pointer to NULL. It is no different from having an "int" local variable and setting its value to something. As soon as the method exits, the stack is cleaned up and all those local variables go away.

ChrisW67
12th September 2015, 21:13
The locking mechanism in your closeTab() routine is unnecessary in a single threaded program. The program cannot re-enter this routine until it processes another click event, and that cannot happen before it leaves this slot and reaches the event loop.

Run your program in a debugger, make if fail and then walk back through the stack backtrace to find where in your code it fails from.

scuba
13th September 2015, 07:10
Try using "tab->deleteLater()" instead of "delete tab".

Thanks, but I forgot to mention I have already tried it. The result is the same.

scuba
13th September 2015, 11:42
Run your program in a debugger, make if fail and then walk back through the stack backtrace to find where in your code it fails from.

Call stack trace points to QGestureManager::filterEvent (grayed out). On an other attempt it gives QCoreApplication.


Starting debugger "LldbEngine" for ABI "x86-macos-generic-mach_o-64bit"...
dStart parameters: 'TabCrash' mode: 1
dABI: x86-macos-generic-mach_o-64bit
dLanguages: c++

cut --- cut --- cut

dLldb stdout: registers=[{name="rax",value="0x000000010123ae10",type="unsigned long"},{name="rbx",value="0x000000000000007c",type="unsigned long"},{name="rcx",value="0x0000000100ff3708",type="unsigned long"},{name="rdx",value="0x00007fff5fbfe278",type="unsigned long"},{name="rdi",value="0x0000000101338f00",type="unsigned long"},{name="rsi",value="0x0000000101239700",type="unsigned long"},{name="rbp",value="0x00007fff5fbfdf70",type="unsigned long"},{name="rsp",value="0x00007fff5fbfdf20",type="unsigned long"},{name="r8",value="0x00000001091cf0d0",type="unsigned long"},{name="r9",value="0x000000000000012c",type="unsigned long"},{name="r10",value="0x00000000000003de",type="unsigned long"},{name="r11",value="0xfffffffffffffff8",type="unsigned long"},{name="r12",value="0x0000000100e4faa8",type="unsigned long"},{name="r13",value="0x0000000100e4faa8",type="unsigned long"},{name="r14",value="0x0000000101239700",type="unsigned long"},{name="r15",value="0x00000001091dd928",type="unsigned long"},{name="rip",value="0x0000000100081531",type="unsigned long"},{name="rflags",value="0x0000000000010202",type="unsigned long"},{name="cs",value="0x000000000000002b",type="unsigned long"},{name="fs",value="0x0000000000000000",type="unsigned long"},{name="gs",value="0x0000000000000000",type="unsigned long"},{name="eax",value="0x0123ae10",type="unsigned int"},{name="ebx",value="0x0000007c",type="unsigned int"},{name="ecx",value="0x00ff3708",type="unsigned int"},{name="edx",value="0x5fbfe278",type="unsigned int"},{name="edi",value="0x01338f00",type="unsigned int"},{name="esi",value="0x01239700",type="unsigned int"},{name="ebp",value="0x5fbfdf70",type="unsigned int"},{name="esp",value="0x5fbfdf20",type="unsigned int"},{name="r8d",value="0x091cf0d0",type="unsigned int"},{name="r9d",value="0x0000012c",type="unsigned int"},{name="r10d",value="0x000003de",type="unsigned int"},{name="r11d",value="0xfffffff8",type="unsigned int"},{name="r12d",value="0x00e4faa8",type="unsigned int"},{name="r13d",value="0x00e4faa8",type="unsigned int"},{name="r14d",value="0x01239700",type="unsigned int"},{name="r15d",value="0x091dd928",type="unsigned int"},{name="ax",value="0xae10",type="unsigned short"},{name="bx",value="0x007c",type="unsigned short"},{name="cx",value="0x3708",type="unsigned short"},{name="dx",value="0xe278",type="unsigned short"},{name="di",value="0x8f00",type="unsigned short"},{name="si",value="0x9700",type="unsigned short"},{name="bp",value="0xdf70",type="unsigned short"},{name="sp",value="0xdf20",type="unsigned short"},{name="r8w",value="0xf0d0",type="unsigned short"},{name="r9w",value="0x012c",type="unsigned short"},{name="r10w",value="0x03de",type="unsigned short"},{name="r11w",value="0xfff8",type="unsigned short"},{name="r12w",value="0xfaa8",type="unsigned short"},{name="r13w",value="0xfaa8",type="unsigned short"},{name="r14w",value="0x9700",type="unsigned short"},{name="r15w",value="0xd928",type="unsigned short"},{name="ah",value="0xae",type="unsigned char"},{name="bh",value="0x00",type="unsigned char"},{name="ch",value="0x37",type="unsigned char"},{name="dh",value="0xe2",type="unsigned char"},{name="al",value="0x10",type="unsigned char"},{name="bl",value="0x7c",type="unsigned char"},{name="cl",value="0x08",type="unsigned char"},{name="dl",value="0x78",type="unsigned char"},{name="dil",value="0x00",type="unsigned char"},{name="sil",value="0x00",type="unsigned char"},{name="bpl",value="0x70",type="unsigned char"},{name="spl",value="0x20",type="unsigned char"},{name="r8l",value="0xd0",type="unsigned char"},{name="r9l",value="0x2c",type="unsigned char"},{name="r10l",value="0xde",type="unsigned char"},{name="r11l",value="0xf8",type="unsigned char"},{name="r12l",value="0xa8",type="unsigned char"},{name="r13l",value="0xa8",type="unsigned char"},{name="r14l",value="0x00",type="unsigned char"},{name="r15l",value="0x28",type="unsigned char"},{name="fctrl",value="0x037f",type="unsigned short"},{name="fstat",value="0x0220",type="unsigned short"},{name="ftag",value="0x00",type="unsigned char"},{name="fop",value="0x0000",type="unsigned short"},{name="fioff",value="0x8d88e3b3",type="unsigned int"},{name="fiseg",value="0x0000",type="unsigned short"},{name="fooff",value="0x5fbff0e0",type="unsigned int"},{name="foseg",value="0x0000",type="unsigned short"},{name="mxcsr",value="0x00001fa1",type="unsigned int"},{name="mxcsrmask",value="0x0000ffff",type="unsigned int"},{name="stmm0",value="None",type="unsigned char __attribute__((ext_vector_type(10)))"},{name="stmm1",value="None",type="unsigned char __attribute__((ext_vector_type(10)))"},{name="stmm2",value="None",type="unsigned char __attribute__((ext_vector_type(10)))"},{name="stmm3",value="None",type="unsigned char __attribute__((ext_vector_type(10)))"},{name="stmm4",value="None",type="unsigned char __attribute__((ext_vector_type(10)))"},{name="stmm5",value="None",type="unsigned char __attribute__((ext_vector_type(10)))"},{name="stmm6",value="None",type="unsigned char __attribute__((ext_vector_type(10)))"},{name="stmm7",value="None",type="unsigned char __attribute__((ext_vector_type(10)))"},{name="ymm0",value="None",type="unsigned char __attribute__((ext_vector_type(32)))"},{name="ymm1",value="None",type="unsigned char __attribute__((ext_vector_type(32)))"},{name="ymm2",value="None",type="unsigned char __attribute__((ext_vector_type(32)))"},{name="ymm3",value="None",type="unsigned char __attribute__((ext_vector_type(32)))"},{name="ymm4",value="None",type="unsigned char __attribute__((ext_vector_type(32)))"},{name="ymm5",value="None",type="unsigned char __attribute__((ext_vector_type(32)))"},{name="ymm6",value="None",type="unsigned char __attribute__((ext_vector_type(32)))"},{name="ymm7",value="None",type="unsigned char __attribute__((ext_vector_type(32)))"},{name="ymm8",value="None",type="unsigned char __attribute__((ext_vector_type(32)))"},{name="ymm9",value="None",type="unsigned char __attribute__((ext_vector_type(32)))"},{name="ymm10",value="None",type="unsigned char __attribute__((ext_vector_type(32)))"},{name="ymm11",value="None",type="unsigned char __attribute__((ext_vector_type(32)))"},{name="ymm12",value="None",type="unsigned char __attribute__((ext_vector_type(32)))"},{name="ymm13",value="None",type="unsigned char __attribute__((ext_vector_type(32)))"},{name="ymm14",value="None",type="unsigned char __attribute__((ext_vector_type(32)))"},{name="ymm15",value="None",type="unsigned char __attribute__((ext_vector_type(32)))"},{name="xmm0",value="None",type="unsigned char __attribute__((ext_vector_type(16)))"},{name="xmm1",value="None",type="unsigned char __attribute__((ext_vector_type(16)))"},{name="xmm2",value="None",type="unsigned char __attribute__((ext_vector_type(16)))"},{name="xmm3",value="None",type="unsigned char __attribute__((ext_vector_type(16)))"},{name="xmm4",value="None",type="unsigned char __attribute__((ext_vector_type(16)))"},{name="xmm5",value="None",type="unsigned char __attribute__((ext_vector_type(16)))"},{name="xmm6",value="None",type="unsigned char __attribute__((ext_vector_type(16)))"},{name="xmm7",value="None",type="unsigned char __attribute__((ext_vector_type(16)))"},{name="xmm8",value="None",type="unsigned char __attribute__((ext_vector_type(16)))"},{name="xmm9",value="None",type="unsigned char __attribute__((ext_vector_type(16)))"},{name="xmm10",value="None",type="unsigned char __attribute__((ext_vector_type(16)))"},{name="xmm11",value="None",type="unsigned char __attribute__((ext_vector_type(16)))"},{name="xmm12",value="None",type="unsigned char __attribute__((ext_vector_type(16)))"},{name="xmm13",value="None",type="unsigned char __attribute__((ext_vector_type(16)))"},{name="xmm14",value="None",type="unsigned char __attribute__((ext_vector_type(16)))"},{name="xmm15",value="None",type="unsigned char __attribute__((ext_vector_type(16)))"},{name="trapno",value="0x0000000e",type="unsigned int"},{name="err",value="0x00000004",type="unsigned int"},{name="faultvaddr",value="0x0000000000000084",type="unsigned long"},]@

Now I'm wondering, if the crashes happen because I am accidentally making some gesture with MacBooks trackpad when doing the fast clicks. I tried before to crash the program with a opentab-closetab -loop, but that never succeeded. Maybe it's a problem with gestures?

EDIT: This might be related: https://bugreports.qt.io/browse/QTBUG-46264

scuba
21st September 2015, 19:24
Upgrading to Qt 5.5.0 solved the issue.