问题
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