Wednesday, October 24, 2012

Automatic Building For Debugging

When using Qmake with QtCreator, both Release and Debug builds are configured and it is easy to switch between the two.  CMake supports several build types including Release, Debug, Release With Debug Info and Minimum Size Release.  The default is blank (which is probably similar to Release, but definitely does not turn on debug information).  However, the CMake build types are not directly available in QtCreator except by specifying the CMAKE_BUILD_TYPE variable when running CMake.

During development it is obviously desirable to build the program with debug information.  The CMAKE_BUILD_TYPE variable could simply be set to Debug in the CMakeLists.txt file.  But then this would need to be changed when a release is made, so this is not a good solution.

Instead, the CMakeLists.txt file was setup to look for a CMAKE_BUILD_TYPE environment variable (CMake can access system environment variables).  If this environment variable is set, then the CMake variable is set to the environment variable unless it has already been set.  If the environment variable is not set, it behaves the way is did before.

This environment variable can be set in QtCreator by going to the Projects screen, selecting the Build Settings and adding this environment variable to the Build Environment with the desired Debug value.  The Release With Debug Info (RelWithDebInfo) could also be used, but can make stepping through the program confusing since most of same optimizations are turned on as with Release and the compiler can rearrange statements for efficiency (execution will appear to jump around) or optimize out variables (the values of which cannot be viewed).

[commit 7ee8e7483c]

Finding Memory Leaks (Linux)

QtCreator can be used to find memory leaks using the Analyze mode.  This requires the valgrind program, which can be installed via the valgrind package on Ubuntu based distros.  Unfortunately it looks like this program has not been ported to Windows (MinGW), so Windows developers are out of luck (at least when using MinGW with the Qt SDK).

In order to use valgrind, the program to check must be compiled with debugging information.  To do this with CMake under QtCreator, in the Run CMake dialog, the Arguments line needs to be set to ‑DCMAKE_BUILD_TYPE=Debug.  This is a nuisance because it needs to be done every time CMake is run the first time and there appears to be no way to automate this inside QtCreator.  So an alternate scheme was devised using CMake (will be described in the next post).

Once Analyze mode is selected (by the icon on the side panel or Ctrl+6), the Analyzer panel will appear.  In this panel, the mode needs to be changed from QML Profiler to Valgrind Memory Analyzer.  The program is started using the start (play) icon (left side of Analyzer panel toolbar).  Once the program ends, any memory issues will be reported.

After using the Analyzer to learn about list element deallocation, I thought it might be a good idea to check the ibcp program for any memory issues.  There is already an implementation to detect token memory leaks accomplished by overloading the new and delete operators for the Token structure, but there are many other memory allocation operations in the program.

So this process was started for each parser, expression and translator test.  For each, the run arguments were set (Projects page, Run Settings) and the Analyzer was run.  This were no memory issues on the parser tests, however, some problems were found on the translator tests, which will be discussed in following posts.

List Class Replacement (Begin)

The List class was the first implemented for this project, so it is fitting that it will be the first to be replaced with the transition to Qt.  Qt's list class is named QList.  The functionality is not much different then the home grown List class, though most of the member functions have different names.

The approach being used was to first replace all cases of List with QList and then search for each List class member function name and replace it with QList's version.  In some cases, the code needs to be written a bit since the QList functionality is slightly different.  For example, while QList also has a first() function, it must not be called if the list is empty (must check if it is empty first), while the List class first() function allows for an empty list (returning a null pointer).

The first complication came in how to deallocate items in the QList.  The question was, does this happen automatically when leaving scope, is deleted or via QList's clear() member function.  Neither was the case where the list is a list of pointers to allocated elements.  Each element needs to be deleted (same as the case with the List class).

A small test program was written to evaluate and confirm this behavior.  As part of this evaluation,  a method to detect memory leaks was employed that is kind of built into QtCreator (at least on Linux).  This lead to quite a few detours, which will be the subject of the posts that follow...