Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. Android dns resolve crash
Forum Updated to NodeBB v4.3 + New Features

Android dns resolve crash

Scheduled Pinned Locked Moved Solved Mobile and Embedded
17 Posts 4 Posters 1.7k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • jsulmJ jsulm

    @wantfat said in Android dns resolve crash:

    QNetworkReply *reply = mgr->get(request);

    Did you check that reply is a valid pointer?

    W Offline
    W Offline
    wantfat
    wrote on last edited by
    #4

    @jsulm Yes, I tried it just now, but the same thing happened. I changed the code to

    QMetaObject::invokeMethod(QAbstractEventDispatcher::instance(thr), ={
    QTimer *t = new QTimer();
    t->setSingleShot(true);
    t->start(1);

            QObject::connect(t, &QTimer::timeout, [=](){
                QHostInfo::lookupHost(QString("xyz%1.cn").arg(i), [=](const QHostInfo &info){
                    qDebug() << info.errorString();
                    QMetaObject::invokeMethod(t, "start");
                });
            });
        });
    

    It also crash in the same place.

    jsulmJ 1 Reply Last reply
    0
    • W wantfat

      @jsulm Yes, I tried it just now, but the same thing happened. I changed the code to

      QMetaObject::invokeMethod(QAbstractEventDispatcher::instance(thr), ={
      QTimer *t = new QTimer();
      t->setSingleShot(true);
      t->start(1);

              QObject::connect(t, &QTimer::timeout, [=](){
                  QHostInfo::lookupHost(QString("xyz%1.cn").arg(i), [=](const QHostInfo &info){
                      qDebug() << info.errorString();
                      QMetaObject::invokeMethod(t, "start");
                  });
              });
          });
      

      It also crash in the same place.

      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #5

      @wantfat said in Android dns resolve crash:

      I tried it just now, but the same thing happened

      How? Please show the code.

      "It also crash in the same place." - which place exactly?

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      W 1 Reply Last reply
      0
      • jsulmJ jsulm

        @wantfat said in Android dns resolve crash:

        I tried it just now, but the same thing happened

        How? Please show the code.

        "It also crash in the same place." - which place exactly?

        W Offline
        W Offline
        wantfat
        wrote on last edited by
        #6

        @jsulm This is the code, I check reply valid
        #include <QGuiApplication>
        #include <QQmlApplicationEngine>
        #include "QAbstractEventDispatcher"
        #include "QThread"
        #include "QTimer"
        #include "QNetworkAccessManager"
        #include "QNetworkReply"
        #include "QNetworkReply"
        #include "QHostInfo"

        int main(int argc, char *argv[])
        {
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

        QGuiApplication app(argc, argv);
        
        QQmlApplicationEngine engine;
        const QUrl url(QStringLiteral("qrc:/main.qml"));
        QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                         &app, [url](QObject *obj, const QUrl &objUrl) {
            if (!obj && url == objUrl)
                QCoreApplication::exit(-1);
        }, Qt::QueuedConnection);
        engine.load(url);
        
        for (int i = 0; i < 10; i++) {
            QThread *thr = new QThread();
            thr->start();
        
            while (!QAbstractEventDispatcher::instance(thr)) {
                thr->wait(1);
            }
        
            QMetaObject::invokeMethod(QAbstractEventDispatcher::instance(thr), [=](){
                QTimer *t = new QTimer();
                t->setSingleShot(true);
                t->start(1);
        
                QNetworkAccessManager *mgr = new QNetworkAccessManager();
                QObject::connect(t, &QTimer::timeout, [=](){
                    QNetworkRequest request;
                    request.setUrl(QString("http://xyz%1.cn").arg(i));
        
                    QNetworkReply *reply = mgr->get(request);
                    if (reply == nullptr) {
                        qDebug() << "reply is null";
                        return;
                    }
        
                    QObject::connect(reply, &QNetworkReply::finished, [=](){
                        reply->deleteLater();
                        t->start();
                    });
                });
            });
        }
        
        return app.exec();
        

        }

        When it crash, The stack is as follows

        1 dlfree 0xb6dcbf4c
        2 free 0xb6db2258
        3 __res_ndestroy 0xb6dba4da
        4 __res_vinit 0xb6dba578
        5 QHostInfoAgent::fromName(QString const&) 0xa2aadd7e
        6 QHostInfoRunnable::run() 0xa2aa5516
        7 QThreadPoolThread::run() 0xa2e6e05e
        8 QThreadPrivate::start(void *) 0xa2e6c400
        9 __pthread_start(void *) 0xb6db659c
        10 __start_thread 0xb6db44c4
        11 ??

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #7

          Hi,

          Why are you creating 10 threads making get requests almost as fast as possible all the time your application is running ?

          On a side note, you are leaking QNetworkAccessManager and QTimer objects.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          W 1 Reply Last reply
          0
          • SGaistS SGaist

            Hi,

            Why are you creating 10 threads making get requests almost as fast as possible all the time your application is running ?

            On a side note, you are leaking QNetworkAccessManager and QTimer objects.

            W Offline
            W Offline
            wantfat
            wrote on last edited by
            #8

            @sgaist If I had two threads, It would still crash, just for a long time. the request is serial execution .
            thank you.

            1 Reply Last reply
            0
            • W Offline
              W Offline
              wantfat
              wrote on last edited by
              #9

              I run on another phone (Android 9, armv7) , The code work well. The mobile phone that had abnormalities is Android 5.1 armv7. I am not sure whether it depend on mobile phone .

              J.HilkJ 1 Reply Last reply
              0
              • W wantfat

                I run on another phone (Android 9, armv7) , The code work well. The mobile phone that had abnormalities is Android 5.1 armv7. I am not sure whether it depend on mobile phone .

                J.HilkJ Offline
                J.HilkJ Offline
                J.Hilk
                Moderators
                wrote on last edited by
                #10

                @wantfat you do realize that

                QThread *thr = new QThread();
                    thr->start();
                
                    while (!QAbstractEventDispatcher::instance(thr)) {
                        thr->wait(1);
                    }
                

                is doing nothing but delay forcefully delay the loop by 1 millisecond?
                Also you don't need a QNetworkAccessManager instance for each get request. QNetworkAccessManager can handle 5 get requests in parallel, IIRC, and the rest is automatically queued


                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                Q: What's that?
                A: It's blue light.
                Q: What does it do?
                A: It turns blue.

                W 1 Reply Last reply
                1
                • J.HilkJ J.Hilk

                  @wantfat you do realize that

                  QThread *thr = new QThread();
                      thr->start();
                  
                      while (!QAbstractEventDispatcher::instance(thr)) {
                          thr->wait(1);
                      }
                  

                  is doing nothing but delay forcefully delay the loop by 1 millisecond?
                  Also you don't need a QNetworkAccessManager instance for each get request. QNetworkAccessManager can handle 5 get requests in parallel, IIRC, and the rest is automatically queued

                  W Offline
                  W Offline
                  wantfat
                  wrote on last edited by
                  #11

                  @j-hilk After call QThread::start the eventDispatcher of thread is null, so must take a sleep wait for eventDispatcher be create, QNetworkAccessManager only one instance for per thread .

                  J.HilkJ 1 Reply Last reply
                  0
                  • W wantfat

                    @j-hilk After call QThread::start the eventDispatcher of thread is null, so must take a sleep wait for eventDispatcher be create, QNetworkAccessManager only one instance for per thread .

                    J.HilkJ Offline
                    J.HilkJ Offline
                    J.Hilk
                    Moderators
                    wrote on last edited by
                    #12

                    @wantfat said in Android dns resolve crash:

                    , QNetworkAccessManager only one instance for per thread

                    no, from your code, you create 10 QNetworkAccessManager instances and all live inside the main(Gui) thread


                    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                    Q: What's that?
                    A: It's blue light.
                    Q: What does it do?
                    A: It turns blue.

                    W 1 Reply Last reply
                    0
                    • J.HilkJ J.Hilk

                      @wantfat said in Android dns resolve crash:

                      , QNetworkAccessManager only one instance for per thread

                      no, from your code, you create 10 QNetworkAccessManager instances and all live inside the main(Gui) thread

                      W Offline
                      W Offline
                      wantfat
                      wrote on last edited by
                      #13

                      @j-hilk QMetaObject::invokeMethod(QAbstractEventDispatcher::instance(thr), ={

                      });
                      This code make sure lambda run on thr.

                      J.HilkJ 1 Reply Last reply
                      0
                      • W wantfat

                        @j-hilk QMetaObject::invokeMethod(QAbstractEventDispatcher::instance(thr), ={

                        });
                        This code make sure lambda run on thr.

                        J.HilkJ Offline
                        J.HilkJ Offline
                        J.Hilk
                        Moderators
                        wrote on last edited by
                        #14

                        @wantfat have you checked that ? by combining invokeMethod with a lambada the object reference pointer becomes a context pointer. I see no reason, why it should be called from the Thread instance, or I personally don't know, never tried threading in this unusual way.


                        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                        Q: What's that?
                        A: It's blue light.
                        Q: What does it do?
                        A: It turns blue.

                        W 1 Reply Last reply
                        0
                        • J.HilkJ J.Hilk

                          @wantfat have you checked that ? by combining invokeMethod with a lambada the object reference pointer becomes a context pointer. I see no reason, why it should be called from the Thread instance, or I personally don't know, never tried threading in this unusual way.

                          W Offline
                          W Offline
                          wantfat
                          wrote on last edited by
                          #15

                          @j-hilk Yes, I have checked it, this is detail info, https://stackoverflow.com/a/21653558

                          1 Reply Last reply
                          0
                          • W Offline
                            W Offline
                            wantfat
                            wrote on last edited by wantfat
                            #16

                            The test code work well on Qt 5.12.3, The problematic version is Qt 5.12.4 . I compared two versions of the relevant code
                            0_1564538533924_QQ图片20190731100118.png
                            0_1564538549953_QQ图片20190731100124.png

                            If method __res_init resolve fail dlsym be call, and it return a valid pointer, But it is not a thread safe function. Maybe so.

                            1 Reply Last reply
                            0
                            • W Offline
                              W Offline
                              wantfat
                              wrote on last edited by
                              #17

                              I solved this problem by export thread safe __res_init

                              #if (QT_VERSION == QT_VERSION_CHECK(5,12,4))

                              #include "resolv.h"
                              #include "QMutex"

                              static QMutex mut;

                              int __res_init(void) {
                              QMutexLocker lck(&mut);
                              return res_init();
                              }

                              #endif

                              Thanks every one.

                              1 Reply Last reply
                              1

                              • Login

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • Users
                              • Groups
                              • Search
                              • Get Qt Extensions
                              • Unsolved