Results 1 to 3 of 3

Thread: QStateMachine does not start up in Windows/Linux RELEASE build, DEBUG build is fine

  1. #1
    Join Date
    Nov 2010
    Posts
    122
    Thanks
    62
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Wink QStateMachine does not start up in Windows/Linux RELEASE build, DEBUG build is fine

    I am uisng a QStateMachine in a multithreaded console based application that executes
    under Windows and Linux, both 32 and 64-bit. The DEBUG build works fine, while in the
    RELEASE build, the state machine fails to execute properly. This is true for both the
    windows and Linux platforms. I have a file trace capability, and I am not able to enter into
    the root state of the state machine at all. The secondary threads in the application all seem to
    work, and there is no apparent problem viewable in terms of inappropriate linked libraries or
    console output suggesting any build or runtime issues or links.

    I have verified the dependencies to be correct. The necessary Qt libraries (console and library)
    as on the path. All seems well with the application other than the state machine never starts
    up in the RELEASE mode. This behavior is true under Windows XP, 7 and Linux Fedora 64-bit, so there
    must be something I am doing wrong.

    I am interested in any suggestions folks might have to try and determine what the issue might be.

    Attached is the source code for the QStateMachine related lines of code.


    My application is derived from QCoreApplication, and the c'tor is as follows

    Qt Code:
    1. App::App(int &argc, char **argv, int ver) :
    2. QCoreApplication(argc, argv),
    3. m_appName(""),
    4. m_appPath(""),
    5. m_stateNumber(unknown),
    6. m_roleID(""),
    7. m_ftpTimeoutMs(5000),
    8. m_tmaMode(eTmaModeStandalone),
    9. m_pXmlParserSettings(0),
    10. m_pSettings(0),
    11. m_bit(false),
    12. m_configured(false),
    13. m_running(false),
    14. ...
    15. {
    16. TRACE();
    17.  
    18. Q_UNUSED(ver);
    19.  
    20. // Create state machine states
    21. m_machine = new QStateMachine(this);
    22. m_stateRoot = new QState();
    23. m_stateInitialize = new QState(m_stateRoot);
    24. m_stateConfiguring = new QState(m_stateRoot);
    25. m_stateUnconfigured = new QState(m_stateRoot);
    26. m_stateRunning = new QState(m_stateRoot);
    27. m_stateIdle = new QState(m_stateRoot);
    28. m_stateInitiatedBIT = new QState(m_stateRoot);
    29. m_stateDone = new QFinalState();
    30. }
    To copy to clipboard, switch view to plain text mode 

    Prior to calling a.exec(), I perform the following to prepare and execute the state machine

    Qt Code:
    1. bool App::aboutToExec(xmlParserSettings *pXmlParserSettings, Settings* pSettings)
    2. {
    3. TRACE();
    4.  
    5. FILE_LOG(logINFO) << "App: created: thread id = " << QThread::currentThreadId();
    6.  
    7. // Save off pointers to local XML file parser and content
    8. m_pXmlParserSettings = pXmlParserSettings;
    9. m_pSettings = pSettings;
    10.  
    11. // Check for multiple instances of lmd
    12. QStringList listOfPids;
    13. int countOfProcesses = System::getProcessIdsByProcessName(szLmdProgramName, listOfPids);
    14. if (countOfProcesses > 1)
    15. {
    16. FILE_LOG(logERROR) << "Only one instance of the Link Manager can run at the same time";
    17. return false;
    18. }
    19.  
    20. // Process contents of the local configuration XML file
    21. processLocalSettings(pSettings);
    22.  
    23. // Process command line arguments (will override local XML file settings)
    24. if (!parseArgs())
    25. {
    26. return false;
    27. }
    28.  
    29. // Allow user to ask for help without being root, but must be root hereafter
    30. #ifdef Q_OS_LINUX
    31. if (geteuid() != 0)
    32. {
    33. // NOTE: SNMP Subagent connection and PTP operation when controlled requires root privilege
    34. FILE_LOG(logERROR) << "Link Manager requires ROOT permisssions to execute";
    35. printf("Link Manager requires ROOT permisssions to execute\n");
    36. return false;
    37. }
    38. #endif
    39.  
    40. // Perform lazy initialization of singletons prior to thread execution (to ensure thread safe creation)
    41. pSnmpInterface->onReset(restoreDefaults);
    42. pMdlInterface->onReset(restoreDefaults);
    43. pPtpdInterface->onReset(restoreDefaults);
    44. pRfnmProcessor->onReset(restoreDefaults);
    45.  
    46. // Create state machine content
    47. FILE_LOG(logINFO) << "INIT: Creating state machine...";
    48.  
    49. // Hook up state entry and exit routines (TODO: remove some of these if eventually not used)
    50. Q_ASSERT(QObject::connect(m_stateRoot, SIGNAL(entered()), this, SLOT(onStateRootEntered())));
    51. Q_ASSERT(QObject::connect(m_stateRoot, SIGNAL(exited()), this, SLOT(onStateRootExited())));
    52. Q_ASSERT(QObject::connect(m_stateInitialize, SIGNAL(entered()), this, SLOT(onStateInitializeEntered())));
    53. Q_ASSERT(QObject::connect(m_stateInitialize, SIGNAL(exited()), this, SLOT(onStateInitializeExited())));
    54. Q_ASSERT(QObject::connect(m_stateConfiguring, SIGNAL(entered()), this, SLOT(onStateConfiguringEntered())));
    55. Q_ASSERT(QObject::connect(m_stateConfiguring, SIGNAL(exited()), this, SLOT(onStateConfiguringExited())));
    56. Q_ASSERT(QObject::connect(m_stateUnconfigured, SIGNAL(entered()), this, SLOT(onStateUnconfiguredEntered())));
    57. Q_ASSERT(QObject::connect(m_stateUnconfigured, SIGNAL(exited()), this, SLOT(onStateUnconfiguredExited())));
    58. Q_ASSERT(QObject::connect(m_stateRunning, SIGNAL(entered()), this, SLOT(onStateRunningEntered())));
    59. Q_ASSERT(QObject::connect(m_stateRunning, SIGNAL(exited()), this, SLOT(onStateRunningExited())));
    60. Q_ASSERT(QObject::connect(m_stateIdle, SIGNAL(entered()), this, SLOT(onStateIdleEntered())));
    61. Q_ASSERT(QObject::connect(m_stateIdle, SIGNAL(exited()), this, SLOT(onStateIdleExited())));
    62. Q_ASSERT(QObject::connect(m_stateInitiatedBIT, SIGNAL(entered()), this, SLOT(onStateInitiatedBITEntered())));
    63. Q_ASSERT(QObject::connect(m_stateInitiatedBIT, SIGNAL(exited()), this, SLOT(onStateInitiatedBITExited())));
    64. Q_ASSERT(QObject::connect(m_stateDone, SIGNAL(entered()), this, SLOT(onStateDoneEntered())));
    65. Q_ASSERT(QObject::connect(m_stateDone, SIGNAL(exited()), this, SLOT(onStateDoneExited())));
    66.  
    67. // Set initial state of root state with common exit for all children states
    68. m_stateRoot->setInitialState(m_stateInitialize);
    69.  
    70. // Make done state the transition target for application exit from any state
    71. Q_ASSERT(m_stateRoot->addTransition(this, SIGNAL(aboutToQuit()), m_stateDone) != 0);
    72.  
    73. // Add states to machine
    74. m_machine->addState(m_stateRoot);
    75. m_machine->addState(m_stateDone);
    76.  
    77. // Add state transitions:
    78.  
    79. // Transition from stateInitialize to stateUnconfigured after initialization. This ensures SNMP
    80. // thread is active to send out traps
    81. //Q_ASSERT(m_stateInitialize->addTransition(m_stateInitialize, SIGNAL(entered()), m_stateUnconfigured) != 0);
    82. Q_ASSERT(m_stateInitialize->addTransition(this, SIGNAL(initializationDone()), m_stateUnconfigured) != 0);
    83.  
    84. // SNMP configured() signal responsive states
    85. Q_ASSERT(m_stateUnconfigured->addTransition(pSnmpInterface, SIGNAL(configured()), m_stateConfiguring) != 0);
    86. Q_ASSERT(m_stateUnconfigured->addTransition(this, SIGNAL(configurationSucceeded()), m_stateIdle) != 0); // MDL file load at boot
    87. Q_ASSERT(m_stateIdle->addTransition(pSnmpInterface, SIGNAL(configured()), m_stateConfiguring) != 0);
    88. Q_ASSERT(m_stateRunning->addTransition(pSnmpInterface, SIGNAL(configured()), m_stateConfiguring) != 0);
    89.  
    90. // Configuration success or failure internal signals from Configuring state
    91. Q_ASSERT(m_stateConfiguring->addTransition(this, SIGNAL(configurationSucceeded()), m_stateIdle) != 0);
    92. Q_ASSERT(m_stateConfiguring->addTransition(this, SIGNAL(configurationFailed()), m_stateUnconfigured) != 0);
    93.  
    94. // SNMP bitInitiated() signal responsive states
    95. // NOTE: call setBitReturnState in each state entry to specify return state from BIT
    96. Q_ASSERT(m_stateUnconfigured->addTransition(pSnmpInterface, SIGNAL(bitInitiated()), m_stateInitiatedBIT) != 0);
    97. Q_ASSERT(m_stateConfiguring->addTransition(pSnmpInterface, SIGNAL(bitInitiated()), m_stateInitiatedBIT) != 0);
    98. Q_ASSERT(m_stateIdle->addTransition(pSnmpInterface, SIGNAL(bitInitiated()), m_stateInitiatedBIT) != 0);
    99. Q_ASSERT(m_stateRunning->addTransition(pSnmpInterface, SIGNAL(bitInitiated()), m_stateInitiatedBIT) != 0);
    100.  
    101. // Transition to and from run state
    102. Q_ASSERT(m_stateIdle->addTransition(pRfnmProcessor, SIGNAL(run()), m_stateRunning) != 0);
    103. Q_ASSERT(m_stateRunning->addTransition(pRfnmProcessor, SIGNAL(stop()), m_stateIdle) != 0);
    104.  
    105. // SNMP reset() responsive states
    106. Q_ASSERT(m_stateConfiguring->addTransition(pSnmpInterface, SIGNAL(reset()), m_stateInitialize) != 0);
    107. Q_ASSERT(m_stateUnconfigured->addTransition(pSnmpInterface, SIGNAL(reset()), m_stateInitialize) != 0);
    108. Q_ASSERT(m_stateRunning->addTransition(pSnmpInterface, SIGNAL(reset()), m_stateInitialize) != 0);
    109. Q_ASSERT(m_stateIdle->addTransition(pSnmpInterface, SIGNAL(reset()), m_stateInitialize) != 0);
    110. Q_ASSERT(m_stateInitiatedBIT->addTransition(pSnmpInterface, SIGNAL(reset()), m_stateInitialize) != 0);
    111.  
    112. // SNMP set epoch
    113. Q_ASSERT(QObject::connect(pSnmpInterface, SIGNAL(setEpochMicroseconds(unsigned int)), this, SLOT(setEpochMicroseconds(unsigned int))));
    114.  
    115. // Connect state machine exit to application exit
    116. Q_ASSERT(QObject::connect(m_machine, SIGNAL(finished()), this, SLOT(quit())));
    117.  
    118. // Start up state machine
    119. m_machine->setInitialState(m_stateRoot);
    120. m_machine->start();
    121.  
    122. // Create processes and secondary thread objects (TODO: add others here)
    123.  
    124. .
    125. .
    126. .
    127. // Create secondary threads (TODO: add others here)
    128. FILE_LOG(logINFO) << "INIT: Creating secondary threads...";
    129. m_snmpSubAgentThread = new SnmpSubAgentThread(0);
    130. m_tdmaThread = new TdmaThread(0);
    131.  
    132. // Start up secondary threads (TODO: add others here)
    133. FILE_LOG(logINFO) << "INIT: Starting secondary threads...";
    134. m_snmpSubAgentThread->start(QThread::NormalPriority);
    135.  
    136. return true;
    137. }
    To copy to clipboard, switch view to plain text mode 

    Interested in ways to debug the RELEASE build.

  2. #2
    Join Date
    Dec 2009
    Posts
    128
    Thanks
    7
    Thanked 14 Times in 14 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QStateMachine does not start up in Windows/Linux RELEASE build, DEBUG build is fi

    Q_ASSERT() body is not compiled in release mode (if i'm right) so the connects will not execute, as well as any statement inside it.
    Last edited by totem; 3rd October 2011 at 22:35.

  3. #3
    Join Date
    Nov 2010
    Posts
    122
    Thanks
    62
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Cool Re: QStateMachine does not start up in Windows/Linux RELEASE build, DEBUG build is fi

    Thanks, that was it, I was looking in the wrong place, I was thinking that Q_ASSERT acted more like a verify setting that was applicable to both DEBUG and RELEASE.
    I could not see the forest for the trees, was infected with brain dumbness.

Similar Threads

  1. Replies: 5
    Last Post: 14th April 2011, 19:10
  2. Compile Qt 4.6.2 with VS2008 - exception in release build, debug ok
    By LynneV in forum Installation and Deployment
    Replies: 0
    Last Post: 7th June 2010, 04:52
  3. Replies: 3
    Last Post: 3rd December 2009, 16:12
  4. Dialog executes in debug build but not release
    By awhite1159 in forum Qt Programming
    Replies: 5
    Last Post: 24th June 2008, 17:51
  5. build debug with shared and release with static?
    By Thor28 in forum Qt Programming
    Replies: 4
    Last Post: 14th April 2008, 22:32

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.