Mac OS 使用gdb调试程序的那些事
VS CODE C/C++ 环境配置
mac下要使用gdb进行代码调试可以说是一波三折,这里做个笔录
前因
最近在更新系统,出现了gdb无法调试程序的情况,翻查了一下gdb的wiki页面.如果您尝试调试文件,您将收到错误,因为Darwin内核不允许gdb在没有特殊权限的情况下控制另一个进程。 出于安全原因,这是默认行为。
这是因为如果您没有特殊权限,Darwin内核将拒绝允许gdb调试另一个进程,因为调试进程意味着可以完全控制该进程,并且默认情况下不允许这样做,因为它可以被利用恶意软件。 (如果你是root用户,内核不会拒绝,但你当然不希望成为root用户进行调试。)
For help, type "help".
Type "apropos word" to search for commands related to "word".
=cmd-param-changed,param="startup-with-shell",value="off"
Warning: Debuggee TargetArchitecture not detected, assuming x86_64.
=cmd-param-changed,param="pagination",value="off"
ERROR: Unable to start debugging. Unexpected GDB output from command "-exec-run". Unable to find Mach task port for process-id 1170: (os/kern) failure (0x5).
(please check gdb is codesigned - see taskgated(8))
The program '/Users/apple/Desktop/helloword/person.out' has exited with code 0 (0x00000000).
在进行下文之前,请参照如下四点,并将你的问题对号入座,找出对应的解决方法.
-
如果您使用macOS 10.13“High Sierra”:gdb 8.1与macOS 10.13不兼容。 降级为gdb 8.0.1。
-
如果您在macOS 10.12(Sierra)或更高版本,请确保在运行要调试的程序之前发出“set startup-with-shell off”命令,为了避免每次调试前输入,可以将该命令写到~/.bashrc文件中。
-
您可能(部分)遵循旧方法部分的说明。 例如,如果gdb二进制文件是setgid procmod,则以下的code-signing方法将不再起作用。 在这种情况下,请先以下命令将gdb二进制文件恢复为原始设置:
要解决这个问题,按照如下步骤进行。
生成证书
一,为gdb使用证书授权,您需要生成证书。
-
启动【钥匙串访问】步骤:应用程序:应用程序 > 使用工具 > 钥匙串访问
屏幕快照 2019-08-12 上午9.18.12.png
-
从左侧的钥匙串访问列表中,右键单击【系统】项,然后选择【解锁钥匙串系统】。
屏幕快照 2019-08-11 下午9.11.30.png
转到钥匙串访问 > 证书助理 > 创建证书
-
按照如下步骤创建自签名根证书,证书类型为代码签名,并且选中覆盖这些默认值
屏幕快照 2019-08-11 下午9.24.20.png
-
此时,您可以继续安装过程,直到获得“指定用于该证书的位置”对话框。 在这里,您需要将Keychain设置为【系统】,但这一步会提示未知错误 -2,147,414,007。
解决方案为,在第 4 步骤中:指定用于该证书的位置,设置钥匙串:登录,等证书创建完成后,将证书从“子菜单钥匙串 > 登录中”拖放到"系统"中
完成这些步骤后,您可以在钥匙串访问下看到新证书。 从新创建的证书的上下文菜单中(右键单击它),选择“获取信息”选项。 在对话框中展开“信任”项,并将“代码签名”设置为“始终信任”。
屏幕快照 2019-08-11 下午11.09.12.png
二,验证证书状态
最后,退出【钥匙串访问】应用程序以刷新证书存储区。确保keychain是系统密钥链使用如下命令,如图所示:
security find-certificate -c gdb-crt
使用如下命令验证:如下图应该显示gdb-crt证书(可能包括其他证书)及其信任设置,包括Code Signing。
security dump-trust-settings -d
三,签署并授权gdb二进制文件
(Mac OS X 10.14及更高版本)创建包含以下内容的gdb-entitlement.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.debugger</key>
<true/>
</dict>
</plist>
</pre>
如果gdb二进制文件位于普通用户无法写入的位置,则可能必须在sudo之前添加此命令。
sudo codesign --entitlements gdb-entitlement.xml -fs gdb-crt $(which gdb)
如果您计划经常构建gdb调试的程序,则可以通过传递--enable-codesign = gdb-cert在准备编译gdb源码的时候,给./configure使用该参数选项,从而实现此步骤。
四,刷新系统的证书和代码签名数据
这一步,重启系统
后记
最后是vs code c/c++开发环境设置中三个最重要的配置文件,这里记录以后备用
tasks.json
{
"label": "Complie C",
"type": "shell",
"command": "gcc",
"args":[
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}",
"-g",
"-Wall"
],
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared",
"showReuseMessage": true,
"clear": false
},
"problemMatcher":"$gcc"
},
{
"label": "Complie C++",
"type": "shell",
"command": "g++",
"args":[
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}",
"-g",
"-Wall",
"-std=c++17"
],
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared",
"showReuseMessage": true,
"clear": false
},
"problemMatcher":"$gcc"
}
]
}
launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch C",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/${fileBasenameNoExtension}",
"args": [],
"stopAtEntry": true, //设为true时程序将暂停在程序入口处,相当于在main上打断点
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"miDebuggerPath":"/usr/local/bin/gdb",
"MIMode": "gdb",
"preLaunchTask": "Complie C",
"internalConsoleOptions": "neverOpen"
},
{
"name": "(gdb) Launch C++",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/${fileBasenameNoExtension}",
"args": [],
"stopAtEntry": false, //设为true时程序将暂停在程序入口处,相当于在main上打断点
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"miDebuggerPath":"/usr/local/bin/gdb",
"MIMode": "gdb",
"preLaunchTask": "Complie C++",
"internalConsoleOptions": "neverOpen"
}
]
}
c_cpp_properties.json
{
"configurations": [
{
"name": "Mac",
"includePath": [
"/usr/include",
"/usr/local/include",
"/Library/Developer/CommandLineTools/usr/lib/clang/10.0.1/include",
"/Library/Developer/CommandLineTools/usr/include/c++/v1",
"/Library/Developer/CommandLineTools/usr/include",
"${workspaceFolder}/**"
],
"defines": [],
"macFrameworkPath": [
"/System/Library/Frameworks",
"/Library/Frameworks"
],
"compilerPath": "/usr/bin/g++",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "gcc-x64"
},
{
"name": "Linux",
"includePath": [
"/usr/include",
"/usr/local/include",
"${workspaceFolder}/**"
],
"defines": [],
"browse":{
"path": [
"/usr/include",
"/usr/local/include",
"${workspaceFolder}/**"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
},
"compilerPath": "/usr/bin/g++",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "gcc-x64"
},
{
"name": "Win32",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [
"_DEBUG",
"UNICODE"
],
"browse":{
"path": [
"${workspaceFolder}/",
"C:\\MinGw\\lib\\gcc\\mingw32\\6.3.0\\c++"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
},
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "msvc-x64"
}
],
"version": 4
}