Showing posts with label Debugging. Show all posts
Showing posts with label Debugging. Show all posts

Thursday, 22 February 2018

TrafficControl: Crash for QQuickItem in QDockWidget after Update

After an update of Qt 5.10, TrafficControl crashes when it is setting up the QtQuick/QML widget in the user interface. The program worked fine before the update (2018-01-17) and I have isolated the issue by removing other parts of TrafficControl.

I suspect strongly that changes in Qt 5.10 has made my application crash. After installing Qt 5.9.3, the program works fine with that version.

If I remember, I'll post updates on this topic when there are news/fixes about this issue.

Friday, 11 August 2017

TrafficControl: Protecting the Code

After reaching the milestone in the second last blog post, I've done some refactoring of the code to make it cleaner and simpler to maintain:
  • Reviewing parameter names
  • Adding Doxygen comments
  • Replacing STL vectors with QLists
  • Calling the QML JavaScript functions directly
The next step will be to introduce automated tests. This is crucial to protect trafficControl from new and existing bugs.

Initially, I'll learn how to use the test framework in Qt Test. After that, I'll focus on some areas:
  • How to reset the traffic network between different tests
  • Module testing - to verify the modules/functions
  • Input files - how to detect problems in the network definition files
  • Useability/User Interfaces
  • Test-Driven Development - Mainly for different traffic scenarios
  • Performance Testing/Optimization 
  • Memory leak tests

Thursday, 20 April 2017

TrafficControl: Refactoring the Train::move() function

There are some issues with the code in the tcTrain part of the program. The code needs to be refactored and when the train has reached the end of the TravelPlan, it is still looking for the next station.

Since the bug was easy to spot and fix, I've solved that first before refactoring. If I would have considered the bug to be difficult to solve, I would have considered refactoring first and debugging later.

The tcTrain::move() method covers some 170 lines of code that needs to be broken up to different methods.

First, I'll review the existing methods for tcTrain:


The tcTrain:move() method is based on some different states:


That method will call some new methods:

  • tcTrain;:waitingState
  • tcTrain::readyState
  • tcTrain::runningState
  • tcTrain::openingState
  • tcTrain::loadingState
  • tcTrain::closingState
  • and also some other helper methods/functions.

I'll remove the method tcTrain::getRouteVectorTracks().

The first step will be porting the code to the new methods without breaking anything...

Sunday, 2 April 2017

TrafficControl: Debugging Train::move Method (part 2)

After re-testing with more debug prints, I've made an observation:

INFO : TRAIN SET MODEL recognised with Model= "X41" . To be implemented!
INFO : TRAIN SET STATION recognised with Station= "Lund_C" . Check that the station exists.
INFO : TRAIN SET DESIRED SPEED recognised with DesiredSpeed= "145"
IMPORT : "Gunnesbo" found. Adding to travelplan
ERROR : Train::addTrackToTrainRoute Error: negative number specified. 0 : "Gunnesbo"<<The stationID 0 is a valid ID.
INFO : "Marie_Curie" has 100 seats. 0 are taken.
: Train is at station "Lund_C"
: TrainRoute, index: 0 :

The program shall check whether the stationID is smaller than zero (invalid value). The bug is that the program is checking whether the stationID is smaller or equal to zero. The new condition is (stationID < 0)


Another issue has been seen: The check for end of travel plans doesn't seem to work:

INFO : "Ada_Lovelace" has reached end of travelplan. tp_s : 2 pos: 1<<For this particular event, the train hasn't reached the end of the travel plan.
INFO : "Marie_Curie" has reached end of travelplan. tp_s : 2 pos: 1
INFO : "Marie_Curie" has reached end of travelplan. tp_s : 2 pos: 1

This new issue will be debugged in a later blog post.

Tuesday, 28 March 2017

TrafficControl: Debugging Train::move Method (part 1)

The bug is that the trains seems not to follow their Travel Plans. A Travel Plan is a list of adjacent stations that the train shall visit before the train stops.

For the network file "Network_LundSuburb-ThreeTrains", the program seems to work. The three trains follow their travel plans.
  • Hedy_Lamarr shall start in Hjärup -> Lund -> Gunnesbo -> Lund -> Stangby (STOP)
  • Ada_Lovelace shall start in Gunnesbo->Lund -> Stångby (STOP)
  • Marie_Curie shall start in Lund -> Gunnesbo -> Lund (STOP)
Time Hedy_Lamarr Ada_Lovelace Marie_Curie Comment
0 Hjärup Gunnesbo Lund
1 HjaLunN GunLunS LunGunN
2 HjaLunN Lund Gunnesbo
3 HjaLunN LunStaN GunLunS
4 Lund LunStaN GunLunS
5 LunGunN LunStaN LunGunS
6 LunGunN LunStaN Lund (Stop)
7 Gunnesbo LunStaN Lund (Stop)
8 LunGunS Stangby (Stop) Lund (Stop)
9 Lund Stangby (Stop) Lund (Stop)
10 LunStaN Stangby (Stop) Lund (Stop)
11 Stangby (Stop) Stangby (Stop) Lund (Stop) Expected behavior


When using a network file with tracks in both directions, (Lund_Coordinates.txt), the program warns that it can't add tracs to Travel Plans:

INFO : Adding track to trainroute << Need to print what station to add. The first station (LundC) was added!
INFO : "Hedy_Lamarr" has 100 seats. 0 are taken.
: Train is at station "Hjaerup"
: TrainRoute, index: 0 :
2 : "Lund_C"
^ Current ^
ERROR : Train::addTrackToTrainRoute Error: negative number specified. <<Why wasn't the program able to addGunnesbo?

INFO : "Hedy_Lamarr" has 100 seats. 0 are taken.
: Train is at station "Hjaerup"
: TrainRoute, index: 0 :
2 : "Lund_C"
^ Current ^
INFO : Adding track to trainroute <<This time, LundC was added to travelPlan. The program isn't designed to handle two consecutive entries of the same station in TravelPlan
INFO : "Hedy_Lamarr" has 100 seats. 0 are taken.
: Train is at station "Hjaerup"
: TrainRoute, index: 0 :
2 : "Lund_C"
^ Current ^
2 : "Lund_C"<< Hjaerup should have been before LundC in the travelPlan
INFO : Adding track to trainroute << Staangby was added to travelPlan
INFO : "Hedy_Lamarr" has 100 seats. 0 are taken.
: Train is at station "Hjaerup"
: TrainRoute, index: 0 :
2 : "Lund_C"
^ Current ^
2 : "Lund_C"
3 : "Staangby"


For the train Ada_Lovelace, that issue wasn't seen. For the train Marie_Curie, the issue came when adding Gunnesbo station to the travelPlan. In the network file, the Gunnesbo station seems to be ok.

In the next blog post, I'll add extra prints to show what happens when trying to add Gunnesbo station to travel plans.


Saturday, 18 October 2014

Qt: ...and one way to succeed rebuilding Qt to enable static builds!

Finally, just before giving up, I found this article:
http://qt-project.org/wiki/How-to-build-a-static-Qt-for-Windows-MinGW

After securing that I had Powershell and 7-zip installed, I downloaded the script and started the build process again over the work day. After some reconfigurations, where I specified where Qt creator should look for the compiler, I was finally able to create static executables (16 Mb)!

Wednesday, 1 October 2014

|| AND &&: Why it is a good idea to quibble

I had to recover my Windows 8 installation one week ago, and in that process, I re-installed Qt. This time, I also included the Microsoft Visual Studio Express compiling option for Qt.

After doing that, I tried to rebuild my programs TrafficControl and StockReader. I got houndreds of strange compiler errors that I didn't expect since the programs compiled without warnings before.

The issue was that I used the keywords "and" and "or" in several if clauses. Those keywords are allowed by gcc/g++ (GNU Compiler Collection), but not by Microsoft Visual Studio 2013: http://msdn.microsoft.com/en-us/library/2e6a4at9.aspx

My personal preference would have been to use AND and OR for logical keywords - that would have kept my source code as similar to human language as possible. But I also want my source code to be portable between different operating systems and compilers. So from now on, I'll continue with using the ||, && and != operators instead of OR, AND and NOT.

I still have some problems making static builds for  my programs. More about that in future blog posts.

Wednesday, 16 July 2014

TrafficControl: Thread running after closing window [Solved]

When I introduced threads to the program, I also introduced a problem: the thread didn't terminate when I closed the User Interface. Instead, it carried on after calling the terminate() method and I saw that the thread was still active in the console output, after closing the main program. When closing the console application manually, the console created an error message:

The program has unexpectedly finished.

The problem came, even if I used

    QThread clockThread;
    TrafficClock trafficClock;
    trafficClock.threadSetup(clockThread);
    trafficClock.moveToThread(&clockThread);
    clockThread.start();

ClockThread implementation:
    for(int iii=0;iii<100000;iii++)
    {
        if(continueTick==true)
        {
            emit stepTimeSignal();
        }
        QThread::msleep(333);
    }

When trying to kill the thread, the thread just continued:

    clockThread.terminate();
    while(!clockThread.isFinished()){}
This came even if I used quit() and exit().
After some investigations, I found that the thread wasn't terminated until the work in the thread was done. With this information, I was able to kill the thread by using a local variable isAlive:
    while(isActive==true)
    {
        for(int iii=0;iii<100000;iii++)
        {
            if(continueTick==true)
            {
                emit stepTimeSignal();
            }
        }
        QThread::msleep(333);
    }

Now, I was able to break the loop by setting isAlive to false, and to terminate the thread properly.

Why all the fuss about a thread still running after closing the program? As this program gets more complex, so will the bugs. Small glitches in the code will give me complex problems in the future, and I need to avoid it as soon as possible.

Also:
There are disagreements in the Qt community about how to implement threads. 
  • Subclass the worker klass from Thread, create a object with new for the thread and use the start() method to start the thread. This approach is recommended by the official QT documentation
  • Instead, I create a normal object and I move it to a thread.
You can follow the discussion below