[SOLVED]QT 5.2.1 crash on QString::arg(QString const&, QString const&)



  • sometimes my application crashes, i'm using google breakpad as crash reporting system and this is the result of the dump:
    @
    ...
    8 MyApp!QString::arg(QString const&, QString const&) const [qstring.h : 796 + 0x2d]
    eip = 0x080658c1 esp = 0xbfce0c70 ebp = 0xbfce0c98
    Found by: stack scanning
    9 MyApp!MainWindow::updateGrafica() [mainwindow.cpp : 1647 + 0x26]
    eip = 0x080f0548 esp = 0xbfce0ca0 ebp = 0xbfce0e68 ebx = 0x082acff4
    Found by: call frame info
    10 MyApp!MainWindow::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) [moc_mainwindow.cpp : 295 + 0xb]
    eip = 0x08164aae esp = 0xbfce0e70 ebp = 0xbfce0ea8 ebx = 0x082acff4
    esi = 0x097d4b08
    Found by: call frame info
    ....
    @

    these are the source files:
    mainwindow.cpp
    mUtility.h
    mUtility.cpp
    plcCommunication.h
    plcCommunication.cpp

    @
    //FILE --> mainwindow.cpp
    ...
    #include "mUtility.h"
    #include "plcCommunication.h"
    ...

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);

    ...
    if(plc.initConnection()){
        qDebug() << "connected!!!";
        QThread::msleep(1000);
        plc.start(QThread::HighestPriority);
    }else{
        qDebug() << "not connected!!!";
    }
    ....
    tGrafica = new QTimer(this);
    connect(tGrafica, SIGNAL(timeout()), this, SLOT(updateGrafica()));
    
    tGrafica->start(100);
    ...
    

    }

    void MainWindow::updateGrafica(){
    ...
    for(int trs= 0; trs < 2; ++trs){
    QLineEdit *l = this->findChild<QLineEdit *>(QString("txtTrs%1State").arg(trs));
    l->setText(QString("%1 : %2").arg(QString::number(myUtility.stTrs[trs].iState), myUtility.stTrs[trs].sState)); //CRASH !!! -- LINE: 1647
    }
    ...
    }


    FILE --> mUtility.h

    #ifndef MUTILITY_H
    #define MUTILITY_H
    ....
    class mUtility : public QObject
    {
    Q_OBJECT

    public:

    mUtility(QObject *parent = 0);
    ~mUtility();
    
    struct trsGB{
        ...
        int iState;
        QString sState;
        ...
    };
    trsGB stTrs[2];
    ...
    

    };

    extern mUtility myUtility;

    #endif // MUTILITY_H


    FILE --> mUtility.cpp

    #include "mUtility.h"
    ...

    mUtility myUtility;

    mUtility::mUtility(QObject *parent)
    : QObject(parent)
    {
    Init();
    }


    FILE --> plcCommunication.h

    #ifndef PLCCOMMUNICATION_H
    #define PLCCOMMUNICATION_H

    #include <QThread>
    ...

    class PlcCommunication : public QThread
    {
    Q_OBJECT
    public:

    PlcCommunication(QObject *parent = 0);
    ~PlcCommunication();
    ...
    

    };

    extern PlcCommunication plc;


    FILE --> plcCommunication.cpp

    #include "plcCommunication.h"
    #include "mUtility.h"
    ...

    PlcCommunication plc;

    PlcCommunication::PlcCommunication(QObject *parent)
    : QThread(parent)
    {
    ....
    }

    PlcCommunication::~PlcCommunication(){

    }

    bool PlcCommunication::initConnection(){
    ....
    }

    void PlcCommunication::run(){

    while(!bQuit){
         ....
         myUtility.stTrs[0].iState = 300;
         myUtility.stTrs[0].sState = "state: 300";
         ....
         myUtility.stTrs[1].iState = 550;
         myUtility.stTrs[1].sState = "state: 550";
         ....
    }
    

    }
    @

    can anyone help me?



  • Try to use two arg() calls
    @
    l->setText(QString("%1 : %2")
    .arg(myUtility.stTrs[trs].iState)
    .arg(myUtility.stTrs[trs].sState));
    @



  • QString QString::arg(const QString & a1, const QString & a2) const
    This function overloads arg().
    This is the same as str.arg(a1).arg(a2), except that the strings a1 and a2 are replaced in one pass. This can make a difference if a1 contains e.g. %1:
    @QString str;
    str = "%1 %2";

    str.arg("", "Hello"); // returns " Hello"
    str.arg("").arg("Hello"); // returns "Hellof %2"@



  • Is it possible that updateGrafica() is called before
    myUtility.stTrs[0] and myUtility.stTrs[1] are initialized?



  • no it's not possible and the crashes are rare and random. could be a synchronization issue?



  • Yes it is possible that your timer slot and PlcCommunication have a race condition. Protect myUtility.stTrs and check if crashes will stop.



  • i have to use a QMutex or a QReadWriteLock or using volatile?



  • I would use QReadWriteLock.
    volatile will not help here.



  • i have to put a QReadWriteLock for every variable ?



  • I would create a QReadWriteLock variable in mUtility class then I would create a setter and a getter for myUtility.stTrs and use QReadLocker in the getter and QWriteLocker in the setter.

    Then change your while loop to modify myUtility.stTrs through the setter and change MainWindow::updateGrafica() to retreive myUtility.stTrs through the getter.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.