123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- CMake Debugging Guide
- *********************
- This guide explains how to attach a debugger to CMake's unit testing framework.
- We'll focus on using **GDB** on Linux for both command-line and IDE debugging.
- See documentation on `CMake Development`_ for more information.
- .. _`CMake Development`: README.rst
- Linux: Using GDB
- ================
- On Linux, the GNU Debugger (**GDB**) is the standard tool for debugging the
- CMake test suite. The core process involves launching the ``cmake`` executable
- from within GDB with a specific set of arguments that configure and run the
- desired test.
- GDB Configuration
- -----------------
- For effective debugging, GDB must be configured to handle child processes
- correctly, which CMake tests often create. A good practice is to use a local
- ``.gdbinit`` file in your build directory. This keeps CMake-specific settings
- separate from your global configuration.
- **1. Enable Local .gdbinit Files (One-Time Setup)**
- To allow GDB to automatically load configuration from your build directory,
- add the following line to your global GDB initialization file at
- ``$HOME/.gdbinit``. This is a one-time setup that makes future projects easier
- to manage.
- .. code-block:: text
- set auto-load local-gdbinit on
- **2. Create a Project-Specific .gdbinit**
- Next, create a ``.gdbinit`` file inside your CMake **build directory**.
- This file will contain settings specific to debugging CMake.
- To make this easier, you can symlink the template file provided in the CMake
- source tree:
- .. code-block:: bash
- # Navigate to your build directory
- cd /path/to/your/cmake/build
- # Create a symlink to the template
- ln -s $cmake_srcdir/Utilities/gdb/gdbinit-template .gdbinit
- The template contains the essential settings for debugging CMake tests:
- .. code-block:: gdb
- # Allows GDB to follow child processes
- set follow-fork-mode child
- # Allows the parent process continue in parallel
- set non-stop on
- Debugging from the Command Line
- -------------------------------
- To start debugging, first cd to the build directory. Then, launch the
- ``cmake`` executable using ``gdb --args``, which passes the necessary test
- configuration arguments directly to CMake.
- .. note::
- To get the launch command, run ``ctest -R "RunCMake.$TESTNAME" -VV -N``
- The following example runs the ``InstallPackageInfo`` test.
- .. code-block:: bash
- # Define paths to your CMake source and build directories
- CMAKE_SOURCE_DIR="$HOME/cmake"
- CMAKE_BUILD_DIR="$CMAKE_SOURCE_DIR/build"
- # Define the specific test to run
- TEST_NAME="InstallPackageInfo"
- # Navigate to the build directory
- cd "$CMAKE_BUILD_DIR"
- # Launch GDB with the appropriate arguments for the test
- gdb --args ./bin/cmake \
- "-DCMAKE_MODULE_PATH=$CMAKE_SOURCE_DIR/Tests/RunCMake" \
- "-DRunCMake_GENERATOR=Ninja" \
- "-DRunCMake_SOURCE_DIR=$CMAKE_SOURCE_DIR/Tests/RunCMake/$TEST_NAME" \
- "-DRunCMake_BINARY_DIR=$CMAKE_BUILD_DIR/Tests/RunCMake/$TEST_NAME" \
- "-P" "$CMAKE_SOURCE_DIR/Tests/RunCMake/RunCMakeTest.cmake"
- Once GDB loads, you may set breakpoints (e.g., ``b cmInstallCommand``) and
- then start the test by typing ``run``.
- Filtering Tests
- ---------------
- Some test suites contain multiple sub-tests. To run only a specific one,
- you can use the ``RunCMake_TEST_FILTER`` environment variable.
- For example, to run only the "Metadata" test within the ``InstallPackageInfo``
- suite, you can set the variable before launching GDB:
- .. code-block:: bash
- RunCMake_TEST_FILTER="Metadata" gdb --args ...
- Alternatively, you can set the environment variable from within the
- GDB session before running the test:
- .. code-block:: gdb-prompt
- (gdb) set environment RunCMake_TEST_FILTER Metadata
- (gdb) run
- IDE Integration
- ---------------
- You can also debug CMake tests directly from your IDE.
- CLion
- =====
- If you have configured GDB to auto-load local ``.gdbinit`` files as described
- above, CLion will automatically pick up the necessary settings.
- A simple way to debug a test is to modify its ``CTest`` run configuration:
- #. **Select the Test**: In the "Run/Debug Configurations" dialog, find the
- ``CTest`` entry for your test (e.g., ``RunCMake.InstallPackageInfo``).
- #. **Add CTest Arguments**: In the "CTest arguments" field, add
- ``--extra-verbose``. This is helpful for debugging because it prints the
- exact command ``CTest`` uses to run the test.
- #. **Set Working Directory**: Ensure the "Working Directory" field is set to
- ``$CMakeCurrentLocalGenerationDir$``.
- You can now set breakpoints in your code and debug this configuration.
- Visual Studio Code
- ==================
- Create a ``launch.json`` file in the ``.vscode`` directory of your
- CMake **source folder** with the following configuration. This configuration
- hardcodes the necessary GDB settings, so it does not depend on an external
- ``.gdbinit`` file.
- .. code-block:: json
- {
- "version": "0.2.0",
- "configurations": [
- {
- "name": "Debug CMake Test",
- "type": "cppdbg",
- "request": "launch",
- "program": "${workspaceFolder}/build/bin/cmake",
- "args": [
- "-DCMAKE_MODULE_PATH=${workspaceFolder}/Tests/RunCMake",
- "-DRunCMake_GENERATOR=Ninja",
- "-DRunCMake_SOURCE_DIR=${workspaceFolder}/Tests/RunCMake/InstallPackageInfo",
- "-DRunCMake_BINARY_DIR=${workspaceFolder}/build/Tests/RunCMake/InstallPackageInfo",
- "-P",
- "${workspaceFolder}/Tests/RunCMake/RunCMakeTest.cmake"
- ],
- "stopAtEntry": false,
- "cwd": "${workspaceFolder}/build",
- "environment": [],
- "MIMode": "gdb",
- "setupCommands": [
- {
- "description": "Enable pretty-printing for gdb",
- "text": "-enable-pretty-printing",
- "ignoreFailures": true
- },
- {
- "description": "Follow child processes",
- "text": "set follow-fork-mode child",
- "ignoreFailures": true
- },
- {
- "description": "Don't stop the parent process",
- "text": "set non-stop on",
- "ignoreFailures": true
- }
- ]
- }
- ]
- }
- .. note::
- Remember to change the test name (``InstallPackageInfo``) in the ``"args"`` section to the specific test you want to debug.
|