Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Mouse-over plain text tabs throwing exceptions



  • Update: This was a bug specific to 5.12.1 (not present in 5.12.0), and appears to be fixed in 5.13.0

    Anytime I display text containing tabs (the plain text tab character, '\t'), mouse-over or clicking in front of the leading tab causes the program to throw:
    (VS2017) Exception thrown at 0x00007FFA964E33F3 (Qt5Guid.dll) in <ProgramName>: 0xC0000005: Access violation writing location 0x0.

    Qt Creator 4.8.1 actually crashes the entire Creator IDE, not just the application being debugged.

    I've distilled this to the simplest elements, so no error checking (it's up to you to select a real file when prompted, for example), using three files main.h, main.cpp, and CrashExample.ui in an otherwise blank VS2017 or Qt Creator project.

    I've tried variations on the code, such as using QDocument, using QTextEditor vs QTextBrowser, plainText versus setText(), et cetera. They all produce the same result: move mouse cursor towards front of a leading tab, and the program throws. If it doesn't happen immediately from hover-over (sometimes it takes a few seconds), it will immediately if you click in that region (not mid-tab, but right at the front of any leading tab on a new line).

    Is this a problem with Qt, or am I missing something? Open any plain-text file with leading tabs on any of the lines, then mouse over where the tab is, and move the mouse towards the front of the tab and the exception will happen. I've tried putting the QTextEdit/QTextBrowser inside various other widgets, with various layouts, making the class inherit QMainWindow instead of QPlainTextEdit, but none of that has any effect at all.

    The one thing that has a small impact, changing from QApplication to QGuiApplication, builds fine, but launching (debug mode) generates:
    "Debug Error!
    Program: <Qt dir>\5.12.1\msvc2017_64\bin\Qt5Cored.dll
    Module: 5.12.1
    File: kernel\qwidget.cpp
    Line: 1126"
    QWidget: Cannot create a QWidget without QApplication"

    So, I can't really test if that helps fix the problem, when it doesn't launch as a QGuiApplication. The class constructor should be using parent = nullptr in both cases, since I'm not passing arguments when I create a CrashExample object, so not sure why this is happening.

    It's very hard to get results for this issue, because search leads to topics about QTabs, not the tab character in plain text.

    Build in debug using x64 with Qt 5.12.1 under Windows 10.
    Pre-processor definitions are the default when making a VS Project with integrated Qt: UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;QT_DLL;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions)

    //main.h
    #pragma once
    
    #include <QtWidgets>
    #include <QtWidgets/QApplication>
    #include <QObject>
    #include <QPlainTextEdit>
    
    class CrashExample : public QPlainTextEdit
    {
    	Q_OBJECT
    
    public:
    	CrashExample(QWidget *parent = nullptr);
    };
    
    
    //main.cpp
    #include "main.h"
    
    CrashExample::CrashExample(QWidget *parent) : QPlainTextEdit(parent)
    {
    	auto fileName = QFileDialog::getOpenFileName(this, tr("Locate File..."));
    	QFile file(fileName);
    	file.open(QIODevice::ReadOnly | QFile::Text);
    
    	QTextStream in(&file);
    	QString text = in.readAll();
    
    	this->setPlainText(text);
    }
    
    int main(int argc, char *argv[])
    {
    	QApplication app(argc, argv);
    
    	CrashExample example; // this is where the program halts if QGuiApplication
    	example.setWindowTitle(QObject::tr("Tab Crash Example"));
    	example.show();
    
    	return app.exec(); // exception thrown during the main app loop here
    }
    
    //CrashExample.ui
    <UI version="4.0" >
     <class>CrashExampleClass</class>
     <widget class="QWidget" name="CrashExampleClass" >
      <property name="objectName" >
       <string notr="true">CrashExampleClass</string>
      </property>
      <property name="geometry" >
       <rect>
    	<x>0</x>
    	<y>0</y>
    	<width>600</width>
    	<height>400</height>
       </rect>
      </property>
      <property name="windowTitle" >
       <string>CrashExample</string>
      </property>
     </widget>
     <layoutDefault spacing="6" margin="11" />
     <pixmapfunction></pixmapfunction>
     <resources>
       <include location="CrashExample.qrc"/>
     </resources>
     <connections/>
    </UI>
    

    Thanks for any insight into why this is throwing exceptions. This is not for any school projects; I don't need to do anything with arbitrary restrictions, so any suggestions on how to work-around this to get tabs to show up in plain text documents without crashing is also helpful.


  • Qt Champions 2019

    @eventHandler said in Mouse-over plain text tabs throwing exceptions:

    QWidget: Cannot create a QWidget without QApplication"

    Do you have any static variables/members (QWidget)?

    Can you run your app through debugger and post the stack trace after it crashed?


  • Moderators

    @eventHandler
    did you add QT += gui to your pro file ? QGuiApplication requires the gui plugin, where as QApplication only requires the widgets one.

    Also don't forget to clean rebuild after modifying the pro file



  • @J.Hilk Yes, QT += core gui widgets

    @jsulm Nothing except what I posted in any non-generated code.

     	Qt5Guid.dll!00007ffa959933f3()	Unknown
     	Qt5Guid.dll!00007ffa959bf891()	Unknown
     	Qt5Widgetsd.dll!00007ffa968effe9()	Unknown
     	Qt5Widgetsd.dll!00007ffa9693b93a()	Unknown
     	Qt5Widgetsd.dll!00007ffa96933e67()	Unknown
     	Qt5Widgetsd.dll!00007ffa96934d01()	Unknown
     	Qt5Widgetsd.dll!00007ffa968f7448()	Unknown
     	Qt5Widgetsd.dll!00007ffa968ed72c()	Unknown
     	Qt5Widgetsd.dll!00007ffa9661bb27()	Unknown
     	Qt5Widgetsd.dll!00007ffa967713ef()	Unknown
     	Qt5Widgetsd.dll!00007ffa9677449c()	Unknown
     	Qt5Widgetsd.dll!00007ffa965aff35()	Unknown
     	Qt5Widgetsd.dll!00007ffa9677959d()	Unknown
     	Qt5Cored.dll!00007ffa9128f194()	Unknown
     	Qt5Widgetsd.dll!00007ffa965bc09e()	Unknown
     	Qt5Widgetsd.dll!00007ffa965b7368()	Unknown
     	Qt5Cored.dll!00007ffa9128e2a6()	Unknown
     	Qt5Cored.dll!00007ffa9128e14b()	Unknown
     	Qt5Widgetsd.dll!00007ffa965be7c4()	Unknown
     	Qt5Widgetsd.dll!00007ffa96666c33()	Unknown
     	Qt5Widgetsd.dll!00007ffa96665276()	Unknown
     	Qt5Widgetsd.dll!00007ffa965bc0be()	Unknown
     	Qt5Widgetsd.dll!00007ffa965b6b5f()	Unknown
     	Qt5Cored.dll!00007ffa9128e2a6()	Unknown
     	Qt5Cored.dll!00007ffa9128e14b()	Unknown
     	Qt5Guid.dll!00007ffa957f1144()	Unknown
     	Qt5Guid.dll!00007ffa957f3ec3()	Unknown
     	Qt5Guid.dll!00007ffa957c22e5()	Unknown
     	qwindowsd.dll!00007ffa950547e2()	Unknown
     	Qt5Cored.dll!00007ffa9134f008()	Unknown
     	user32.dll!00007ffae7006d41()	Unknown
     	user32.dll!00007ffae7006713()	Unknown
     	Qt5Cored.dll!00007ffa9134f8f8()	Unknown
     	qwindowsd.dll!00007ffa95054794()	Unknown
     	Qt5Cored.dll!00007ffa912884d3()	Unknown
     	Qt5Cored.dll!00007ffa9128870e()	Unknown
     	Qt5Cored.dll!00007ffa9128bd9f()	Unknown
     	Qt5Guid.dll!00007ffa957ee4c8()	Unknown
     	Qt5Widgetsd.dll!00007ffa965b650a()	Unknown
    >	CrashExample.exe!main(int argc, char * * argv) Line 24	C++
     	CrashExample.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal) Line 104	C++
     	[External Code]	
    

    I can't really debug this WinMain line 104 (qtmain_win.cpp), since there is no line 104 in any of my code or any files named qtmain_win.cpp; I assume it's part of the library code.

    I'm including the generated files here:

    /****************************************************************************
    ** Resource object code
    **
    ** Created by: The Resource Compiler for Qt version 5.12.1
    **
    ** WARNING! All changes made in this file will be lost!
    *****************************************************************************/
    
    #ifdef QT_NAMESPACE
    #  define QT_RCC_PREPEND_NAMESPACE(name) ::QT_NAMESPACE::name
    #  define QT_RCC_MANGLE_NAMESPACE0(x) x
    #  define QT_RCC_MANGLE_NAMESPACE1(a, b) a##_##b
    #  define QT_RCC_MANGLE_NAMESPACE2(a, b) QT_RCC_MANGLE_NAMESPACE1(a,b)
    #  define QT_RCC_MANGLE_NAMESPACE(name) QT_RCC_MANGLE_NAMESPACE2( \
            QT_RCC_MANGLE_NAMESPACE0(name), QT_RCC_MANGLE_NAMESPACE0(QT_NAMESPACE))
    #else
    #   define QT_RCC_PREPEND_NAMESPACE(name) name
    #   define QT_RCC_MANGLE_NAMESPACE(name) name
    #endif
    
    #ifdef QT_NAMESPACE
    namespace QT_NAMESPACE {
    #endif
    
    #ifdef QT_NAMESPACE
    }
    #endif
    
    int QT_RCC_MANGLE_NAMESPACE(qInitResources_CrashExample)();
    int QT_RCC_MANGLE_NAMESPACE(qInitResources_CrashExample)()
    {
        return 1;
    }
    
    int QT_RCC_MANGLE_NAMESPACE(qCleanupResources_CrashExample)();
    int QT_RCC_MANGLE_NAMESPACE(qCleanupResources_CrashExample)()
    {
        return 1;
    }
    
    namespace {
       struct initializer {
           initializer() { QT_RCC_MANGLE_NAMESPACE(qInitResources_CrashExample)(); }
           ~initializer() { QT_RCC_MANGLE_NAMESPACE(qCleanupResources_CrashExample)(); }
       } dummy;
    }
    
    /********************************************************************************
    ** Form generated from reading UI file 'CrashExample.ui'
    **
    ** Created by: Qt User Interface Compiler version 5.12.1
    **
    ** WARNING! All changes made in this file will be lost when recompiling UI file!
    ********************************************************************************/
    
    #ifndef UI_CRASHEXAMPLE_H
    #define UI_CRASHEXAMPLE_H
    
    #include <QtCore/QVariant>
    #include <QtWidgets/QApplication>
    #include <QtWidgets/QWidget>
    
    QT_BEGIN_NAMESPACE
    
    class Ui_CrashExampleClass
    {
    public:
    
        void setupUi(QWidget *CrashExampleClass)
        {
            if (CrashExampleClass->objectName().isEmpty())
                CrashExampleClass->setObjectName(QString::fromUtf8("CrashExampleClass"));
            CrashExampleClass->resize(600, 400);
    
            retranslateUi(CrashExampleClass);
    
            QMetaObject::connectSlotsByName(CrashExampleClass);
        } // setupUi
    
        void retranslateUi(QWidget *CrashExampleClass)
        {
            CrashExampleClass->setWindowTitle(QApplication::translate("CrashExampleClass", "CrashExample", nullptr));
        } // retranslateUi
    
    };
    
    namespace Ui {
        class CrashExampleClass: public Ui_CrashExampleClass {};
    } // namespace Ui
    
    QT_END_NAMESPACE
    
    #endif // UI_CRASHEXAMPLE_H
    
    /****************************************************************************
    ** Meta object code from reading C++ file 'main.h'
    **
    ** Created by: The Qt Meta Object Compiler version 67 (Qt 5.12.1)
    **
    ** WARNING! All changes made in this file will be lost!
    *****************************************************************************/
    
    #include "../../main.h"
    #include <QtCore/qbytearray.h>
    #include <QtCore/qmetatype.h>
    #if !defined(Q_MOC_OUTPUT_REVISION)
    #error "The header file 'main.h' doesn't include <QObject>."
    #elif Q_MOC_OUTPUT_REVISION != 67
    #error "This file was generated using the moc from 5.12.1. It"
    #error "cannot be used with the include files from this version of Qt."
    #error "(The moc has changed too much.)"
    #endif
    
    QT_BEGIN_MOC_NAMESPACE
    QT_WARNING_PUSH
    QT_WARNING_DISABLE_DEPRECATED
    struct qt_meta_stringdata_CrashExample_t {
        QByteArrayData data[1];
        char stringdata0[13];
    };
    #define QT_MOC_LITERAL(idx, ofs, len) \
        Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
        qptrdiff(offsetof(qt_meta_stringdata_CrashExample_t, stringdata0) + ofs \
            - idx * sizeof(QByteArrayData)) \
        )
    static const qt_meta_stringdata_CrashExample_t qt_meta_stringdata_CrashExample = {
        {
    QT_MOC_LITERAL(0, 0, 12) // "CrashExample"
    
        },
        "CrashExample"
    };
    #undef QT_MOC_LITERAL
    
    static const uint qt_meta_data_CrashExample[] = {
    
     // content:
           8,       // revision
           0,       // classname
           0,    0, // classinfo
           0,    0, // methods
           0,    0, // properties
           0,    0, // enums/sets
           0,    0, // constructors
           0,       // flags
           0,       // signalCount
    
           0        // eod
    };
    
    void CrashExample::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
    {
        Q_UNUSED(_o);
        Q_UNUSED(_id);
        Q_UNUSED(_c);
        Q_UNUSED(_a);
    }
    
    QT_INIT_METAOBJECT const QMetaObject CrashExample::staticMetaObject = { {
        &QPlainTextEdit::staticMetaObject,
        qt_meta_stringdata_CrashExample.data,
        qt_meta_data_CrashExample,
        qt_static_metacall,
        nullptr,
        nullptr
    } };
    
    
    const QMetaObject *CrashExample::metaObject() const
    {
        return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
    }
    
    void *CrashExample::qt_metacast(const char *_clname)
    {
        if (!_clname) return nullptr;
        if (!strcmp(_clname, qt_meta_stringdata_CrashExample.stringdata0))
            return static_cast<void*>(this);
        return QPlainTextEdit::qt_metacast(_clname);
    }
    
    int CrashExample::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
    {
        _id = QPlainTextEdit::qt_metacall(_c, _id, _a);
        return _id;
    }
    QT_WARNING_POP
    QT_END_MOC_NAMESPACE
    

  • Qt Champions 2019

    @eventHandler You should use a debug build


  • Moderators

    @eventHandler
    try it without

    QFileDialog::getOpenFileName(this, tr("Locate File..."));
    

    inside your class constructor, I could see that causing trouble before the main event loop is running.



  • @J.Hilk It's not that, I don't actually use that in my own code aside from confirming it runs and clicking in front of tabs crash it; I added that so if anyone testing wants to pick a file at will, they can. My test code just automatically opens main.cpp at launch. And that's a distillation of my actual program, which has a menu with "open file" QAction instead of all being in the constructor.

    I'm just trying to make it as simple as possible for people to test and confirm if this is an issue with Qt crashing whenever leading tabs are present in text widgets, or if there is something I am missing that needs setup for QTextEdit/QTextBrowser's to avoid whatever is happening.

    Like, do I need to define some "mouse over" event code? Is there some dangling event happening when leading tabs are hovered over?

    This doesn't happen in the Qt Code Editor example, which I checked to see if they do anything I'm missing, but if you take away the "show line numbers on the left side" code that covers up the region where clicking causes crashes, it's basically this code and crashes when you click in that specific spot.



  • So, I just ran Examples\Qt-5.12.1\assistant\simpletextviewer and opened a file with that app (that example's makefile as the simple test, since I knew it'd have lines with leading tabs), and it crashed when I clicked in that narrow sweet spot just in-front of the leading tab character. So, this is definitely a Qt issue.

    Looks like it's time to make a bug report; I didn't want to bug report without checking first that it wasn't something obvious I was missing on my end. (I will wait a day to see if anyone on the "day shift" responds with further insight before marking this "solved" and filing that bug report.)

    Thanks for the quick replies @J-Hilk and @jsulm

    I guess I will try putting transparent layer above the left margin and seeing if I can use that as a workaround for crashes. Or maybe just have line numbers always forced on instead of optional.

    I'm really surprised this is a Qt issue and not something I was doing wrong; seems like text with leading tabs would be a common use-case.


  • Moderators

    @eventHandler
    if you fill a bug report, make sure to link it in this topic, that helps people who stumble upon the same issue ;-)


  • Lifetime Qt Champion

    @eventHandler said in Mouse-over plain text tabs throwing exceptions:

    simpletextviewer

    Hi
    i tried that example and it cannot get it to crash.

    So after selecting its own makefile
    alt text

    what do you do to make it crash?
    i click like crazy but nothing happens.



  • @mrjj Go to "SUBTARGETS" and click in the narrow area between the two tabs leading to debug \ and the left most edge of the window. It's a narrow line basically, about cursor width, between the edge and any leading tab.



  • @mrjj Actually, I just ran it with 5.12.0 instead of 5.12.1 and it doesn't seem to want to crash. I'm getting 5.13 now and seeing if it carried on from 5.12.1 or goes back to working like 5.12.0...



  • @mrjj Thanks for posting that exact screenshot; it made me try switching to the 5.12.0 install I still had (since I saw your file path wasn't 5.12.1), and that in turn led to me noticing 5.13.0 is out now too.

    This turned out to be specific to 5.12.1 (and maybe further specific to msvc2017_64, not sure).

    No more crashing in any of my different test cases or my original app now, without changing anything in my code. I feel pretty silly for spending so much time coming up with a lot of different attempts to fix my code over the past few days, but I did learn a few new things about Qt at least.