Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Statemachine crashes with SIGBUS while stopping
Forum Updated to NodeBB v4.3 + New Features

Statemachine crashes with SIGBUS while stopping

Scheduled Pinned Locked Moved Solved General and Desktop
3 Posts 2 Posters 219 Views
  • 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.
  • K Offline
    K Offline
    Krulle
    wrote on last edited by
    #1

    Hi guys,
    I have a problem with crashing again :)
    The statemachine crashes as soon as i exit it.
    I am using Qt 5.7, cross compiled for a Raspberry Pi 3 with GCC 4.8.

    I have an interface to program two different flows:

    class IintervalMeasurement : public QObject
    {
        Q_OBJECT
    
    protected:
        /*
         * State Machine
         */
        QStateMachine m_stateMachine;
    
        QState *m_mainState{nullptr};
        QState *m_stateTakeMeasurement{nullptr};
        QState *m_stateZeroing{nullptr};
        QState *m_stateStandby{nullptr};
    
        QFinalState *m_abortIntervalMeasurement;
    
        QSharedPointer<StandardDeviceFunctions> m_deviceSpecialFunktions;
        QPointer<QTimer> m_timerUpdateGraphik;
    
        int m_count{0};
    
        IntervalMeasurementParameter m_parameter;
        IintervalMeasurement::statusMeasurement m_lastState;
    
        QList<QObject*> m_listContext;
    
    public:
        virtual void start();
        ~IintervalMeasurement();
    
        IintervalMeasurement::statusMeasurement lastState() const;
        void stopMeasurement();
    
    protected:
        explicit IintervalMeasurement(QSharedPointer<StandardDeviceFunctions> deviceFunctions, QObject *parent = nullptr);
        IintervalMeasurement(QSharedPointer<StandardDeviceFunctions> deviceFunctions, IntervalMeasurementParameter &parameter, QObject *parent = nullptr);
    
        // builder functions
        virtual void setZeroing();
        virtual void setStandby();
    
        virtual void setState(statusMeasurement state);
        virtual void setCyclesLeft();
    
    signals:
        virtual void sig_zeroingReady() = 0;
        virtual void sig_measurementReady() = 0;
    
        virtual void performNullpkt();
        virtual void sig_stopMeasurement();
    
        virtual void sig_measurementBreakReady();
        virtual void sig_MeasurementWithoutZeroing();
    
    protected slots:
        virtual void zeroing() = 0;
        virtual void takeMeasurement() = 0;
        virtual void standby() = 0;
    
        virtual void updateTime();
        virtual void finished();
    private:
        virtual void initStateMachine() = 0;
        void init();
        void setTimeDisplay();
    };
    

    .cpp

    IintervalMeasurement::IintervalMeasurement(QSharedPointer<StandardDeviceFunctions> deviceFunctions, QObject *parent) : QObject(parent)
      , m_mainState(new QState)
      , m_stateTakeMeasurement(new QState(m_mainState))
      , m_abortIntervalMeasurement(new QFinalState)
      , m_deviceSpecialFunktions(deviceFunctions)
      , m_timerUpdateGraphik(new QTimer(this))
    {
        init();
    }
    
    IintervalMeasurement::IintervalMeasurement(QSharedPointer<StandardDeviceFunctions> deviceFunctions, IntervalMeasurementParameter &parameter, QObject *parent) : QObject(parent)
      , m_parameter(parameter)
      , m_mainState(new QState)
      , m_stateTakeMeasurement(new QState(m_mainState))
      , m_abortIntervalMeasurement(new QFinalState)
      , m_deviceSpecialFunktions(deviceFunctions)
      , m_timerUpdateGraphik(new QTimer(this))
    {
        init();
    }
    
    IintervalMeasurement::~IintervalMeasurement()
    {
        qDebug() << Q_FUNC_INFO;
        m_timerUpdateGraphik->stop();
        m_timerUpdateGraphik.clear();
    
        if(m_stateZeroing != nullptr) m_stateZeroing->deleteLater();
        if(m_stateStandby != nullptr) m_stateStandby->deleteLater();
    
        if(m_mainState != nullptr) m_mainState->deleteLater();
        if(m_abortIntervalMeasurement != nullptr) m_abortIntervalMeasurement->deleteLater();
        if(m_stateTakeMeasurement != nullptr) m_stateTakeMeasurement->deleteLater();
    }
    
    void IintervalMeasurement::init()
    {
        m_mainState->setInitialState(m_stateTakeMeasurement);
        m_stateMachine.addState(m_mainState);
    
        m_mainState->addTransition(this, &IintervalMeasurement::sig_stopMeasurement, m_abortIntervalMeasurement);
        m_stateMachine.addState(m_abortIntervalMeasurement);
        m_stateMachine.setInitialState(m_mainState);
    
        connect(m_stateTakeMeasurement, &QState::entered, this, &IintervalMeasurement::takeMeasurement);
        connect(m_timerUpdateGraphik.data(), &QTimer::timeout, this, &IintervalMeasurement::updateTime);
        connect(&m_stateMachine, &QStateMachine::finished, this, &IintervalMeasurement::finished);
    }
    
    void IintervalMeasurement::stopMeasurement()
    {
        qDebug() << Q_FUNC_INFO << "1";
        emit sig_stopMeasurement();
        qDebug() << Q_FUNC_INFO << "2";
    }
    
    void IintervalMeasurement::start()
    {
        m_count = 0;
        m_timerUpdateGraphik->start(1000);
        DI_Pointer::Instance().getService<VarioluxxIntervalMeasurementPropertys>()->setMeasurementActivated(true);
        setCyclesLeft(); // init
        m_stateMachine.start();
    }
    

    First implementation of the interface:

    class IntervalMeasurement : public IintervalMeasurement
    {
        Q_OBJECT
    
    public:
        explicit IntervalMeasurement(QSharedPointer<StandardDeviceFunctions> deviceFunctions, QObject *parent = nullptr);
        IntervalMeasurement(QSharedPointer<StandardDeviceFunctions> deviceFunctions, IntervalMeasurementParameter & parameter, QObject *parent = nullptr);
        ~IntervalMeasurement() override;
    
    signals:
        // State machine signals for transistions
        void sig_standbyReady();
        void sig_zeroingReady() override;
        void sig_measurementReady() override;
    
    protected slots:
        void standby() override;
        void takeMeasurement() override;
        void zeroing() override;
    
    private:
        void initStateMachine() override;
    };
    

    .cpp

    IntervalMeasurement::IntervalMeasurement(QSharedPointer<StandardDeviceFunctions> deviceFunctions, QObject *parent) : IintervalMeasurement(deviceFunctions, parent)
    {
        initStateMachine();
    }
    
    IntervalMeasurement::IntervalMeasurement(QSharedPointer<StandardDeviceFunctions> deviceFunctions, IntervalMeasurementParameter &parameter, QObject *parent) : IintervalMeasurement(deviceFunctions, parameter, parent)
    {
        initStateMachine();
    }
    
    IntervalMeasurement::~IntervalMeasurement()
    {
    
    }
    
    void IntervalMeasurement::initStateMachine()
    {
        setStandby();
        setZeroing();
    
        // transitions
        m_stateTakeMeasurement->addTransition(this, &IntervalMeasurement::sig_measurementReady, m_stateStandby);
        m_stateStandby->addTransition(this, &IntervalMeasurement::sig_standbyReady, m_stateZeroing);
        m_stateZeroing->addTransition(this, &IntervalMeasurement::sig_zeroingReady, m_stateTakeMeasurement);
    }
    

    Second implementation of the interface:

    class IntervalMeasurementWithoutStandby : public IintervalMeasurement
    {
        Q_OBJECT
    
        QState *m_stateMeasurementBreak{nullptr};
        QScopedPointer<QTimer> m_timer{new QTimer(this)};
    
    public:
        explicit IntervalMeasurementWithoutStandby(QSharedPointer<StandardDeviceFunctions> deviceFunctions, QObject *parent = nullptr);
        IntervalMeasurementWithoutStandby(QSharedPointer<StandardDeviceFunctions> deviceFunctions, IntervalMeasurementParameter parameter, QObject *parent = nullptr);
        ~IntervalMeasurementWithoutStandby() override;
    
    signals:
        void sig_zeroingReady() override;
        void sig_measurementReady() override;
    
    protected slots:
        void standby() override { } // not used!
        void takeMeasurement() override;
        void zeroing() override;
        void measurementBreak();
    
    private:
        void initStateMachine() override;
    };
    

    .cpp

    IntervalMeasurementWithoutStandby::IntervalMeasurementWithoutStandby(QSharedPointer<StandardDeviceFunctions> deviceFunctions, QObject *parent) : IintervalMeasurement(deviceFunctions, parent)
    {
        initStateMachine();
    }
    
    IntervalMeasurementWithoutStandby::IntervalMeasurementWithoutStandby(QSharedPointer<StandardDeviceFunctions> deviceFunctions, IntervalMeasurementParameter parameter, QObject *parent) : IintervalMeasurement(deviceFunctions, parameter, parent)
    {
        initStateMachine();
    }
    
    IntervalMeasurementWithoutStandby::~IntervalMeasurementWithoutStandby()
    {
        if(m_stateMeasurementBreak != nullptr) m_stateMeasurementBreak->deleteLater();
        m_timer.reset(nullptr);
    }
    
    void IntervalMeasurementWithoutStandby::initStateMachine()
    {
        setZeroing();
        m_stateMeasurementBreak = new QState(m_mainState);
        connect(m_stateMeasurementBreak, &QState::entered, this, &IntervalMeasurementWithoutStandby::measurementBreak);
    
        // set transitions
        m_stateTakeMeasurement->addTransition(this, &IntervalMeasurementWithoutStandby::sig_measurementReady, m_stateMeasurementBreak);
        m_stateMeasurementBreak->addTransition(this, &IntervalMeasurementWithoutStandby::sig_measurementBreakReady, m_stateZeroing);
        m_stateMeasurementBreak->addTransition(this, &IntervalMeasurementWithoutStandby::sig_MeasurementWithoutZeroing, m_stateTakeMeasurement);
        m_stateZeroing->addTransition(this, &IntervalMeasurementWithoutStandby::sig_zeroingReady, m_stateTakeMeasurement);
    
        m_timer->setSingleShot(true);
    }
    

    Then I use a model which takes the signals from the gui:

    class IntervalMeasurementModel : public QObject
    {
        Q_OBJECT
    
        QSharedPointer<StandardDeviceFunctions> m_deviceSpecialFunktions;
        QScopedPointer<IintervalMeasurement> m_intervalMeasurement;
        IntervalMeasurementParameter m_parameter{ IntervalMeasurementParameter(true) };
        bool m_withStandby{true};
    
    public:
        explicit IntervalMeasurementModel(QObject *parent = nullptr);
        ~IntervalMeasurementModel();
    
        Q_INVOKABLE void startMeasurement();
        Q_INVOKABLE void stopMeasurement();
       [....]
    };
    
    
    IntervalMeasurementModel::IntervalMeasurementModel(QObject *parent) : QObject(parent)
      , m_deviceSpecialFunktions(new StandardDeviceFunctions(new IntervalMeasurementStrategy))
    {
        QSettings sett;
        sett.beginGroup("IntervalMeasurement");
    
        m_withStandby = sett.value("standbyAfterBreak", true).toBool();
    }
    
    IntervalMeasurementModel::~IntervalMeasurementModel()
    {
        m_deviceSpecialFunktions.clear();
    }
    
    void IntervalMeasurementModel::startMeasurement()
    {
        if(m_withStandby)
            m_intervalMeasurement.reset(new IntervalMeasurement(m_deviceSpecialFunktions, m_parameter, this));
        else
            m_intervalMeasurement.reset(new IntervalMeasurementWithoutStandby(m_deviceSpecialFunktions, m_parameter, this));
    
        m_intervalMeasurement->start();
    }
    
    void IntervalMeasurementModel::stopMeasurement()
    {
        qDebug() << Q_FUNC_INFO;
        m_intervalMeasurement->stopMeasurement();
    
        qDebug() << "test";
        QTimer::singleShot(1000, [this] {
            m_intervalMeasurement->disconnect();
            qDebug() << "delete pointer";
            m_intervalMeasurement.reset();
            qDebug() << m_intervalMeasurement;
        });
    }
    

    The Statemachine runs through without problems.
    Only when I want to stop the machine while runtime, the machine crashes with the error SIGBUS.
    The exact position is in void IintervalMeasurement::stopMeasurement() {} while the signal emit sig_stopMeasurement(); is sent. I suspect it can no longer find the return address.
    The debugger crashes at the following point (moc_iintervalmeasurement.cpp):

    // SIGNAL 3
    void IintervalMeasurement::sig_stopMeasurement()
    {
        QMetaObject::activate(this, &staticMetaObject, 3, Q_NULLPTR);
    }
    

    Does anyone have an idea where the error is?
    I almost suspect that it has to do with the interface class but cannot find an error
    Thank you very much!

    1 Reply Last reply
    0
    • J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by
      #2

      @Krulle said in Statemachine crashes with SIGBUS while stopping:

      signals:
      // State machine signals for transistions
      void sig_standbyReady();
      void sig_zeroingReady() override;

      virtual signals are a big red NONO because the function implementation is done by moc


      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.

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

        @Krulle said in Statemachine crashes with SIGBUS while stopping:

        signals:
        // State machine signals for transistions
        void sig_standbyReady();
        void sig_zeroingReady() override;

        virtual signals are a big red NONO because the function implementation is done by moc

        K Offline
        K Offline
        Krulle
        wrote on last edited by
        #3

        @J-Hilk said in Statemachine crashes with SIGBUS while stopping:

        virtual signals are a big red NONO because the function implementation is done by moc

        Shame on me.
        Of course you are right.
        I stumbled across the same problem a year ago, but was able to solve it relatively quickly. But I forgot about it. It's quite tricky at this point. I'll remember it and it won't happen again.
        The problem only took me 3 evenings.
        Thanks for your quick help :)

        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