Qt应用程序在退出时崩溃,OS应用“容错堆垫片” [英] Qt application crashes on exit, OS applies "fault tolerant heap shim"

查看:568
本文介绍了Qt应用程序在退出时崩溃,OS应用“容错堆垫片”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法分离导致应用程序在退出时崩溃的原因。更进一步的混乱是,它不总是崩溃,有时它是,有时它不,并且似乎是完全任意的。



样本基本上自定义图片提供程序,它将静态Google Maps API请求作为PNG图片加载以在QML中显示。图像提供者本身工作,我第一次怀疑的问题可能是在栈上实例化网络访问管理器,但这不是它,我得到相同的行为动态实例化它。有趣的是,崩溃似乎不对应任何特别的。只是启动和关闭应用程序有时会生成崩溃,没有任何与它的任何交互,但它大多不会崩溃,没有任何交互。有时,与地图中心和缩放的多次互动在退出时不会发生崩溃,但大多数时间都会发生。



另一个可疑是我实例化的事件循环在网络请求完成时阻止图像提供方方法。由于图像提供程序的设计,图像必须通过请求它的相同方法返回,换句话说,我不能使用推荐方法只是从一个方法启动请求并捕获它连接其 completed 信号到另一个方法。但是,似乎也不是,因为提供者总是设法提供的图像我认为没有问题。至少不直接,但也许有网络访问的一些副作用?



BTW Qt正在发出一些警告,只有在第一个网络访问管理器使用。对于Qt 5.2,我只有这四个:

  QSslSocket:无法解析TLSv1_1_client_method 
QSslSocket:无法解析TLSv1_2_client_method
QSslSocket:无法解析TLSv1_1_server_method
QSslSocket:无法解析TLSv1_2_server_method
QSslSocket:无法解析SSL_select_next_proto

...和升级到新的5.3.1后,希望删除这些警告实际上除了上述四个之外出现了两个:

  QSslSocket:无法解析SSL_CTX_set_next_proto_select_cb 
QSslSocket:无法解析SSL_get0_next_proto_negotiated



这里也是appcrash信息:

 

code>故障模块名称:ntdll.dll
故障模块版本:6.1.7601.17725
故障模块时间戳:4ec49b8f
异常代码:c0000005
异常偏移量:000332a0
OS版本:6.1.7601.2.1.0.256.1
语言代码ID:1033
其他信息1:0a9e
其他信息2:0a9e372d3b4ad19135b953a78882e789
其他信息3:0a9e
附加信息4:0a9e372d3b4ad19135b953a78882e789

平台信息:Windows 7 x64, p>

以下是相关代码:



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

属性字符串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
}
}

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)
b $ b 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()
}
}


解决方案

问题出在你的图片提供者类中。我不知道到底在哪里,但它在那里,因为没有它,我不能重现崩溃。我可以告诉这个,因为在你的情况下的图像提供程序是完全不必要的 - 一个QtQuick Image 元素将接受和使用Google API网址源,因为它是。 p>

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()
    }
}

解决方案

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.

这篇关于Qt应用程序在退出时崩溃,OS应用“容错堆垫片”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆