[Qt-interest] crash during QObject::connect

Thomas Ehrnhoefer thomas.ehrnhoefer at tasktop.com
Fri Sep 9 17:27:30 CEST 2011


Thanks Martin and Denny

Bit of context: I am working on (two) plugins for Qt Creator, so the
application we are talking about is Qt Creator. I am certain it's
initialized/started fully, as I manually open the sidebars after startup,
which can only happen if both plugins I work on are started.

As for the crash: I am fairly certain it crashes right at that
QObject::connect line. I have to admit that I yet have failed to setup the
whole project for debugging, so I am simply using logging statements. And
whatever comes after that QObject::connect, does not get logged anymore.

As for the signal emitting: I know exactly where in my code that signal
could be emitted, and it has to come from a successful REST call to a
service that currently is not online/running, thus there is no way that I
can imagine that that signal actually gets emitted.

As for pointers: I am using QPointer<MyModel>, so as far as I know, once I
delete the myModel instance the pointer pointed to, it should get reset to
0. In fact I had crashes before that I fixed using a QPointer.

That said, I am still very inexperienced with C++ and Qt.

What strikes me is that the first time that QObject::connect is reached
(it's in the constructor of my sidebar widget), it works. But as soon as I
open a second sidebar with the same widget, it crashes. Qt::UniqueConnection
shouldn't pose a problem, as the "this" (the sidebar widget) is different in
this case, but the controller is the same. The controller also is not
deleted (in fact, I never delete the controller, as it gets created on
plugin startup and shall live until QtCreator shuts down - it's very light
weight).


Here is some more code.
The "controller" in the case of the crash is of "TracTaskListController",
but could also be a "TasktopTaskListController", they both have a common
parent "TaskListController".

*-----tasklistcontroller.h-----*
#ifndef TASKLISTCONTROLLER_H
#define TASKLISTCONTROLLER_H
#include [.....]
class TASKTOP4QTCREATOR_EXPORT TaskListController : public QObject
{
    Q_OBJECT
public:
   TaskListController(QObject *parent = 0);

signals:
    void onModelChanged(TaskListRoot *taskListRoot);
    [.....]

public slots:
    virtual void root() = 0;
    [.....]
};
#endif // TASKLISTCONTROLLER_H

*-----tractasklistcontroller.h-----*
#ifndef TRACTASKLISTCONTROLLER_H
#define TRACTASKLISTCONTROLLER_H

#include [.....]
{
    Q_OBJECT
public:
    TracTaskListController();
    ~TracTaskListController();

signals:
    void onModelChanged(TaskListRoot *taskListRoot);
    [.....]

public slots:
    void root();
    [.....]

private slots:
    [.....]

private:
    void changeConfiguration(ITicketBackendConfiguration *conf);
    void setTicketModel(BaseTicketItemModel *model);
    void queryComplete(int done, int total);
    void restoreSettings();
    ProjectExplorer::Project *m_project;
    QSortFilterProxyModel *m_proxy;
    QUrl m_currentBackendUrl;
    TicketsSideBarPrivate *d;
};
#endif // TRACTASKLISTCONTROLLER_H


*-----tasklistsidebar.cpp-----*
[.....]
TaskListSideBar::TaskListSideBar(QWidget *parent) :
    QWidget(parent),
    _core(Core::ICore::instance()),
    ui(new Ui::TaskListSideBar),
    _imageProvider(new ImageProvider(this)),
    _context(new TaskListContext(this)),
    lastwidth(1),
    tasktopAvailable(TaskListUtil::isTasktopAvailable())
{
    //initialize tasklist controller
    taskListController = getTaskListController();
    ui->setupUi(this);
    qxtLog->debug(QString("Constructing Tasklist sidebar."));
    qRegisterMetaType<TaskListRoot>();
    qRegisterMetaType<TaskListRoot*>();
    qRegisterMetaType<TaskContainerHandle>();
    qRegisterMetaType<TaskContainerHandle*>();
    qRegisterMetaType<TaskContainer>();
    qRegisterMetaType<TaskContainer*>();
    qRegisterMetaType<Error*>();
    qRegisterMetaType<Repository*>();
    qRegisterMetaType<Person*>();
    qRegisterMetaType<TaskHandle>();
    qRegisterMetaType<TaskHandle*>();
    qRegisterMetaType<TaskImage*>();
    qxtLog->debug(QString("Connecting controller."));
    QObject::connect(taskListController,
SIGNAL(onModelChanged(TaskListRoot*)), this,
SLOT(onModelChanged(TaskListRoot*)),Qt::UniqueConnection);
    qxtLog->debug(QString("1"));
[.....]
TaskListController* TaskListSideBar::getTaskListController()
{
    if (TaskListUtil::isTasktopAvailable())
    {
        return new TasktopTaskListController(false);
    }
    return TaskListControllerRegistry::taskListController();
}

On Fri, Sep 9, 2011 at 8:06 AM, MARTIN Pierre <hickscorp at gmail.com> wrote:

> Hello again Thomas,
>
> > Thanks Martin, answers inline
> BTW my first name is Pierre, not Martin :)
>
> > I used to had a problem getting certain signals multiple times, so I made
> it a habit to use UniqueConnection, as I did not see any downside in it. In
> this case of the crash I tried to remove this already, which didn't make a
> difference
> Well, i think you shall provide us a bit more of your source code, or at
> least a very thin project showing the problem (i'm myself am unable to
> reproduce it with the same calls).
>
> > Yes, I always check validity of those pointers.
> How? If your model got deleted by it's parent earlier, you'll receive a
> non-null pointer pointing to a deleted memory location (Dangling pointer).
> There are no ways to check that (Unless you're using guarded pointers, but i
> doubt it seeing your code, correct me if i'm wrong).
>
> > But from what I understand the crash happening when I call connect wont
> have anything to do with an actual signal being triggered, or does it?
>
>
> i'm not sure i'm following anymore. When does it crashes exactly?
> Theorically, the "connect" statement cannot make your application "crash"
> because even if either of your signal / slot specification is wrong, you'll
> just get a debug message and nothing more.
>
> > In fact, I can say for certain that that signal gets not emitted while I
> test the app and it crashes.
> How can you know the signal isn't emitted? i believe you can tell if your
> slot gets called, but the emission of a signal is in your moc-generated
> code. Are you debugging it correctly to assert that it does not emits
> anything?
>
> Again, i think a bit more of your code would be sufficient to help you
> further :)
>
> _______________________________________________
> Qt-interest mailing list
> Qt-interest at qt.nokia.com
> http://lists.qt.nokia.com/mailman/listinfo/qt-interest
>



-- 
Thomas Ehrnhoefer
Software Developer, http://tasktop.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20110909/be48173d/attachment.html 


More information about the Qt-interest-old mailing list