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. QProcess in event loop causes memory leak?
Forum Updated to NodeBB v4.3 + New Features

QProcess in event loop causes memory leak?

Scheduled Pinned Locked Moved Unsolved Mobile and Embedded
2 Posts 2 Posters 420 Views 1 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.
  • M Offline
    M Offline
    mablabs
    wrote on 13 Apr 2022, 23:26 last edited by
    #1

    Hi,

    I have an iMX6 board and I'm creating a UI to allow me to connect and disconnect from a WiFi access point. Under the hood, I'm using nmcli to manage the WiFi connections and using QProcess to make the appropriate system call. Unfortunately, in order to disconnect, I have to invoke nmcli on the command line 3 times with some time in between; this was determined empirically by trying to make repeated calls to nmcli on the command line.

    When migrating this methodology to Qt, my thought process was as follows. On a button click, I will make a call from QML to an INVOKABLE that makes a system call via QProcess. Then I will kick off a Timer that runs for about 500 ms. In the onTriggered of the Timer, I will call another INVOKABLE that checks if the WiFi connection has been severed. If not, it will make another call to the INVOKABLE to disconnect and restart the timer. If it's determined that we don't have a connection anymore, we're done.

    However, I'm noticing that this results in consistent crashes of the app due to munmap_chunk, or a unaligned tcache chunk detected. Can anybody point me to why I am seeing this? Note, I don't think it's repeated calls to QProcess, because I've implemented this by adding sleeps in between the calls to QProcess::execute in disablewifi, and that seems to work fine all the time. I'm not sure why incorporating a timer in QML would cause such issues.

    This is the button click logic:

     onSigClicked: {
                            if (!infoData.getwifiStatus()) {
                                wifiResultView = true
                                textNotify.text = qsTr("WiFi already disconnected")
                            } else {
                                root.showSpinner()
                                infoData.disablewifi()
                                // For some reason disable needs to be executed three times with some pauses in between
                                wifiDisconnectTimer.start()
                            }
                        }
    

    This is the timer logic:

    function handleWiFiDisconnectResult() {
            if (!wifiConnected) {
                textNotify.text = qsTr("Disconnected successfully")
                root.hideSpinner()
                wifiResultView = true
            } else {
                infoData.disablewifi()
                wifiDisconnectTimer.start()
            }
        }
    
        Timer {
            id: wifiDisconnectTimer
            interval: 500
            running: false
            repeat: false
            onTriggered: root.handleWiFiDisconnectResult()
        }
    

    And these are the C++ functions to check the WiFi status and disconnect from WiFi:

    bool InfoData::getwifiStatus()
    {
        QString temp = "";
        memset(buf, 0, sizeof(buf));
        FILE *in = popen("nmcli connection show --active | grep wlan0", "r");
        if(in == NULL)
        {
            perror("popen:");
            exit(EXIT_FAILURE);
        }
    
        // Write the output of the command to the console.
        while(fgets(buf, sizeof(buf), in) != NULL)
    
        int pcloseRetVal = pclose(in); // wait for process to finish.
        // If grep returned anything then a connection still exists
        if (strlen(buf) > 0) {
            return true;
        } else {
            return false;
        }
    }
    
    void InfoData::disablewifi()
    {
        // "ssid" determined elsewhere (statically set for now)
        QString disconnectCommand = "nmcli connection down id " + ssid;
        QProcess::execute(disconnectCommand);
    }
    
    
    1 Reply Last reply
    0
    • S Offline
      S Offline
      sierdzio
      Moderators
      wrote on 14 Apr 2022, 09:08 last edited by
      #2

      I've implemented this by adding sleeps in between the calls

      This will likely cause crashes.

      QML and main thread communicate frequently and relay on queued signal connections. If you disrupt them with sleeps, all sorts of weird stuff can start happening (been there, done that ;) ).

      Avoid using sleep/msleep etc., also avoid semi-blocking the main thread with QProcess::execute(). Better use non-static methods and rely on finished() and readyRead() signals.

      Same goes for your getwifiStatus() method.

      (Z(:^

      1 Reply Last reply
      3

      1/2

      13 Apr 2022, 23:26

      • Login

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