Tips and tricks

Debugging tests

  • To debug a test, find the test executable:

    • Libs/MRML/Core tests are in the MRMLCoreCxxTests project

    • CLI module tests are in <MODULE_NAME>Test project (e.g. ThresholdScalarVolumeTest)

    • Loadable module tests are in qSlicer<MODULE_NAME>CxxTests project (e.g. qSlicerVolumeRenderingCxxTests)

    • Module logic tests are in <MODULE_NAME>LogicCxxTests project (e.g. VolumeRenderingLogicCxxTests)

    • Module widgets tests are in <MODULE_NAME>WidgetsCxxTests project (e.g. VolumesWidgetsCxxTests)

  • Make the project the startup project (right-click -> Set As Startup Project)

  • Specify test name and additional input arguments:

    • Go to the project debugging properties (right click -> Properties, then Configuration Properties/Debugging)

    • In Command Arguments, type the name of the test (e.g. vtkMRMLSceneImportTest for project MRMLCoreCxxTests)

    • If the test takes argument(s), enter the argument(s) after the test name in Command Arguments (e.g. vtkMRMLSceneImportTest C:\Path\To\Slicer4\Libs\MRML\Core\Testing\vol_and_cube.mrml)

      • You can see what arguments are passed by the dashboards by looking at the test details in CDash.

      • Most VTK and Qt tests support the -I argument, it allows the test to be run in “interactive” mode. It doesn’t exit at the end of the test.

  • Start Debugging (F5)

Debugging memory leaks

See some background information in VTK leak debugging in Slicer3 and Strategies for Writing and Debugging Code in Slicer3 pages.

  1. If you build the application from source, make sure VTK_DEBUG_LEAKS CMake flag is set to ON. Slicer Preview Releases are built with this flag is ON, while in Slicer Stable Releases the flag is OFF.

  2. Reproduce the memory leak. When the application exits, it logs a message like this:

vtkDebugLeaks has detected LEAKS!
Class "vtkCommand or subclass" has 1 instance still around.
  1. Add the listed classes to the VTK_DEBUG_LEAKS_TRACE_CLASSES environment variable (separated by commas, if there are multiple). For example:

VTK_DEBUG_LEAKS_TRACE_CLASSES=vtkCommand

In Visual Studio, environment variable can be added to SlicerApp project properties -> Debugging -> Environment.

  1. Reproduce the memory leak. It will print the stack trace of the call that allocated the object, which should be enough information to determine which object instance in the code it was. For example:

vtkDebugLeaks has detected LEAKS!
Class "vtkCommand or subclass" has 1 instance still around.

Remaining instance of object 'vtkCallbackCommand' was allocated at:
 at vtkCommand::vtkCommand in C:\D\S4D\VTK\Common\Core\vtkCommand.cxx line 28
 at vtkCallbackCommand::vtkCallbackCommand in C:\D\S4D\VTK\Common\Core\vtkCallbackCommand.cxx line 20
 at vtkCallbackCommand::New in C:\D\S4D\VTK\Common\Core\vtkCallbackCommand.h line 49
 at vtkNew<vtkCallbackCommand>::vtkNew<vtkCallbackCommand> in C:\D\S4D\VTK\Common\Core\vtkNew.h line 89
 at qSlicerCoreApplicationPrivate::init in C:\D\S4\Base\QTCore\qSlicerCoreApplication.cxx line 325
 at qSlicerApplicationPrivate::init in C:\D\S4\Base\QTGUI\qSlicerApplication.cxx line 232
 at qSlicerApplication::qSlicerApplication in C:\D\S4\Base\QTGUI\qSlicerApplication.cxx line 393
 at `anonymous namespace'::SlicerAppMain in C:\D\S4\Applications\SlicerApp\Main.cxx line 40
 at main in C:\D\S4\Base\QTApp\qSlicerApplicationMainWrapper.cxx line 57
 at invoke_main in D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl line 79
 at __scrt_common_main_seh in D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl line 288
 at __scrt_common_main in D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl line 331
 at mainCRTStartup in D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp line 17
 at BaseThreadInitThunk
 at RtlUserThreadStart

Why is my VTK actor/widget not visible?

  • Add a breakpoint in RenderOpaqueGeometry() check if it is called. If not, then:

    • Check its vtkProp::Visibility value.

      • For vtkWidgets, it is the visibility of the representation.

    • Check its GetBounds() method. If they are outside the camera frustrum, the object won’t be rendered.

      • For vtkWidgets, it is the bounds of the representation.

Debugging Slicer application startup issues

See instructions here for debugging application startup issues.

Disabling features

It may help pinpointing issues if Slicer is started with as few features as possible:

  • Disable Slicer options via the command line

    ./Slicer --no-splash --ignore-slicerrc --disable-cli-module --disable-loadable-module --disable-scriptedmodule
    
    • Look at all the possible options On Linux and macOS:

      ./Slicer --help
      

      On Windows:

      Slicer.exe --help | more
      
  • Disable ITK plugins

    • CLI modules silently load the ITK plugins in lib/Slicer-4-13/ITKFactories. These plugins are used to share the volumes between Slicer and the ITK filter without having to copy them on disk.

    • rename lib/Slicer-4.13/ITKFactories into lib/Slicer-4.13/ITKFactories-disabled

  • Disable Qt plugins

    • rename lib/Slicer-4.13/iconengine into lib/Slicer-4.13/iconengine-disabled

Console output on Windows

On Windows, by default the application launcher is built as a Windows GUI application (as opposed to a console application) to avoid opening a console window when starting the application.

If the launcher is a Windows GUI application, it is still possible to show the console output by using one of these options:

Option A. Run the application with capturing and displaying the output using the more command (this captures the output of both the launcher and the launched application):

Slicer.exe --help 2>&1 | more

The 2>&1 argument redirects the error output to the standard output, making error messages visible on the console, too.

Option B. Instead of more command (that requires pressing space key after the console window is full), tee command can be used (that continuously displays the output on screen and also writes it to a file). Unfortunately, tee is not a standard command on Windows, therefore either a third-party implementation can be used (such as wtee) or the built-in tee command in Windows powershell:

powershell ".\Slicer.exe 2>&1 | tee out.txt"

Option C. Run the application with a new console (the launcher sets up the environment, creates a new console, and starts the SlicerApp-real executable directly, which can access this console):

Slicer.exe --launch %comspec% /c start SlicerApp-real.exe

To add console output permanently, the application launcher can be switched to a console application by setting Slicer_BUILD_WIN32_CONSOLE_LAUNCHER CMake variable to ON when configuring the application build.