Valgrind - how to run on many binaries - valgrind

How to run valgrind on many libraries?
I try to define custom_target in CMakeLists.txt and I try to define COMMAND as:
valgrind bin1 bin2
and valgrind runs only first binary.

Valgrind can only exercise one executable at a time.
You could do something like
valgrind --trace-children=yes script bin1 bin2
where script would be a shell script that loops over its arguments and executes them.
The disadvantage of this is that Valgrind will also be executing the shell, which will make things slower and generate more noise.

Related

how to use clang tidy in CMake

I would like to use CMake and clang-tidy in my project, however I see that build times are quite a bit higher when I use this in all the main cmake file:
set(CMAKE_CXX_CLANG_TIDY
clang-tidy-11;
-format-style='file';
-header-filter=${CMAKE_CURRENT_SOURCE_DIR};
)
It is working well, but I don't want to have this build-time penalty every time I build the project during development. Therefore I thought I would make a separate target that builds all, but uses clang-tidy. And when I do a regular debug or release build it does not do any checking. However I don't know how to do this in Cmake. Do I make a custom target with a command "cmake --build" with a target_set_property of CMAKE_CXX_CLANG_TIDY?
This feels rather clunky, so my question is, are there other ways to do this?
however I see that build times are quite a bit higher when I use this in all the main cmake file:
You're going to have to pay for the cost of running clang-tidy sometime or another. It's essentially running the first few phases of a compiler to analyze your code and look for errors.
Setting CMAKE_CXX_CLANG_TIDY runs clang-tidy in line with your build, as you have observed.
This feels rather clunky, so my question is, are there other ways to do this?
Yes. When using the Ninja or Makefile generators, you may set -DCMAKE_EXPORT_COMPILE_COMMANDS=ON at the command line. That will create a file called compile_commands.json in your build folder that the standalone clang-tidy can read.
In sum, at the command line, you would manually run:
$ cmake -G Ninja -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
$ clang-tidy-11 -format-style=file -header-filter=. -p build
The -p flag tells clang-tidy in which directory to find your compile_commands.json.

cmake/ctest generate Test.xml (without rebuilding?) / could not load cache

I have a cmake based (C++) project which includes tests created via add_test().
The build process is basically:
cmake
make all testsuite
make test
This has worked well for some time.
I am now trying to get my build to generate a Test.xml to be submitted as part of a pipeline build. It is not working for this project.
Q1 Can I tell cmake that I want a Test.xml to be generated when it (make test) runs the tests?
Currently I believe that a Test.xml can only be created by running ctest.
Presumably ctest aggregates the test results whereas cmake just runs them blindly?
Can someone confirm or refute this?
So I am currently trying to run ctest using:
ctest -vv -debug --output-on-failure -T test
As this does create the Test.xml file I need.
I had to add include(CTest) & include(Dart) to fix "could not find DartConfiguration.tcl".
However, even if I have previously run "make test" which guarantees the build is up to date it still tries to build and I get:
Error: could not load cache
For tests that run a compiled test (script based tests work fine).
The command it is executing is:
/opt/cmake-3.18.1/bin/cmake "--build" "<projectDir>/test/<TestName>" --target "<test_exe>"
The CMakeCache.txt & CMakeLists.txt actually live in "<projectDir>/cmake" which is why the cache cannot be loaded.
The command should be:
/opt/cmake-3.18.1/bin/cmake "--build" "<projectDir>/cmake" --target "<test_exe>"
Q2 Is there some way to tell ctest it does not need to run cmake?
My suspicion is no. Does ctest have to invoke cmake to run the tests? Does it just monitor and aggregate the output?
If I look in DartConfiguration.tcl I have:
SourceDirectory: <projectDir/cmake
BuildDirectory: <projectDir/cmake
ConfigureCommand: "/opt/cmake-3.18.1/bin/cmake" "<projectDir/cmake"
MakeCommand: /opt/cmake-3.18.1/bin/cmake --build . --config "${CTEST_CONFIGURATION_TYPE}" -- -i
I am running ctest -T test rather than ctest -T build-and-test why is ctest trying to build at all?
I've tried setting Ctest_build_command but it seems to have no effect on the DartConfiguration.tcl generated.
Some clarifications:
ctest works for me for other projects which use out of source builds
This one cannot yet use an out of source build without massive refactoring.
The source root is actually "<projectDir>"
The CMakeLists.txt lives in "<projectDir>/cmake"
Program source code lives in "<projectDir>/src"
Test scripts and code live in "<projectDir>/test"
My build worked using:
enable_testing()
I never previously had to use:
include(CTest)
include(Dart)
One or other of these creates the DartConfiguration.tcl which is just a list of "key: value" pairs. I think this is used when ctest is invoked directly which was not the case here.
I'm not entirely clear on why and what are they actually for despite reading this.
Also posted on the cmake discourse channel - https://discourse.cmake.org/t/cmake-ctest-generate-test-xml-without-rebuilding-could-not-load-cache/2025
It turns out I had some pseudo tests used to build the test driver programs via cmake --build. These were explicitly and inexplicably using CMAKE_CURRENT_DIRECTORY instead of CMAKE_SOURCE_DIR. Oops.

Dynamic Loader of Executable in Valgrind Ignoring LD_LIBRARY_PATH

LD_LIBRARY_PATH=/otherRoot/lib/ valgrind myProg
chroot /otherRoot valgrind myProg
When running the first command, valgrind gives me errors about a stripped dynamic linker because it apparently is not using the one in /otherRoot/lib. Using the second command, it finds my the appropriate .so and works.
For reference, I have valgrind installed in the "normal root" and "otherRoot" as well.
Why does valgrind/myProg not search for the .so in /otherRoot/lib first?
When running the first command, valgrind gives me errors about a stripped dynamic linker because it apparently is not using the one in /otherRoot/lib.
The dynamic loader your program uses doesn't (can't) depend on LD_LIBRARY_PATH, because it is the kernel the loads the dynamic loader (and the kernel generally doesn't care about environment variables). More info here.
Outside of chroot, the "wrong" dynamic loader is used with or without valgrind. You can confirm this by pausing myProg and examining /proc/$PID/maps for it.

How to get CMake to build, but not run, a test

In CMake, how do I indicate that a C test program should be built, but not run?
For the netCDF C library, a free software science data package used by weather, climate, and space scientists, we have both a CMake and an autotools build. The code is available on github. You can see the CMake files there.
In our tests we have some shell scripts and some C programs. In this case, I need some shell script actions to complete before the C test is run. Since I want all this to work with parallel builds, the easiest solution seems to be to have the shell program call the C test program when it needs to, and not call the C test program during testing at all.
For example I have a test program tst_interops3.c (in directory nc_test4). I also have a shell script test run_get_hdf4_files.sh. Here it is:
#!/bin/sh
# This shell gets files from the netCDF ftp site for testing.
# $Id: run_get_hdf4_files.sh,v 1.4 2009/07/15 15:16:05 ed Exp $
set -e
echo ""
file_list="AMSR_E_L2_Rain_V10_200905312326_A.hdf AMSR_E_L3_DailyLand_V06_20020619.hdf \
MYD29.A2009152.0000.005.2009153124331.hdf MYD29.A2002185.0000.005.2007160150627.hdf \
MOD29.A2000055.0005.005.2006267200024.hdf"
echo "Getting HDF4 test files $file_list"
for f1 in $file_list
do
if ! test -f $f1; then
curl -O "ftp://ftp.unidata.ucar.edu/pub/netcdf/sample_data/hdf4/$f1.gz"
gunzip $f1.gz
fi
done
${execdir}/tst_interops3
echo "SUCCESS!!!"
exit 0
This script downloads some data files, and then runs program tst_interops3, which reads the data files to ensure that netCDF can read HDF4 data files. (HDF4 is a legacy science data format).
In autotools, I list tst_interops3 in check_PROGRAMS, but not TESTS. This causes it to be built, but not run. (It is run in the script.)
However, I can't figure out how to do the same thing in CMake. How do I get a test program to build, but not run?
There is no predefined "check" target in CMake; most of test infrastructures used with CMake defines "test" pseudo-target, but not a "check".
So you may define "check" target manually, and set it dependent from every target (like executable) you want to build at this stage:
# Add "check" target which simply executes "ctest" for perform testing.
add_custom_target(check COMMAND "ctest")
# Create an executable which is needed only for testing.
# It *won't* be built on "make all" or "make".
add_executable(test_program_a EXCLUDE_FROM_ALL test_program_a.c)
# Mark the executable to be built on "make check".
add_dependencies(check test_program_a)
# Create some test which involves the executable created above.
# This test is executed on "ctest" (or "make test").
# So it will be executed on "make check" too, after building the test program.
add_test(NAME test.01 COMMAND test_program_a "val1")

CMake add_custom_command run in background

I have a command executed in a POST_BUILD step using add_custom_command(). It takes quite some time, but I don't need the results to run the executable, I just want it to start after the build. Is there a way to run such a command in the background so that the executable can be run right after the build without waiting for the command to finish?
If you are willing to use some platform-specific logic, one way is to use a shell script to launch the command you want to run in the background. A very crude example for Unix systems may look like this:
launcher.sh:
#!/bin/sh
"$#"&
CMakeLists.txt:
add_custom_command(TARGET myTarget POST_BUILD
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/launcher.sh whateverYouWantToRun
)
You could add something equivalent for Windows and then test the CMAKE_HOST_SYSTEM_NAME variable to choose which launcher script to use.