CLion 是 JetBrains IDE 全家桶产品之一,可以用来开发 C/C++ 项目,而 GDB 则可以用来对 C/C++ 程序进行调试。

作为一款调试器,GDB 为程序开发人员提供了强大的调试功能,但却需要使用命令来执行调试操作,操作起来不是很方便。(有关 GDB 的使用,可以参考文章《GDB 调试》。)为此,CLion 为程序开发人员提供了图形化的调试界面以方便调试。另外,CLion 还提供了远程调试的功能。因为在实际项目中,我们常会碰到在本地开发环境编写代码,程序却在远程机器运行的情况。远程调试功能对我们来说是十分必要的。

环境准备

假设本地开发环境是 Windows 操作系统,程序远程执行环境是 Ubuntu系统 操作系统。为满足远程调试,需要在 CentOS 上安装必要的软件,安装的软件包括:

  • cmake
  • gcc
  • gdb
  • gdbserver

cmake 用于管理编译过程,生成 Makefile 文件;gcc-c++ 是编译器;gdb 是个调试工具,程序调试功能实际上就是由 gdb 提供的;gdbserver 用于监听某个 TCP 端口,允许远程主机连接,以实现远程调试功能

代码同步

使用 CLion 创建一个 C++ 项目 helloworld。然后,打开菜单 Tools - Deployment - Configuration,配置远程主机以及本地目录与远程目录的映射关系:
image.png
image.png
右键项目文件夹,选择 Deployment - Upload to 192.168.190.70,便将项目源代码上传至 192.168.190.70 主机上。
image.png
上述我们配置了远程主机与本地主机目录映射,因此执行上传操作后,可以看到源代码已被上传至上述配置的目录中。

代码编译

CLion 为我们生成了默认的源代码main.cpp,修改 main.cpp,增加一个 add 函数,方便展示调试功能

  1. #include <iostream>
  2. using namespace std;
  3. int add(int a, int b)
  4. {
  5. int sum = a + b;
  6. return sum;
  7. }
  8. int main() {
  9. std::cout << "Hello, World!" << std::endl;
  10. int sum = 0;
  11. sum = add(5, 3);
  12. std:cout << "sum of 5 and 3 is " << sum << std::endl;
  13. return 0;
  14. }

修改 main.cpp 源代码后,需要重新将代码上传至远程机器。
CLion生成的 CMakeLists.txt 如下,使用 C++14 标准,指定生成的可执行文件名为 clion_cmake_demo:

  1. cmake_minimum_required(VERSION 3.20)
  2. project(clion_cmake_demo)
  3. set(CMAKE_CXX_STANDARD 14)
  4. add_executable(clion_cmake_demo main.cpp)

由于上面我们已将源代码上传至 10.88.115.114 主机,进入 10.88.115.114 目录 /mnt/project/clion-cmake-demo,然后执行以下操作:

  1. cd /mnt/project/clion-cmake-demo
  2. mkdir build && cd build
  3. cmake .. -DCMAKE_BUILD_TYPE=Debug
  4. make -j 20

执行 cmake 命令会生成 Makefile 文件,指定 -DCMAKE_BUILD_TYPE=Debug 是为了支持 gdb 调试。
执行 make 命令会在 build 目录下编译生成可执行文件:clion_cmake_demo。

远程调试

经过上述的操作步骤,接下来我们就可以实施远程调试了。
在远程主机继续执行命令:

  1. gdbserver :1234 /mnt/project/clion-cmake-demo/build/clion_cmake_demo

报错

  1. gdbserver: Error disabling address space randomization: Operation not permitted

解决
linux 内核为了安全起见,采用了Seccomp(secure computing)的沙箱机制来保证系统不被破坏。它能使一个进程进入到一种“安全”运行模式,该模式下的进程只能调用4种系统调用(system calls),即read(), write(), exit()和sigreturn(),否则进程便会被终止。

docker只有以--security-opt seccomp=unconfined的模式运行container才能利用GDB调试

返回本地 CLion,配置远程调试信息,增加一个 GDB Remote Debug 配置:
image.png
image.png

设置断点,按下调试按钮,可以看到程序已被执行起来,且中断在断点处,可以看到变量值:
image.png