1
0

debug.rst 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. CMake Debugging Guide
  2. *********************
  3. This guide explains how to attach a debugger to CMake's unit testing framework.
  4. We'll focus on using **GDB** on Linux for both command-line and IDE debugging.
  5. See documentation on `CMake Development`_ for more information.
  6. .. _`CMake Development`: README.rst
  7. Linux: Using GDB
  8. ================
  9. On Linux, the GNU Debugger (**GDB**) is the standard tool for debugging the
  10. CMake test suite. The core process involves launching the ``cmake`` executable
  11. from within GDB with a specific set of arguments that configure and run the
  12. desired test.
  13. GDB Configuration
  14. -----------------
  15. For effective debugging, GDB must be configured to handle child processes
  16. correctly, which CMake tests often create. A good practice is to use a local
  17. ``.gdbinit`` file in your build directory. This keeps CMake-specific settings
  18. separate from your global configuration.
  19. **1. Enable Local .gdbinit Files (One-Time Setup)**
  20. To allow GDB to automatically load configuration from your build directory,
  21. add the following line to your global GDB initialization file at
  22. ``$HOME/.gdbinit``. This is a one-time setup that makes future projects easier
  23. to manage.
  24. .. code-block:: text
  25. set auto-load local-gdbinit on
  26. **2. Create a Project-Specific .gdbinit**
  27. Next, create a ``.gdbinit`` file inside your CMake **build directory**.
  28. This file will contain settings specific to debugging CMake.
  29. To make this easier, you can symlink the template file provided in the CMake
  30. source tree:
  31. .. code-block:: bash
  32. # Navigate to your build directory
  33. cd /path/to/your/cmake/build
  34. # Create a symlink to the template
  35. ln -s $cmake_srcdir/Utilities/gdb/gdbinit-template .gdbinit
  36. The template contains the essential settings for debugging CMake tests:
  37. .. code-block:: gdb
  38. # Allows GDB to follow child processes
  39. set follow-fork-mode child
  40. # Allows the parent process continue in parallel
  41. set non-stop on
  42. Debugging from the Command Line
  43. -------------------------------
  44. To start debugging, first cd to the build directory. Then, launch the
  45. ``cmake`` executable using ``gdb --args``, which passes the necessary test
  46. configuration arguments directly to CMake.
  47. .. note::
  48. To get the launch command, run ``ctest -R "RunCMake.$TESTNAME" -VV -N``
  49. The following example runs the ``InstallPackageInfo`` test.
  50. .. code-block:: bash
  51. # Define paths to your CMake source and build directories
  52. CMAKE_SOURCE_DIR="$HOME/cmake"
  53. CMAKE_BUILD_DIR="$CMAKE_SOURCE_DIR/build"
  54. # Define the specific test to run
  55. TEST_NAME="InstallPackageInfo"
  56. # Navigate to the build directory
  57. cd "$CMAKE_BUILD_DIR"
  58. # Launch GDB with the appropriate arguments for the test
  59. gdb --args ./bin/cmake \
  60. "-DCMAKE_MODULE_PATH=$CMAKE_SOURCE_DIR/Tests/RunCMake" \
  61. "-DRunCMake_GENERATOR=Ninja" \
  62. "-DRunCMake_SOURCE_DIR=$CMAKE_SOURCE_DIR/Tests/RunCMake/$TEST_NAME" \
  63. "-DRunCMake_BINARY_DIR=$CMAKE_BUILD_DIR/Tests/RunCMake/$TEST_NAME" \
  64. "-P" "$CMAKE_SOURCE_DIR/Tests/RunCMake/RunCMakeTest.cmake"
  65. Once GDB loads, you may set breakpoints (e.g., ``b cmInstallCommand``) and
  66. then start the test by typing ``run``.
  67. Filtering Tests
  68. ---------------
  69. Some test suites contain multiple sub-tests. To run only a specific one,
  70. you can use the ``RunCMake_TEST_FILTER`` environment variable.
  71. For example, to run only the "Metadata" test within the ``InstallPackageInfo``
  72. suite, you can set the variable before launching GDB:
  73. .. code-block:: bash
  74. RunCMake_TEST_FILTER="Metadata" gdb --args ...
  75. Alternatively, you can set the environment variable from within the
  76. GDB session before running the test:
  77. .. code-block:: gdb-prompt
  78. (gdb) set environment RunCMake_TEST_FILTER Metadata
  79. (gdb) run
  80. IDE Integration
  81. ---------------
  82. You can also debug CMake tests directly from your IDE.
  83. CLion
  84. =====
  85. If you have configured GDB to auto-load local ``.gdbinit`` files as described
  86. above, CLion will automatically pick up the necessary settings.
  87. A simple way to debug a test is to modify its ``CTest`` run configuration:
  88. #. **Select the Test**: In the "Run/Debug Configurations" dialog, find the
  89. ``CTest`` entry for your test (e.g., ``RunCMake.InstallPackageInfo``).
  90. #. **Add CTest Arguments**: In the "CTest arguments" field, add
  91. ``--extra-verbose``. This is helpful for debugging because it prints the
  92. exact command ``CTest`` uses to run the test.
  93. #. **Set Working Directory**: Ensure the "Working Directory" field is set to
  94. ``$CMakeCurrentLocalGenerationDir$``.
  95. You can now set breakpoints in your code and debug this configuration.
  96. Visual Studio Code
  97. ==================
  98. Create a ``launch.json`` file in the ``.vscode`` directory of your
  99. CMake **source folder** with the following configuration. This configuration
  100. hardcodes the necessary GDB settings, so it does not depend on an external
  101. ``.gdbinit`` file.
  102. .. code-block:: json
  103. {
  104. "version": "0.2.0",
  105. "configurations": [
  106. {
  107. "name": "Debug CMake Test",
  108. "type": "cppdbg",
  109. "request": "launch",
  110. "program": "${workspaceFolder}/build/bin/cmake",
  111. "args": [
  112. "-DCMAKE_MODULE_PATH=${workspaceFolder}/Tests/RunCMake",
  113. "-DRunCMake_GENERATOR=Ninja",
  114. "-DRunCMake_SOURCE_DIR=${workspaceFolder}/Tests/RunCMake/InstallPackageInfo",
  115. "-DRunCMake_BINARY_DIR=${workspaceFolder}/build/Tests/RunCMake/InstallPackageInfo",
  116. "-P",
  117. "${workspaceFolder}/Tests/RunCMake/RunCMakeTest.cmake"
  118. ],
  119. "stopAtEntry": false,
  120. "cwd": "${workspaceFolder}/build",
  121. "environment": [],
  122. "MIMode": "gdb",
  123. "setupCommands": [
  124. {
  125. "description": "Enable pretty-printing for gdb",
  126. "text": "-enable-pretty-printing",
  127. "ignoreFailures": true
  128. },
  129. {
  130. "description": "Follow child processes",
  131. "text": "set follow-fork-mode child",
  132. "ignoreFailures": true
  133. },
  134. {
  135. "description": "Don't stop the parent process",
  136. "text": "set non-stop on",
  137. "ignoreFailures": true
  138. }
  139. ]
  140. }
  141. ]
  142. }
  143. .. note::
  144. Remember to change the test name (``InstallPackageInfo``) in the ``"args"`` section to the specific test you want to debug.