所谓“工欲善其事,必先利其器”,作为一个程序员,调试在项目开发过程中的重要性自然是不言而喻的。
最近项目中遇到的项目是由python和cpp完成的,python端会调用到cpp的库。由于做二次开发需要进行跨语言联调,所以在这里对调试的配置做个记录。
整个项目是在Linux环境下进行调试的,代码使用vscode进行编辑的,这里就记录了vscode下远程跨语言调试过程。
首先vscode项目下的配置,都会在项目下生成一个隐藏的.vscode文件夹,这个文件夹下是项目的配置,相关的基础部分可以看我的这篇文章记录vscode远程lldb调试Linux下程序_笑傲江湖的小白的博客-CSDN博客
整个项目上层使用python端写的,底层采用cpp。这里先给出.vscode文件夹下的结构。.env文件是配置项目的环境变量的;c_cpp_properties.json是配置cpp项目的编译器,以及搜索头文件路径的;launch.json是配置项目调试执行。
这里python的环境采用了conda的环境和本地编译后的python文件共同组成的。在.vscode文件中设置的,这里给出.vscode的配置,这里的/home/wzy/tvm-sycl/git-tvm-sycl/tvm/python是本地项目需要用到的二次开发使用的python库。
PYTHONPATH="/home/wzy/tvm-sycl/git-tvm-sycl/tvm/python:${PYTHONPATH}"
下面给出c_cpp_properties.json文件
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/home/wzy/sycl_workspace/build-cuda-2022-09-debug/include/sycl/",
"/home/wzy/app/googletest-build-release-1.10/include/",
"/usr/local/cuda-11.2/include/**"
],
"defines": [],
"compilerPath": "/home/wzy/sycl_workspace/build-cuda-2022-09-debug/bin/clang++",
"cStandard": "gnu17",
"cppStandard": "gnu++17",
"intelliSenseMode": "linux-clang-x64"
}
],
"version": 4
}
这里面包含了头文件搜索路径,C和Cpp使用标准,以及要使用的平台-编译器-架构模式,以及编译器路径。
下面给出launch.json内容
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"python":"/home/wzy/anaconda3/envs/tvm/bin/python",
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
"justMyCode": true,
},
{
"type": "lldb",
"request": "attach",
"name": "Attach-TVM-lldb",
"pid":"${command:pickMyProcess}",
}
]
}
这个launch.json可以采用vscode界面添加自动生成再做细节调整,可以通过添加配置来生成模板,模板选项如下图所示。
这里第一个配置是python的配置,里面主要设置了python的编译器路径。request这里标明了执行类型,vscode的执行类型有两种launch和attach,launch一般是直接运行调试的,attach是通过进程管理方式进行调试。program定义的"${file}"是制定目前选中的执行文件去执行。
这里的第二个配置是cpp的配置,里面采用attach by PID的方式来调试,通过attach进行的方式进行调试,这里的pid就是进程的id号,需要在调试的时候指定。
下面简述一下调试过程。首先从python端调试器,开始点击绿色开始按钮后启动调试,程序会进入到python端的断点处。
然后通过调试控制台来获取python端调试程序的进程id号,即cpp需要attach的pid,这里我通过
python命令在调试控制台获取到了pid,如下pid为20683
import os
os.getpid()
这里需要提前设置权限。
防止调试过程中出现运行中的进程报错:Operation not permitted.
从Ubuntu10.10开始,系统为安全考虑,默认阻止一个进程检查和修改另一个进程,除非前者是后者的父进程。
阻止操作由 ptrace_scope 实现,当 ptrace_scope = 1 时,gdb 在调试运行中的进程时,会产生如下报错:
将 ptrace_scope 修改为 0,即可正常调试。
查看 ptrace_scope :cat /proc/sys/kernel/yama/ptrace_scope
修改 ptrace_scope :vi /etc/sysctl.d/10-ptrace.conf(修改为 kernel.yama.ptrace_scope = 0)
生效 :sysctl -p /etc/sysctl.d/10-ptrace.conf (不行就重启)
重启 :reboot
接下来如果要进入到cpp端的断点处,需要将编译器切换至lldb编译器,然后打断点,点击启动调试按钮。
这个时候会跳出输入选择进程的界面,把我们刚才获取的进程pid号输入进去,回车后等待一阵,就会进入到lldb调试器中去。
等待片刻后,可能会有点慢,会发现调用堆栈这里会有两个debug控制折叠栏,等到Attach-TVM-lldb前面有了箭头,说明lldb调试调用就绪了。
下面要注意将断点里面C++:on throw 选中按钮给取消掉,然后按跳过,就可进入cpp的断点处。