Qt application crashes on exit, OS applies “fault tolerant heap shim”

落花浮王杯 提交于 2020-01-05 10:04:15

问题


I can't isolate what is causing the application to crash on exit. What adds further confusion is that it doesn't always crash, sometimes it does, sometimes it doesn't and it seems to be completely arbitrary.

The sample basically crates a custom image provider that loads a static google maps API request as a PNG image to show in QML. The image provider itself works, I first suspected that the issue might be with instantiating the network access manager on the stack, but that's not it, I get the same behavior instantiating it dynamically. Funny thing is the crash doesn't seem to correspond to anything in particular. Just starting and closing the app sometimes generates the crash, without any interaction with it, but it mostly doesn't crash without any interaction. Sometimes multiple interactions with the map center and zoom result in no crash on exit, but most of the time it does.

Another suspect is the event loop I instantiate in order to "block" the image provider method while the network request is completed. Due to the design of the image provider, the image must be returned by the same method that requests it, in other words I cannot use the "recommended" approach of just launching the request from a method and capturing it with connecting its completed signal to another method. But that doesn't seem to be it either, as the provider always manages to provide the image I assume there is no problem with it. At least not directly, but maybe some side effect of the network access?

BTW Qt is spewing out some warnings, only on the first network access manager use. With Qt 5.2 I only got those four:

QSslSocket: cannot resolve TLSv1_1_client_method
QSslSocket: cannot resolve TLSv1_2_client_method
QSslSocket: cannot resolve TLSv1_1_server_method
QSslSocket: cannot resolve TLSv1_2_server_method
QSslSocket: cannot resolve SSL_select_next_proto

... and after upgrading to the fresh 5.3.1 in hopes of removing those warnings actually two more appeared in addition to the previous four:

QSslSocket: cannot resolve SSL_CTX_set_next_proto_select_cb
QSslSocket: cannot resolve SSL_get0_next_proto_negotiated

Maybe those warnings are somehow related to the crash?

Here is also the appcrash info:

  Fault Module Name:    ntdll.dll
  Fault Module Version: 6.1.7601.17725
  Fault Module Timestamp:   4ec49b8f
  Exception Code:   c0000005
  Exception Offset: 000332a0
  OS Version:   6.1.7601.2.1.0.256.1
  Locale ID:    1033
  Additional Information 1: 0a9e
  Additional Information 2: 0a9e372d3b4ad19135b953a78882e789
  Additional Information 3: 0a9e
  Additional Information 4: 0a9e372d3b4ad19135b953a78882e789

Platform info: Windows 7 x64, stock 32bit Qt build with GCC

Here is the relevant code:

C++

class MapReader : public QQuickImageProvider {
public:
    explicit MapReader() : QQuickImageProvider(QQuickImageProvider::Pixmap, QQmlImageProviderBase::ForceAsynchronousImageLoading) { }

    QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize) {
        QNetworkAccessManager m;
        Q_UNUSED(requestedSize)
        Q_UNUSED(size)
        QEventLoop loop;
        QObject::connect(&m, SIGNAL(finished(QNetworkReply*)), &loop, SLOT(quit()));
        QNetworkReply * r = m.get(QNetworkRequest(QUrl(id)));
        loop.exec();

        if (r->error()) {
            qDebug() << "Error: " << r->errorString();
            r->deleteLater();
            return QPixmap();
        }

        QPixmap p;
        p.loadFromData(r->readAll());
        r->deleteLater();
        return p;
    }    
};

QML

Rectangle {
    id: root
    width: 360
    height: 360

    property string url : 'image://map/http://maps.googleapis.com/maps/api/staticmap?center=' + n + ',' + e + '&zoom=' + zoom.value + '&size=' + width  + "x" + height + '&maptype=satellite'
    property real n : 48.858222
    property real e : 2.2945

    Timer {
        id: t
        repeat: false
        interval: 100
        running: false
        onTriggered: {
            placeholder.source = root.url
        }
    }

    function refresh() { if (t.running) t.restart(); else t.start() }

    Image {
        id: placeholder
        anchors.fill: parent
    }

    MouseArea {
        anchors.fill: parent

        onClicked: {
            var xOffset = (mouseX / width - 0.5) * (360 / Math.pow(2, zoom.value))
            var yOffset = (mouseY / height - 0.5) * (360 / Math.pow(2, zoom.value))

            console.log(xOffset + " " + yOffset)

            root.n = root.n - yOffset
            root.e = root.e + xOffset
            root.refresh()
        }
    }

    Slider {
        id: zoom
        value: 17
        maximumValue: 21
        minimumValue: 1
        stepSize: 1
        x: 80
        y: parent.height - 25
        width: parent.width - 90

        onValueChanged: root.refresh()
    }
}

回答1:


The problem is in your image provider class. I am not sure exactly where, but it is there, since without it I cannot reproduce the crash. I am able to tell this because the image provider in your case is entirely unnecessary - a QtQuick Image element will accept and work with the Google API url source as it is.



来源:https://stackoverflow.com/questions/25932804/qt-application-crashes-on-exit-os-applies-fault-tolerant-heap-shim

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!