Address Sanitizer / Consume ITK as Source Code

Hello,

This is a question where I feel I don’t know quite enough to ask the right question, so if I’m doing it wrong feel free to enlighten me.

I recently discovered the joy of Address Sanitizer for debugging memory issues (which I sadly still make). The problem with Address Sanitizer is that all your code has to be compiled with it, but it entails a significant performance hit (https://github.com/google/sanitizers/wiki/AddressSanitizerPerformanceNumbers) which means you don’t want to leave it on all the time. If you don’t compile and link all code with Address Sanitizer, then it will hit false positives almost immediately upon program start (often in std::!).

My approach in projects where everything is compiled from source is to add the following in CMakeLists:

set(USE_ASAN $<$<CONFIG:RelWithDebInfo>:-fsanitize=address>)
target_compile_options(Project PRIVATE ${USE_ASAN})
target_link_options(Project PRIVATE ${USE_ASAN})

I then mostly develop in Release mode, and if I hit a problem I recompile in RelWithDebInfo.

This doesn’t work well in projects with an externally compiled library - e.g. ITK. If I want to take this approach, I either have to remember to go off and rebuild ITK with Address Sanitizer, or I need to keep two copies of ITK compiled, one with Address Sanitizer and one without, and swap which one I’m linking to in my project based on the build type.

I think I could make the second approach work, but then I started wondering whether it is actually possible to consume ITK purely as source-code in my project? I.e. don’t build ITK as a separate library then link it to my project, but build it all within my project as a single step? I am aware that this may not be optimal either, as every time I switch between Release and RelWithDebInfo it will require rebuilding a lot of files. But given ITK is a lot of template header code anyway, this may not be so bad.

Does anyone have any opinions on how best to approach this? Thanks in advance.

Hello @spinicist,

I suspect this is a use case for a CMake Superbuild so that your itk is configured in the same way as your general project, passing the flags to the ITK build.

It sounds like you want a super-build. Some ready-to-steal examples of a super-build are PlusBuild and Slicer.

Thanks both.

Super-Builds are an odd one. I don’t think they are widely used outside of the ITK sphere? ANTs is the only project I’ve actually encountered one on before now. I’ve been put off them because they seem like yet another layer of complication for a C++ build. I guess the root cause of this is the lack of proper package management system in C++?

I found a minimal example which looks easier to work with than PlusBuild or Slicer: https://github.com/Sarcasm/cmake-superbuild. However I’m also tempted to look into conan or another package manager as well, if I find the time.

If another example will help, SimpleITK also uses a Superbuild to build ITK:

It’s a little different in that the top level CMakeLists.txt is a normal project. But if you configure with the “Superbuild” directory, then it build ITK and SWIG.

In my experience, the most efficient approach for this use case is to keep two build trees around and switch as needed.

2 Likes

@matt.mccormick In terms of minimising compile-time, I think you are right. The question is whether there is a way to write my CMakeLists.txt (in my project) to pick the ITK directory depending on the build type, rather than having to change a variable manually. Otherwise I’ll forget to change it!

@spinicist yes. In practice, it is nice to have dedicated build configurations, including for the project, e.g.

ITK-Release-build/
MyProject-Release-build/

ITK-RelWithDebInfo-build/
MyProject-RelWithDebInfo-build/

Then, switch to the dedicated project MyProject-RelWithDebInfo-build tree and re-build, when ASan checks are desired.

1 Like

That’s an interesting idea. I don’t think it would play well with the VSCode CMake plug-in (which assumes a single build directory). I’ll have a try though…

1 Like

We set the ITK_DIR based on the CMAKE_BUILD_TYPE variable and seems to work with both VS and ninja builds.

1 Like