QTextEdit crash on appending text
<p>I am developing an application which run scripts and display scripts results in a "Shell Window". This window contains a <code>QTextEdit</code> where all script output is appended.</p>

<p>The script may append data to two <code>QTextStream</code>: <code>out</code> and <code>err</code>.</p>

<p>To let the <code>QTextStream</code> use the <code>QTextEdit</code> as an output I used the <code>TextEditIODevice</code> class (source below).</p>

<p>The script is run in a separated thread in the <code>VirtualMachine</code> class (source not provided).</p>

<p>My problem is that the program randomly crash while appending data to the <code>QTextEdit</code>.</p>

<p>Here is a screen shoot of the crash:</p>

<p><a href="https://lut.im/SqxxyqgDUI/jjoY6q7BJsvUTest.png" rel="nofollow" title="Show fullsize"><img src="https://lut.im/SqxxyqgDUI/jjoY6q7BJsvUTest" alt="debugger"></a></p>

<p>Does someone already had this problem ? Do you know how to solve it ?</p>

<p>Thanks for your help solving this !</p>

<hr>

<h1>TextEditIODevice</h1>

<h2>Header file</h2>

<pre><code>class TextEditIODevice : public QIODevice
{
    Q_OBJECT

public:
    TextEditIODevice(QTextEdit * qTextEdit, QColor color, QObject * parent);

    virtual ~TextEditIODevice();

protected:
    qint64 readData(char *data, qint64 maxlen);

    qint64 writeData(const char *data, qint64 len);

private:
    /**
     * @brief Pointer to QTextEdit
     */
    QPointer&lt;QTextEdit&gt; textEdit;

    /**
     * @brief Text color
     */
    QColor color;

    /**
     * @brief Shared pointer to QTextEdit associated mutex
     */
    QSharedPointer&lt;QMutex&gt; mutex;

    /**
     * @brief Storage for QTextEdit associated mutexes
     */
    static QMap&lt;QPointer&lt;QTextEdit&gt;, QSharedPointer&lt;QMutex&gt;&gt; mutexes;
};
</code></pre>

<h2>Source file</h2>

<pre><code>QMap&lt;QPointer&lt;QTextEdit&gt;, QSharedPointer&lt;QMutex&gt;&gt; TextEditIODevice::mutexes;

TextEditIODevice::TextEditIODevice(QTextEdit * qTextEdit, QColor color, QObject * parent) :
    QIODevice(parent),
    textEdit(qTextEdit),
    color(color)
{
    open(QIODevice::WriteOnly | QIODevice::Text);

    qRegisterMetaType&lt;QTextCharFormat&gt;("QTextCharFormat");
    qRegisterMetaType&lt;QTextBlock&gt;("QTextBlock");
    qRegisterMetaType&lt;QTextCursor&gt;("QTextCursor");

    if(mutexes.contains(textEdit))
    {
        qDebug() &lt;&lt; QString("[%1] Reuse previously created mutex").arg(textEdit-&gt;objectName());
        mutex = mutexes[textEdit];
    }
    else
    {
        qDebug() &lt;&lt; QString("[%1] Create mutex").arg(textEdit-&gt;objectName());
        mutex = QSharedPointer&lt;QMutex&gt;(new QMutex());
        mutexes.insert(textEdit, mutex);
    }
}

TextEditIODevice::~TextEditIODevice()
{
}

qint64 TextEditIODevice::readData(char *data, qint64 maxlen)
{
    Q_UNUSED(data);
    Q_UNUSED(maxlen);
    return 0;
}



qint64 TextEditIODevice::writeData(const char *data, qint64 len)
{
    if(textEdit)
    {
        qDebug() &lt;&lt; QString("[%1] Wait for lock").arg(textEdit-&gt;objectName());
        mutex-&gt;lock();
        qDebug() &lt;&lt; QString("[%1] Append text : %2").arg(textEdit-&gt;objectName()).arg(data);
        const QColor lastColor = textEdit-&gt;textColor();
        textEdit-&gt;setTextColor(color);
        textEdit-&gt;append(QString(data));
        textEdit-&gt;setTextColor(lastColor);
        qDebug() &lt;&lt; QString("[%1] Unlock mutex").arg(textEdit-&gt;objectName());
        mutex-&gt;unlock();
    }

    return len;
}
</code></pre>