I am now running CTest with or without Valgrind in Ubuntu Linux. Firstly, I set up a CMakeLists.txt script to enable testing:
enable_testing()
include(CTest)
if(UNIX)
set(CTEST_MEMORYCHECK_COMMAND, "usr/bin/valgrind")
set(CTEST_MEMORYCHECK_COMMAND_OPTIONS, "--trace-children=yes --leak-check=full")
endif()
add_test(NAME test
WORKING_DIRECTORY ${my_outputdirectory}
COMMAND test_exe)
When I run the test without valgrind, I use the following command:
cmake -G "CodeBlocks - Unix Makefiles"
ctest -D ExperimentalBuild
ctest -R test -D ExperimentalTest
That works fine. However, when I run the following command to invoke valgrind:
cmake -G "CodeBlocks - Unix Makefiles"
ctest -D ExperimentalBuild
ctest -R test -D ExperimentalMemChec
the following message appear:
--Processing memory checking output:
Memory checking results:
This is definitely not the diagnostic information I expect. I was wondering what I should do next. Thanks!
EDIT:
Later on, I find that the diagnostic information can be available only in the case where the memory leak happens. However, the diagnostic information is very vague in the sense that the location where the error occurs is not given. How could I obtain more detailed information?
By default, CMake does not build debug symbols for Makefile projects, so Valgrind is unable to determine the exact location of a leak in source code.
Try running cmake with
cmake -DCMAKE_BUILD_TYPE=Debug /path/to/source
which should add the compiler option for building debug symbols.
I use a python script which parses my memory leaks from valgrind it is available here.
In CMake I use the following command to add a memory test:
ADD_TEST(testName ${Test_Dir}/memtest.py ${CMAKE_CURRENT_BINARY_DIR}/testExecutable ${CMAKE_BINARY_DIR})
Such that I do not need to parse the memory leak errors direct in cmake. The python script simply executes a memory check with valgrind on the executable and returns an error if a leak was found. If a leak was found the test then fails otherwise it passes. Hope this might help you.
CMake by default uses the following command line arguments for valgrind memcheck:
--log-file=/Path/to/build-dir/Testing/Temporary/MemoryChecker.1.log \
-q --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=50
Note that the --log-file argument means that any valgrind errors ends up in that file. I find it more useful when valgrind posts the information to the stderr, so a build server like Jenkins or TeamCity can show it more easily. In order to do that, you have to set the MEMORYCHECK_COMMAND_OPTIONS variable with --log-fd=2 (and other options if you'd like) so it overrides the --log-file option.
More info here.
Related
I use CMake with GNU Make and would like to see all commands exactly (for example how the compiler is executed, all the flags etc.).
GNU make has --debug, but it does not seem to be that helpful are there any other options? Does CMake provide additional flags in the generated Makefile for debugging purpose?
When you run make, add VERBOSE=1 to see the full command output. For example:
cmake .
make VERBOSE=1
Or you can add -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON to the cmake command for permanent verbose command output from the generated Makefiles.
cmake -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON .
make
To reduce some possibly less-interesting output you might like to use the following options. The option CMAKE_RULE_MESSAGES=OFF removes lines like [ 33%] Building C object..., while --no-print-directory tells make to not print out the current directory filtering out lines like make[1]: Entering directory and make[1]: Leaving directory.
cmake -DCMAKE_RULE_MESSAGES:BOOL=OFF -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON .
make --no-print-directory
It is convenient to set the option in the CMakeLists.txt file as:
set(CMAKE_VERBOSE_MAKEFILE ON)
Or simply export VERBOSE environment variable on the shell like this:
export VERBOSE=1
cmake --build . --verbose
On Linux and with Makefile generation, this is likely just calling make VERBOSE=1 under the hood, but cmake --build can be more portable for your build system, e.g. working across OSes or if you decide to do e.g. Ninja builds later on:
mkdir build
cd build
cmake ..
cmake --build . --verbose
Its documentation also suggests that it is equivalent to VERBOSE=1:
--verbose, -v
Enable verbose output - if supported - including the build commands to be executed.
This option can be omitted if VERBOSE environment variable or CMAKE_VERBOSE_MAKEFILE cached variable is set.
Tested on Cmake 3.22.1, Ubuntu 22.04.
If you use the CMake GUI then swap to the advanced view and then the option is called CMAKE_VERBOSE_MAKEFILE.
I was trying something similar to ensure the -ggdb flag was present.
Call make in a clean directory and grep the flag you are looking for. Looking for debug rather than ggdb I would just write.
make VERBOSE=1 | grep debug
The -ggdb flag was obscure enough that only the compile commands popped up.
CMake 3.14+
CMake now has --verbose to specify verbose build output. This works regardless of your generator.
cd project
cmake -B build/
cmake --build build --verbose
It's worth noting however Xcode may not work with --verbose
Some generators such as Xcode don't support this option currently.
Another option it to use the VERBOSE environment variable.
New in version 3.14.
Activates verbose output from CMake and your build tools of choice when you start to actually build your project.
Note that any given value is ignored. It's just checked for existence.
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=TRUE will generate a file with all compilation commands.
This file is required by some LSP to know how to compile a source file out of the box, but it could also help for debugging compilation problems.
The output file is named ${CMAKE_BINARY_DIR}/compile_commands.json.
I would like to run program to perform do extra installation tasks from CMake. My attempted solution, based on INSTALL(CODE ...) is (this is a real MWE):
macro(MY_EXTRA_STUFF ARG)
execute_process(...)
endmacro()
install(CODE "MY_EXTRA_STUFF(${SOME_ARG})")
but CMake complains when I run ninja install (or make install, depending on generator in use):
[0/1] Install the project...
-- Install configuration: ""
CMake Error at cmake_install.cmake:41 (MY_EXTRA_STUFF):
Unknown CMake command "MY_EXTRA_STUFF".
FAILED: CMakeFiles/install.util
cd /tmp && /usr/bin/cmake -P cmake_install.cmake
ninja: build stopped: subcommand failed.
Is there a way to smuggle my own code into the install stage? The code is too long to fit inside install(CODE "...") nicely. A bonus to do it without an external file. Thanks!
The code passed to install(CODE) is executed as standalone CMake code, thus it shouldn't use definitions (functions,macros, variables) from the rest of CMakeLists.txt.
That is, install(CODE) behaves similar as install(SCRIPT) with a standalone script containing given code.
The thing is that configuration stage (when you call cmake to configure your project) and installation stage, which, as you can see, calls /usr/bin/cmake -P cmake_install.cmake, are separate cmake invocations. These invocations parse different files, so they unaware about context of each other.
I have a build system which uses CMake to generate Makefiles. By default, make will not echo the commands (e.g. g++ -std=c++11 ...), but we can specify VERBOSE=1 to do that.
I want a selective version, where it will not show the verbose commands, but if there is an error, then it will print the full compile / link command that caused the error.
Is there such a setting?
I'm working on a GNU Autotools project where I'm encountering some strange memory allocation errors. I want to use Valgrind to debug, however when I run my executable under it I don't get any line numbers or source file names. I even tried configuring so that optimization is -O0 and with the -g flag for debugging by using the command:
./configure 'CXXFLAGS=-g -O0'
Then I'll run the executable under Valgrind as follows:
valgrind -leak-check=full ./[exename]
and I still only see mysterious outputs like:
==3493== 24 bytes in 1 blocks are definitely lost in loss record 137 of 303
==3493== at 0x4A06409: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==3493== by 0x46904A: xmalloc (in /usr/bin/bash)
What you really want is:
libtool --mode=execute valgrind --leak-check=full exename ...
Complementing on ldav1s's answer, this is what I have on my .bashrc:
alias lgdb="libtool --mode=execute gdb"
alias lddd="libtool --mode=execute ddd"
alias lvalgrind="libtool --mode=execute valgrind"
alias lvalgrinddd="libtool --mode=execute valgrind --db-attach=yes --db-command=\"ddd %f %p\""
This way I don't have to type the rather long command line.
This is resolved by invoking the executable using libtool in "execute" mode as described by ldav1s and also in the manual here: libtool: Debugging-executables. Thanks for the insight ldav1s!
I have a project that compiled an executable with codeblocks. I have modified the compilation chain to use CMAKE. The compilation and execution works well.
The problem is that when a coredump is generated after a crash. I analyse it with gdb with the command: gdb myapp --core=core.1222
If I runs gdb on the computer where executable has been generated, I get all symbols and I can explore threads and local variables.
The problem is when I try to run gdb on another computer, it does not manage to get any symbol. I got the following warning:
BFD: Warning: /home/.../core.1222 is truncated: expected core file size >= 307032064, found: 307027968
"info threads" in gdb display ?? instead function name.
My CMakeLists.txt contains:
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ../bin )
SET(CMAKE_USE_RELATIVE_PATHS ON)
SET(CMAKE_VERBOSE_MAKEFILE ON)
SET(CMAKE_CXX_COMPILER g++)
SET(CMAKE_BUILD_STRIP FALSE)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")
I had compare the invoked make command used by codeblocks and cmake. There are quite similarly except the option -o:
with cmake
-o CMakeFiles/monappilcation.dir/home/.../main.cpp.o
and with codeblock:
-o obj/Release/.../main.cpp.o
The command nm -a display all the symbols correctly.
My questions are:
How does gdb compute the expected size?
How can I retrieve the symbol by using cmake compilation tool chain?
Any of your suggestions will be welcome.