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 Update on Monday, May 27th 2025

Statemachine crashes with SIGBUS while stopping

Scheduled Pinned Locked Moved Solved General and Desktop
3 Posts 2 Posters 203 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