2014-09-19 2 views
1

종료시 응용 프로그램이 중단되는 원인을 격리 할 수 ​​없습니다. 더 혼란을주는 것은 그것이 언제나 부서지는 것이 아니라, 때로는 그렇지 않은 경우가 있으며, 완전히 혼란스러워하는 것입니다.종료시 Qt 응용 프로그램이 충돌하고 OS가 "fault tolerant heap shim"을 적용합니다

샘플은 기본적으로 정적 Google지도 API 요청을 PNG 이미지로로드하여 QML에 표시하는 맞춤 이미지 제공 업체를 구합니다. 이미지 공급자 자체가 작동합니다. 먼저 네트워크 액세스 관리자를 스택에서 인스턴스화하는 것이 문제 일 수 있다고 생각했지만, 그렇지 않습니다. 역동적으로 인스턴스를 생성하는 것과 동일한 동작이 발생합니다. 우스운 일은 충돌이 특히 어떤 것에도 대응하지 않는 것입니다. 앱을 시작하고 닫는 순간 가끔씩 충돌이 일어나지 만 충돌이 거의 발생하지 않습니다. 경우에 따라지도 중심 및 확대/축소와의 여러 상호 작용으로 인해 이탈시 충돌이 발생하지 않지만 대부분은 종료됩니다.

또 다른 용의자는 네트워크 요청이 완료되는 동안 이미지 공급자 메서드를 "차단"하기 위해 인스턴스화하는 이벤트 루프입니다. 이미지 공급자의 디자인으로 인해 이미지는 요청한 것과 동일한 방법으로 반환되어야합니다. 즉, 메서드에서 요청을 시작하고 completed 신호를 다음과 같이 연결하여 캡처하는 "권장"방식을 사용할 수 없습니다. 또 다른 방법. 그러나 공급자는 항상 문제가 없다고 가정 한 이미지를 제공하기 때문에 공급자 중 하나 인 것 같지 않습니다. 적어도 직접적으로는 아니지만 네트워크 액세스의 부작용 일 수 있습니까?

BTW Qt는 첫 번째 네트워크 액세스 관리자에서만 경고 메시지를 표시합니다.

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 

... 그리고 그 경고를 제거하는 희망에 신선한 5.3.1로 업그레이드 한 후 실제로 두 개 더 이전 4 개 추가에 출연 : 그 4 Qt는 5.2로 난 단지 가지고

QSslSocket: cannot resolve SSL_CTX_set_next_proto_select_cb 
QSslSocket: cannot resolve SSL_get0_next_proto_negotiated 

아마도 이러한 경고는 충돌과 관련이 있을까요?

다음

또한 APPCRASH 정보입니다 :

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 

플랫폼 정보 :

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; 
    }  
}; 
: 윈도우 7 64, 주식 32 비트 Qt는 여기

은 관련 코드입니다 GCC 빌드

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

재귀 이벤트 루프는 문제의 근원이 아닙니다. 이미지 공급자를 사용하는 디자인은 본질적으로 손상되었습니다. 다른 방법으로해야합니다. –

+0

@KubaOber - 네트워크 액세스 관리자가 본질적으로 비동기식이며 이미지 공급자가 동일한 방법으로 이미지를 요청하고 반환해야하는 경우 질문이 제기됩니다. 어떻게 이미지 공급자를 구현할 것인가? –

+0

'QQuickImageProvater' API는 근본적으로 손상되었습니다 :(QML 엔진이 별도의 스레드에서 공급자를 실행하는 추악한 해결 방법이 있습니다. –

답변

2

문제는 이미지 공급자 클래스에 있습니다. 나는 그것이 어디에서 발생했는지 정확히 알지 못한다. 그러나 그것 없이는 충돌을 재현 할 수 없기 때문이다. 귀하의 케이스에있는 이미지 제공 업체가 완전히 불필요하기 때문에 이것을 말할 수 있습니다. QtQuick Image 요소가 Google API URL 소스를 그대로 받아 들일 수 있습니다.