Results 1 to 9 of 9

Thread: segfault with QMessageBox in QAbstractItemModel::hasChildren

  1. #1
    Join Date
    Sep 2010
    Posts
    8
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default segfault with QMessageBox in QAbstractItemModel::hasChildren

    It appears if I display something inside the implementation of hasChildren on a QAbstractItemModel I get a segfault.
    This is easily reproducible with the simpletreemodel example included in the source tarball.
    Simply add the following method to treemodel.cpp (and corresponding method to the header as well).
    You can click through the first round of messages. After that when you mouse over one of the tree items it will give you another prompt. After clicking it you'll segfault.

    Qt Code:
    1. #include <string>
    2. #include <sstream>
    3.  
    4. // ...
    5.  
    6. bool TreeModel::hasChildren(const QModelIndex &parent) const
    7. {
    8. std::ostringstream oss;
    9. if (!parent.isValid()) {
    10. oss << "hasChildren root" << std::endl;
    11. } else {
    12. oss << "hasChildren (" << parent.row() << "," << parent.column() << ")" << std::endl;
    13. }
    14. oss << QAbstractItemModel::hasChildren(parent) << std::endl;
    15.  
    16. QMessageBox::information((QWidget*)QAbstractItemModel::parent(), "TITLE", QString::fromStdString(oss.str()));
    17. return QAbstractItemModel::hasChildren(parent);
    18.  
    19. }
    To copy to clipboard, switch view to plain text mode 

    Since I'm sure it will be asked, let me explain why I'm doing this.
    I have an application which connects to a server but can also work off-line.
    While connected a user can drag an item from the server to their local cache.
    This does a shallow copy.
    If the user then closes and re-opens the application they will see their local copy of that top level item and 1 level of items under it.
    Expanding nodes any further than what the client has cached locally will cause a login dialog to appear to log into the server.

    What should I do?
    I'm open to suggestions.

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: segfault with QMessageBox in QAbstractItemModel::hasChildren

    The model index might have become invalid.

    Basically model indexes are only considere valid as long as the model doesn't change or something else has happend, e.g. events have been processed.
    The latter happens inside the message box.

    You could try storing the index in a QPersitantModelIndex before you go into the nested event loop.

    Ideally of course the model wouldn't use a message box with a nested event loop at all.

    Cheers,
    _

  3. #3
    Join Date
    Sep 2010
    Posts
    8
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: segfault with QMessageBox in QAbstractItemModel::hasChildren

    Thanks for the reply.

    I don't think a QPersistentModelIndex helps here.
    There is only a single line after the QMessageBox where I call...
    Qt Code:
    1. return QAbstractItemModel::hasChildren(parent);
    To copy to clipboard, switch view to plain text mode 
    If I were to store the result of this call as a boolean variable at the top of the method and just return it, then I'm not using the index at all after the QMessageBox and it still segfaults.

    Qt Code:
    1. bool TreeModel::hasChildren(const QModelIndex &parent) const
    2. {
    3. bool ret = QAbstractItemModel::hasChildren(parent);
    4. std::ostringstream oss;
    5. if (!parent.isValid()) {
    6. oss << "hasChildren root" << std::endl;
    7. } else {
    8. oss << "hasChildren (" << parent.row() << "," << parent.column() << ")" << std::endl;
    9. }
    10. oss << QAbstractItemModel::hasChildren(parent) << std::endl;
    11.  
    12. QMessageBox::information((QWidget*)QAbstractItemModel::parent(), "TITLE", QString::fromStdString(oss.str()));
    13. return ret;
    14. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by eric.frederich; 27th October 2015 at 18:10. Reason: added code

  4. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: segfault with QMessageBox in QAbstractItemModel::hasChildren

    Hmm, what does the backtrace say where it crashes?

    Is the parent really a QWidget? A C style cast is always a chance for trouble.

    Cheers,
    _

  5. #5
    Join Date
    Sep 2010
    Posts
    8
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: segfault with QMessageBox in QAbstractItemModel::hasChildren

    Here is the backtace I got from Qt Creator.
    I changed both the index and parent methods to return QPersistentModelIndex and I still get the error.
    Again, this is just a simple example from the source tar files. Should be easy to re-produce.
    I changed the c style cast to a qobject_cast<QWidget*>() call and still segfaults.

    0 QTransform :: type() const 0x7ffff7472030
    1 QRasterPaintEngine :: drawImage(QPointF const&, QImage const&) 0x7ffff748e288
    2 QRasterPaintEngine :: drawPixmap(QPointF const&, QPixmap const&) 0x7ffff7495efe
    3 QPainter :: drawPixmap(QPointF const&, QPixmap const&) 0x7ffff741cafb
    4 QGtkPainter :: paintFlatBox(_GtkWidget *, const char *, QRect const&, GtkStateType, GtkShadowType, _GtkStyle *, QString const&) 0x7ffff7657183
    5 QGtkStyle :: drawPrimitive(QStyle :: PrimitiveElement, QStyleOption const *, QPainter *, QWidget const *) const 0x7ffff7643e96
    6 QTreeView :: drawRow(QPainter *, QStyleOptionViewItem const&, QModelIndex const&) const 0x7ffff782302c
    7 QTreeView :: drawTree(QPainter *, QRegion const&) const 0x7ffff78268eb
    8 QTreeView :: paintEvent(QPaintEvent *) 0x7ffff782a303
    9 QWidget :: event(QEvent *) 0x7ffff731a506
    10 QFrame :: event(QEvent *) 0x7ffff76d0fae
    11 QAbstractItemView :: viewportEvent(QEvent *) 0x7ffff77ed093
    12 QTreeView :: viewportEvent(QEvent *) 0x7ffff782e210
    13 QCoreApplicationPrivate :: sendThroughObjectEventFilters(QObject *, QEvent *) 0x7ffff6d982d6
    14 QApplicationPrivate :: notify_helper(QObject *, QEvent *) 0x7ffff72c7b9c
    15 QApplication :: notify(QObject *, QEvent *) 0x7ffff72ce555
    16 QCoreApplication :: notifyInternal(QObject *, QEvent *) 0x7ffff6d9816d
    17 QWidgetPrivate :: drawWidget(QPaintDevice *, QRegion const&, QPoint const&, int, QPainter *, QWidgetBackingStore *) 0x7ffff7314869
    18 QWidgetBackingStore :: sync() 0x7ffff74df5ca
    19 QWidgetPrivate :: syncBackingStore() 0x7ffff73091d0
    20 QWidget :: event(QEvent *) 0x7ffff731a296
    21 QFrame :: event(QEvent *) 0x7ffff76d0fae
    22 QAbstractScrollArea :: event(QEvent *) 0x7ffff7754333
    23 QAbstractItemView :: event(QEvent *) 0x7ffff77ecd2b
    24 QApplicationPrivate :: notify_helper(QObject *, QEvent *) 0x7ffff72c7bbc
    25 QApplication :: notify(QObject *, QEvent *) 0x7ffff72ce555
    26 QCoreApplication :: notifyInternal(QObject *, QEvent *) 0x7ffff6d9816d
    27 QCoreApplicationPrivate :: sendPostedEvents(QObject *, int, QThreadData *) 0x7ffff6d9b255
    28 postEventSourceDispatch(_GSource *, int ( *)(void *), void *) 0x7ffff6dc73f3
    29 g_main_context_dispatch 0x7ffff592c9ba
    30 g_main_context_iterate.isra 0x7ffff592cd08
    31 g_main_context_iteration 0x7ffff592cdbc
    32 QEventDispatcherGlib :: processEvents(QFlags<QEventLoop :: ProcessEventsFlag>) 0x7ffff6dc6c75
    33 QGuiEventDispatcherGlib :: processEvents(QFlags<QEventLoop :: ProcessEventsFlag>) 0x7ffff7369ab6
    34 QEventLoop :: processEvents(QFlags<QEventLoop :: ProcessEventsFlag>) 0x7ffff6d96caf
    35 QEventLoop :: exec(QFlags<QEventLoop :: ProcessEventsFlag>) 0x7ffff6d96ffd
    36 QDialog :: exec() 0x7ffff778f8dc
    37 showNewMessageBox(QWidget *, QMessageBox :: Icon, QString const&, QString const&, QFlags<QMessageBox :: StandardButton>, QMessageBox :: StandardButton) 0x7ffff77b0030
    38 QMessageBox :: information(QWidget *, QString const&, QString const&, QFlags<QMessageBox :: StandardButton>, QMessageBox :: StandardButton) 0x7ffff77b011f
    39 TreeModel :: hasChildren treemodel.cpp 235 0x404cad
    40 QTreeViewPrivate :: hasVisibleChildren(QModelIndex const&) const 0x7ffff78260e2
    41 QTreeViewPrivate :: itemDecorationRect(QModelIndex const&) const 0x7ffff78261e4
    42 QTreeViewPrivate :: itemDecorationAt(QPoint const&) const 0x7ffff7826474
    43 QTreeView :: viewportEvent(QEvent *) 0x7ffff782e254
    44 QCoreApplicationPrivate :: sendThroughObjectEventFilters(QObject *, QEvent *) 0x7ffff6d982d6
    45 QApplicationPrivate :: notify_helper(QObject *, QEvent *) 0x7ffff72c7b9c
    46 QApplication :: notify(QObject *, QEvent *) 0x7ffff72ce8a3
    47 QCoreApplication :: notifyInternal(QObject *, QEvent *) 0x7ffff6d9816d
    48 QApplicationPrivate :: sendMouseEvent(QWidget *, QMouseEvent *, QWidget *, QWidget *, QWidget * *, QPointer<QWidget>&, bool) 0x7ffff72cddd7
    49 QETWidget :: translateMouseEvent(_XEvent const *) 0x7ffff73434bb
    50 QApplication :: x11ProcessEvent(_XEvent *) 0x7ffff7341f2c
    51 x11EventSourceDispatch(_GSource *, int ( *)(void *), void *) 0x7ffff7369934
    52 g_main_context_dispatch 0x7ffff592c9ba
    53 g_main_context_iterate.isra 0x7ffff592cd08
    54 g_main_context_iteration 0x7ffff592cdbc
    55 QEventDispatcherGlib :: processEvents(QFlags<QEventLoop :: ProcessEventsFlag>) 0x7ffff6dc6c75
    56 QGuiEventDispatcherGlib :: processEvents(QFlags<QEventLoop :: ProcessEventsFlag>) 0x7ffff7369ab6
    57 QEventLoop :: processEvents(QFlags<QEventLoop :: ProcessEventsFlag>) 0x7ffff6d96caf
    58 QEventLoop :: exec(QFlags<QEventLoop :: ProcessEventsFlag>) 0x7ffff6d96ffd
    59 QCoreApplication :: exec() 0x7ffff6d9c519
    60 main main.cpp 67 0x406602

    Added after 33 minutes:


    Here is a complete self-contained example.
    Once you start mousing over the items in the tree you get pop-ups and you segfault.

    Qt Code:
    1. #include <QtGui>
    2. #include <iostream>
    3.  
    4. class MyModel : public QStandardItemModel {
    5.  
    6. public:
    7. bool hasChildren(const QModelIndex &parent = QModelIndex()) const;
    8. void setDialogParent(QWidget* dp) { dialogParent = dp; }
    9. private:
    10. QWidget* dialogParent;
    11. };
    12.  
    13. bool MyModel::hasChildren(const QModelIndex &parent) const {
    14. bool ret = QStandardItemModel::hasChildren(parent);
    15. std::cout << "returning " << ret << std::endl;
    16. QMessageBox::information(dialogParent, "Hey", "hasChildren was called");
    17. return ret;
    18. }
    19.  
    20. int main(int argc, char *argv[])
    21. {
    22. QApplication app(argc, argv);
    23.  
    24. MyModel model;
    25.  
    26. QList<QStandardItem*> list;
    27. list << new QStandardItem("One");
    28. list << new QStandardItem("Two");
    29. list << new QStandardItem("Three");
    30. model.invisibleRootItem()->appendRows(list);
    31.  
    32. QTreeView view;
    33. view.setModel(&model);
    34. model.setDialogParent(&view);
    35. view.setWindowTitle(QObject::tr("Simple Tree Model"));
    36. view.show();
    37. return app.exec();
    38. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by eric.frederich; 27th October 2015 at 20:26.

  6. #6
    Join Date
    Sep 2010
    Posts
    8
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: segfault with QMessageBox in QAbstractItemModel::hasChildren

    Qt5 standalone example:

    Qt Code:
    1. QT += core
    2. QT += gui
    3. QT += widgets
    4.  
    5. TARGET = example
    6. CONFIG += c++11
    7.  
    8. TEMPLATE = app
    9.  
    10. SOURCES += main.cpp
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #include <QApplication>
    2. #include <QMessageBox>
    3. #include <QPersistentModelIndex>
    4. #include <QStandardItemModel>
    5. #include <QTreeView>
    6.  
    7. class MyModel : public QStandardItemModel {
    8. bool hasChildren(const QModelIndex &parent) const override {
    9. auto ret = QStandardItemModel::hasChildren(parent);
    10. QMessageBox::information(NULL, "Title", "Message");
    11. return ret;
    12. }
    13. // Override these to make sure any indices returned from this model are persistent
    14. // Doesn't make a differents; still segfaults anyway
    15. QModelIndex parent(const QModelIndex &child) const override {
    16. return QPersistentModelIndex(QStandardItemModel::parent(child));
    17. }
    18. QModelIndex index(int row, int column, const QModelIndex &parent) const override {
    19. return QPersistentModelIndex(QStandardItemModel::index(row, column, parent));
    20. }
    21. };
    22.  
    23. int main(int argc, char *argv[])
    24. {
    25. QApplication a(argc, argv);
    26. MyModel model;
    27. QList<QStandardItem*> l;
    28. l << new QStandardItem("One");
    29. l << new QStandardItem("Two");
    30. l << new QStandardItem("Three");
    31. model.invisibleRootItem()->appendRows(l);
    32. tv.setModel(&model);
    33. tv.show();
    34. return a.exec();
    35. }
    To copy to clipboard, switch view to plain text mode 

  7. #7
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: segfault with QMessageBox in QAbstractItemModel::hasChildren

    Both examples work for me.

    "work" as there is an almost uninterrrupted stream of annoying message boxes.

    I do get these warnings though
    Qt Code:
    1. QWidget::repaint: Recursive repaint detected
    To copy to clipboard, switch view to plain text mode 
    very likely caused by the nested event loop and the focus change to the modal message box, etc.

    Since your backtrace shows the Gtk style plugin, have you tried with a different style plugin?

    Cheers,
    _

  8. #8
    Join Date
    Sep 2010
    Posts
    8
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: segfault with QMessageBox in QAbstractItemModel::hasChildren

    Crashes with all 3 available styles on my system. GTK+, Fusion and Windows.
    This trace is from a different machine running Qt5.5
    I've tested with Qt4.8 on RHEL7 and with Qt5.5 on Ubuntu 14.04 (Linux Mint 17.2).

    What system were you running on?

    0 QRasterPaintEngine :: brushOriginChanged() 0x7ffff7092178
    1 QPainter :: setBrushOrigin(QPointF const&) 0x7ffff70a7b39
    2 QTreeView :: drawBranches(QPainter *, QRect const&, QModelIndex const&) const 0x7ffff7938614
    3 QTreeView :: drawRow(QPainter *, QStyleOptionViewItem const&, QModelIndex const&) const 0x7ffff793ca10
    4 QTreeView :: drawTree(QPainter *, QRegion const&) const 0x7ffff793fd1d
    5 QTreeView :: paintEvent(QPaintEvent *) 0x7ffff7946a46
    6 QWidget :: event(QEvent *) 0x7ffff76f11d8
    7 QFrame :: event(QEvent *) 0x7ffff77ec19e
    8 QAbstractItemView :: viewportEvent(QEvent *) 0x7ffff790925b
    9 QTreeView :: viewportEvent(QEvent *) 0x7ffff7947af0
    10 QCoreApplicationPrivate :: sendThroughObjectEventFilters(QObject *, QEvent *) 0x7ffff6895496
    11 QApplicationPrivate :: notify_helper(QObject *, QEvent *) 0x7ffff76b04ac
    12 QApplication :: notify(QObject *, QEvent *) 0x7ffff76b5630
    13 QCoreApplication :: notifyInternal(QObject *, QEvent *) 0x7ffff6895663
    14 QWidgetPrivate :: sendPaintEvent(QRegion const&) 0x7ffff76ea499
    15 QWidgetPrivate :: drawWidget(QPaintDevice *, QRegion const&, QPoint const&, int, QPainter *, QWidgetBackingStore *) 0x7ffff76eaaaf
    16 QWidgetPrivate :: paintSiblingsRecursive(QPaintDevice *, QList<QObject *> const&, int, QRegion const&, QPoint const&, int, QPainter *, QWidgetBackingStore *) 0x7ffff76eb7e4
    17 QWidgetPrivate :: paintSiblingsRecursive(QPaintDevice *, QList<QObject *> const&, int, QRegion const&, QPoint const&, int, QPainter *, QWidgetBackingStore *) 0x7ffff76eb63a
    18 QWidgetPrivate :: drawWidget(QPaintDevice *, QRegion const&, QPoint const&, int, QPainter *, QWidgetBackingStore *) 0x7ffff76ea652
    19 ?? 0x7ffff76bd3d6
    20 ?? 0x7ffff76bdc5e
    21 ?? 0x7ffff770dd1b
    22 QApplicationPrivate :: notify_helper(QObject *, QEvent *) 0x7ffff76b04cc
    23 QApplication :: notify(QObject *, QEvent *) 0x7ffff76b5630
    24 QCoreApplication :: notifyInternal(QObject *, QEvent *) 0x7ffff6895663
    25 QGuiApplicationPrivate :: processExposeEvent(QWindowSystemInterfacePrivate :: ExposeEvent *) 0x7ffff6e39210
    26 QGuiApplicationPrivate :: processWindowSystemEvent(QWindowSystemInterfacePri vate :: WindowSystemEvent *) 0x7ffff6e39e9d
    27 QWindowSystemInterface :: sendWindowSystemEvents(QFlags<QEventLoop :: ProcessEventsFlag>) 0x7ffff6e1efbf
    28 ?? 0x7fffee0efde0
    29 g_main_context_dispatch 0x7ffff51ebe04
    30 ?? 0x7ffff51ec048
    31 g_main_context_iteration 0x7ffff51ec0ec
    32 QEventDispatcherGlib :: processEvents(QFlags<QEventLoop :: ProcessEventsFlag>) 0x7ffff68eaa87
    33 QEventLoop :: exec(QFlags<QEventLoop :: ProcessEventsFlag>) 0x7ffff6893212
    34 QCoreApplication :: exec() 0x7ffff689ad3d
    35 main main.cpp 39 0x403121

    Added after 25 minutes:


    Actually, I'm working from home today in a very convoluted way (from windows I VNC to a RHEL6 machine, then ssh with X forwarding to the RHEL7 machine).
    In this convoluted set up I get the "QWidget::repaint: Recursive repaint detected" printout but no segfault.
    Last edited by eric.frederich; 28th October 2015 at 15:55.

  9. #9
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: segfault with QMessageBox in QAbstractItemModel::hasChildren

    I am on Debian/Unstable, Qt 5.4.2, not sure which style.

    Anyway, mostly an academic problem right? You wouldn't use such a messagebox anyway, even without crash it would make the application unusable.

    Cheers,
    _

Similar Threads

  1. Replies: 5
    Last Post: 23rd April 2015, 15:14
  2. QSqlQuery segfault
    By pdoria in forum Qt Programming
    Replies: 14
    Last Post: 16th March 2012, 21:01
  3. Replies: 4
    Last Post: 7th May 2010, 03:13
  4. Segfault
    By Dumbledore in forum Qt Programming
    Replies: 3
    Last Post: 12th November 2007, 07:31
  5. segfault
    By conexion2000 in forum Qt Programming
    Replies: 1
    Last Post: 31st May 2006, 12:34

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.