C++ 如何在 OSX 上获得“编码”的 gdb?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13913818/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 17:49:40  来源:igfitidea点击:

How to get a "codesigned" gdb on OSX?

c++macosdebugginggdbcode-signing

提问by clstaudt

Because I need a Python-enabled gdb, I installed another version via

因为我需要启用 Python 的gdb,所以我通过以下方式安装了另一个版本

brew tap homebrew/dupes
brew install gdb

I want to use this gdbwith Eclipse CDT, where I entered the path to the binary in the Debugging settings. However, launching a program for debugging fails with the following message:

我想在gdbEclipse CDT 中使用它,我在调试设置中输入了二进制文件的路径。但是,启动调试程序失败并显示以下消息:

Error in final launch sequence
Failed to execute MI command:
-exec-run
Error message from debugger back end:
Unable to find Mach task port for process-id 39847: (os/kern) failure (0x5).\n (please check gdb is codesigned - see taskgated(8))
Unable to find Mach task port for process-id 39847: (os/kern) failure (0x5).\n (please check gdb is codesigned - see taskgated(8))

What does "codesigned" mean in this context? How can I get this gdbrunning?

在这种情况下,“协同设计”是什么意思?我怎样才能让它gdb运行?

采纳答案by Matt

It would seem you need to sign the executable. See these links for more information. You should be able to get away with self signing if you don't plan on redistributing that version of gdb.

您似乎需要对可执行文件进行签名。有关更多信息,请参阅这些链接。如果您不打算重新分发该版本的gdb.

https://developer.apple.com/library/mac/#documentation/Security/Conceptual/CodeSigningGuide/Introduction/Introduction.html

https://developer.apple.com/library/mac/#documentation/Security/Conceptual/CodeSigningGuide/Introduction/Introduction.html

https://developer.apple.com/library/mac/#documentation/Darwin/Reference/Manpages/man1/codesign.1.html

https://developer.apple.com/library/mac/#documentation/Darwin/Reference/Manpages/man1/codesign.1.html

Alternatively, you could disable code signing on your system, although this presents a security risk. To do so try running sudo spctl --master-disablein the Terminal.

或者,您可以禁用系统上的代码签名,尽管这会带来安全风险。为此,请尝试sudo spctl --master-disable在终端中运行。

回答by Zak

I.1 Codesigning the Debugger

The Darwin Kernel requires the debugger to have special permissions before it is allowed to control other processes. These permissions are granted by codesigning the GDB executable. Without these permissions, the debugger will report error messages such as:

Starting program: /x/y/foo
Unable to find Mach task port for process-id 28885: (os/kern) failure (0x5).
 (please check gdb is codesigned - see taskgated(8))

Codesigning requires a certificate. The following procedure explains how to create one:

  • Start the Keychain Access application (in /Applications/Utilities/Keychain Access.app)
  • Select the Keychain Access -> Certificate Assistant -> Create a Certificate... menu
  • Then:
    • Choose a name for the new certificate (this procedure will use "gdb-cert" as an example)
    • Set "Identity Type" to "Self Signed Root"
    • Set "Certificate Type" to "Code Signing"
    • Activate the "Let me override defaults" option
  • Click several times on "Continue" until the "Specify a Location For The Certificate" screen appears, then set "Keychain" to "System"
  • Click on "Continue" until the certificate is created
  • Finally, in the view, double-click on the new certificate, and set "When using this certificate" to "Always Trust"
  • Exit the Keychain Access application and restart the computer (this is unfortunately required)

Once a certificate has been created, the debugger can be codesigned as follow. In a Terminal, run the following command...

codesign -f -s  "gdb-cert"  <gnat_install_prefix>/bin/gdb

... where "gdb-cert" should be replaced by the actual certificate name chosen above, and should be replaced by the location where you installed GNAT.

I.1 调试器的编码

Darwin 内核要求调试器在被允许控制其他进程之前具有特殊权限。这些权限是通过对 GDB 可执行文件进行代码设计来授予的。如果没有这些权限,调试器将报告错误消息,例如:

Starting program: /x/y/foo
Unable to find Mach task port for process-id 28885: (os/kern) failure (0x5).
 (please check gdb is codesigned - see taskgated(8))

编码需要证书。以下过程说明了如何创建一个:

  • 启动 Keychain Access 应用程序(在 /Applications/Utilities/Keychain Access.app 中)
  • 选择 Keychain Access -> Certificate Assistant -> Create a Certificate... 菜单
  • 然后:
    • 为新证书选择一个名称(此过程将使用“gdb-cert”作为示例)
    • 将“身份类型”设置为“自签名根”
    • 将“证书类型”设置为“代码签名”
    • 激活“让我覆盖默认值”选项
  • 单击“继续”几次,直到出现“为证书指定位置”屏幕,然后将“钥匙串”设置为“系统”
  • 单击“继续”,直到创建证书
  • 最后,在视图中,双击新证书,将“使用此证书时”设置为“始终信任”
  • 退出钥匙串访问应用程序并重新启动计算机(不幸的是,这是必需的)

创建证书后,调试器可以按如下方式进行代码签名。在终端中,运行以下命令...

codesign -f -s  "gdb-cert"  <gnat_install_prefix>/bin/gdb

...其中“gdb-cert”应替换为上面选择的实际证书名称,并应替换为您安装 GNAT 的位置。

source: https://gcc.gnu.org/onlinedocs/gcc-4.8.1/gnat_ugn_unw/Codesigning-the-Debugger.html

来源:https: //gcc.gnu.org/onlinedocs/gcc-4.8.1/gnat_ugn_unw/Codesigning-the-Debugger.html

UPDATE:High-Sierra (Certificate Assistant - Unknown Error)https://apple.stackexchange.com/questions/309017/unknown-error-2-147-414-007-on-creating-certificate-with-certificate-assist

更新:High-Sierra(证书助手 - 未知错误)https://apple.stackexchange.com/questions/309017/unknown-error-2-147-414-007-on-creating-certificate-with-certificate-assist

回答by klm123

I made gdb work on OSX 10.9 without codesigning this way (described here):

我让 gdb 在 OSX 10.9 上工作,而没有以这种方式进行协同设计(此处描述):

  1. Install gdb with macports. (may be you can skip it)

  2. sudo nano /System/Library/LaunchDaemons/com.apple.taskgated.plist

    change option string from -sto -spat line 22, col 27.

  3. reboot the computer.

  4. Use gdb

  1. 使用 macports 安装 gdb。(也许你可以跳过它)

  2. 须藤纳米 /System/Library/LaunchDaemons/com.apple.taskgated.plist

    将选项字符串从第 22 行第 27 列更改-s-sp

  3. 重新启动计算机。

  4. 使用 gdb

回答by user637338

Check the trust of the cert, it must be trusted for code signing (on yosemite that is the third last in the trust section of the cert view in the keychain access).

检查证书的信任,它必须被信任进行代码签名(在优胜美地,这是钥匙串访问中证书视图信任部分的倒数第三)。

At first the cert was not known for codesigning to the keychain, because there was the Extension purpose "Code Signing" missing, you can find this if you look into the keychain and double click on the certificate:

起初,证书并不以对钥匙串进行代码签名而为人所知,因为缺少扩展目的“代码签名”,如果您查看钥匙串并双击证书,您可以找到它:

enter image description here

在此处输入图片说明

I fixed that:

我修复了:

enter image description here

在此处输入图片说明

Then I added the certificate to the trusted signing certificates, after I had drag&dropped the certificate from the keychain to my desktop, which created the ~/Desktop/gdb-cert.cer:

然后我将证书添加到受信任的签名证书,在我将证书从钥匙串拖放到我的桌面后,创建了 ~/Desktop/gdb-cert.cer:

$ sudo security add-trusted-cert -d -r trustRoot -p codeSign -k /Library/Keychains/System.keychain ~/Desktop/gdb-cert.cer

This was a bit tricky because I was mislead by some internet posts and did not look at the man page. Some said you should use add-trust (https://llvm.org/svn/llvm-project/lldb/trunk/docs/code-signing.txt). The terrible bit was that the command succeeded, but did not do what it "should" (well, it was the wrong command, but it should have told me it was wrong).

这有点棘手,因为我被一些互联网帖子误导了,没有看手册页。有人说你应该使用 add-trust ( https://llvm.org/svn/llvm-project/lldb/trunk/docs/code-signing.txt)。可怕的是命令成功了,但没有做它“应该”的事情(好吧,这是错误的命令,但它应该告诉我这是错误的)。

After that I found the new cert in the trusted certs like so:

之后,我在受信任的证书中找到了新证书,如下所示:

$ security find-identity -p codesigning

Policy: Code Signing
  Matching identities
      1) E7419032D4..... "Mac Developer: FirstName LastName (K2Q869SWUE)"    (CSSMERR_TP_CERT_EXPIRED)
      2) ACD43B6... "gdb-cert"
  2 identities found

  Valid identities only
      1) ACD43... "gdb-cert"
  1 valid identities found

In my case the apple cert is expired, but the one I was using to sign gdb was not (well, I just created it myself). Also be aware that the policy is named differently for the "security add-trusted-cert"(-p codeSign) and the "security find-identity" command (-p codesigning). I then went on to sign gdb and I also always got:

在我的情况下,苹果证书已过期,但我用来签署 gdb 的证书没有过期(好吧,我只是自己创建的)。另请注意,“security add-trusted-cert”(-p codeSign) 和“security find-identity”命令(-p codesigning)的策略命名不同。然后我继续签署 gdb,我也总是得到:

$ codesign --sign gdb-cert.cer --keychain ~/Library/Keychains/login.keychain `which gdb`
  gdb-cert.cer: no identity found

because I was under the impression that I had to give the file name of the cert file to the --sign option, but that in fact was the CN of the certificate that I should have provided and should be in the trust store. You can find the CN here when double clicking on the cert in the keychain:

因为我的印象是我必须将证书文件的文件名提供给 --sign 选项,但实际上这是我应该提供并且应该在信任库中的证书的 CN。双击钥匙串中的证书时,您可以在此处找到 CN:

enter image description here

在此处输入图片说明

or in the above output of "security find-identity -p codesigning". Then I went on to sign and I had to give it the right keychain:

或在“security find-identity -p codesigning”的上述输出中。然后我继续签名,我不得不给它正确的钥匙串:

 codesign -s gdb-cert --keychain /Library/Keychains/System.keychain `which gdb` 

I had to enter the root password to allow access to the keychain.

我必须输入 root 密码才能访问钥匙串。

That then gave me a working gdb and it should give you a signed application.

然后给了我一个可用的 gdb,它应该给你一个签名的应用程序。

回答by Schneems

If using gdbisn't a hard requirement you can also use lldbas an alternative. It is already on your system and doesn't need to be code signed:

如果使用gdb不是硬性要求,您也可以将其lldb用作替代方案。它已经在你的系统上,不需要代码签名:

$ lldb stddev_bugged
(lldb) target create "stddev_bugged"
Current executable set to 'stddev_bugged' (x86_64).
(lldb) b mean_and_var
Breakpoint 1: where = stddev_bugged`mean_and_var + 17 at stddev_bugged.c:17, address = 0x0000000100000b11
(lldb) r
Process 1621 launched: '/Users/richardschneeman/Documents/projects/21stCentury/02/example-00/stddev_bugged' (x86_64)
Process 1621 stopped
* thread #1: tid = 0xc777, 0x0000000100000b11 stddev_bugged`mean_and_var(data=0x00007fff5fbff590) + 17 at stddev_bugged.c:17, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x0000000100000b11 stddev_bugged`mean_and_var(data=0x00007fff5fbff590) + 17 at stddev_bugged.c:17
   14   typedef struct meanvar {double mean, var;} meanvar;
   15
   16   meanvar mean_and_var(const double *data){
-> 17       long double avg = 0,
   18             avg2 = 0;
   19       long double ratio;
   20       size_t count= 0;
(lldb)

Here's a table converting gdbto lldbcommands http://lldb.llvm.org/lldb-gdb.html

这是一个转换gdblldb命令的表格http://lldb.llvm.org/lldb-gdb.html

回答by Autumnsault

I ended up having to follow these directionsinstead of the directions suggested by others.

我最终不得不遵循这些指示,而不是其他人建议的指示。

I'm still not sure if it was the act of killall taskgatedor the process of enabling root user that made the difference.

我仍然不确定是否是killall taskgated启用 root 用户的行为或过程造成了差异。

Some have said rebooting is necessary. I find that with the above instructions, that may not be the case.

有人说重启是必要的。我发现根据上述说明,情况可能并非如此。

I did also make the change recommended by @klm123, so this may also have contributed.

我也做了@klm123 推荐的更改,所以这也可能有所贡献。

Note that I use homebrew, not macports.

请注意,我使用自制软件,而不是 macports。

回答by skh

It's a very old topic, but I am adding a response, because out of many available instructions, only one contained just the right steps to make a self-signed debugger work.

这是一个非常古老的主题,但我正在添加一个响应,因为在许多可用的说明中,只有一个包含使自签名调试器工作的正确步骤。

You have to create a self-signed root certificate and then sign the gdb executable with it, but many people complained that it did not work for them. Neither did it for me until I stumbled upon this link.

您必须创建一个自签名根证书,然后用它签署 gdb 可执行文件,但许多人抱怨它对他们不起作用。在我偶然发现此链接之前,我也没有这样做。

The key point missing in other manuals is that you have to restartyour computer for the changes to take effect. Once I did that, everything worked as intended.

其他手册中缺少的关键点是您必须重新启动计算机才能使更改生效。一旦我这样做了,一切都按预期进行。

I hope, this will help others.

我希望,这会帮助其他人。

回答by Ilya M

I followed the instructions with codesigning, but gdb would still give me the same error. It turned out that it did work when gdb is run as root (sudo gdb). I'm using Sierra osx.

我遵循了协同设计的说明,但 gdb 仍然会给我同样的错误。事实证明,当 gdb 以 root (sudo gdb) 运行时它确实有效。我正在使用 Sierra osx。

回答by GLJ

This is an older question but none of the solutions seemed to work for me (I was using Mojave). Converting to lldb isn't the solution to the question - its just a work around.

这是一个较旧的问题,但似乎没有一个解决方案对我有用(我使用的是 Mojave)。转换为 lldb 不是问题的解决方案 - 它只是一种解决方法。

After trying several solutions, the one I found to work was located here: https://gist.github.com/gravitylow/fb595186ce6068537a6e9da6d8b5b96d#gistcomment-2891198

在尝试了几种解决方案后,我发现可行的解决方案位于此处:https: //gist.github.com/gravitylow/fb595186ce6068537a6e9da6d8b5b96d#gistcomment-2891198

Which references this site: https://sourceware.org/gdb/wiki/PermissionsDarwin#Sign_and_entitle_the_gdb_binary

其中引用了这个站点:https: //sourceware.org/gdb/wiki/PermissionsDarwin#Sign_and_entitle_the_gdb_binary

The solution involves a slightly modified version of the code signing. Essentially, the main difference is when signing the certificate, an entitlements XML file must be passed when codesigning. Below I copy/pasted the contents of the sourceware website for all of the steps from beginning to end.

该解决方案涉及代码签名的稍微修改版本。本质上,主要区别在于在签署证书时,代码签名时必须传递一个权利 XML 文件。下面我从头到尾复制/粘贴了源软件网站的内容。

1.1. Create a certificate in the System Keychain

Start Keychain Access application (/Applications/Utilities/Keychain Access.app)

Open the menu item /Keychain Access/Certificate Assistant/Create a Certificate...

Choose a name (gdb-cert in the example), set Identity Type to Self Signed Root, set Certificate Type to Code Signing and select the Let me override defaults. Click several times on Continue until you get to the Specify a Location For The Certificate screen, then set Keychain to System.

If you cannot store the certificate in the System keychain: create it in the login keychain instead, then export it. You can then import it into the System keychain.

Finally, quit the Keychain Access application to refresh the certificate store.

Control: in the terminal type

security find-certificate -c gdb-cert

This should display some details about your newly minted certificate, e.g.

keychain: "/Library/Keychains/System.keychain" version: 256 class: 0x80001000 attributes: "alis"="gdb-cert" [...]

Make sure that keychain: is the System keychain, as shown.

Also, make sure that your certificate is not expired yet:

security find-certificate -p -c gdb-cert | openssl x509 -checkend 0

If you want to inspect the entire X509 data structure, you can type

security find-certificate -p -c gdb-cert |openssl x509 -noout -text

1.2. Trust the certificate for code signing

Start Keychain Access again. Using the contextual menu for the certificate, select Get Info, open the Trust item, and set Code Signing to Always Trust.

Finally, quit the Keychain Access application once more to refresh the certificate store.

Control: in the terminal type

security dump-trust-settings -d

This should show the gdb-cert certificate (perhaps among others) and its trust settings, including Code Signing.

1.3. Sign and entitle the gdb binary

(Mac OS X 10.14 and later) Create a gdb-entitlement.xml file containing the following:

<?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>

If the certificate you generated in the previous section is known as gdb-cert, use:

codesign --entitlements gdb-entitlement.xml -fs gdb-cert $(which gdb)

or before Mojave (10.14), just

codesign -fs gdb-cert $(which gdb)

You may have to prepend this command with sudo if the gdb binary is located in a place that is not writable by regular users.

If you plan to build gdb frequently, this step can be automated by passing --enable-codesign=gdb-cert (assuming, again, that gdb-cert is the name of the certificate) to configure.

Control: in the terminal type

codesign -vv $(which gdb)

And for 10.14 (Mojave) onwards, also check the entitlements:

codesign -d --entitlements - $(which gdb)

1.4. Refresh the system's certificates and code-signing data

The most reliable way is to reboot your system.

A less invasive way is to and restart taskgated service by killing the current running taskgated process (at any time in the process, but no later than before trying to run gdb again):

sudo killall taskgated

However, sometimes the taskgated service will not restart successfully after killing it, so ensure that it is alive after this step by checking e.g. ps $(pgrep -f taskgated). Or just reboot your system, as mentioned above.

1.1. 在系统钥匙串中创建证书

启动钥匙串访问应用程序 (/Applications/Utilities/Keychain Access.app)

打开菜单项/钥匙串访问/证书助手/创建证书...

选择一个名称(示例中的 gdb-cert),将身份类型设置为自签名根,将证书类型设置为代码签名,然后选择让我覆盖默认值。单击“继续”多次,直到进入“为证书指定位置”屏幕,然后将“钥匙串”设置为“系统”。

如果您无法将证书存储在系统钥匙串中:改为在登录钥匙串中创建它,然后将其导出。然后您可以将其导入到系统钥匙串中。

最后,退出 Keychain Access 应用程序以刷新证书存储。

控制:在终端类型

security find-certificate -c gdb-cert

这应该显示有关您新铸造的证书的一些详细信息,例如

钥匙串:“/Library/Keychains/System.keychain”版本:256 类:0x80001000 属性:“alis”="gdb-cert" [...]

确保钥匙串:是系统钥匙串,如图所示。

另外,请确保您的证书尚未过期:

security find-certificate -p -c gdb-cert | openssl x509 -checkend 0

如果要检查整个 X509 数据结构,可以键入

security find-certificate -p -c gdb-cert |openssl x509 -noout -text

1.2. 信任用于代码签名的证书

再次启动钥匙串访问。使用证书的上下文菜单,选择获取信息,打开信任项,并将代码签名设置为始终信任。

最后,再次退出 Keychain Access 应用程序以刷新证书存储。

控制:在终端类型

security dump-trust-settings -d

这应该显示 gdb-cert 证书(可能包括其他证书)及其信任设置,包括代码签名。

1.3. 对 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-cert,请使用:

codesign --entitlements gdb-entitlement.xml -fs gdb-cert $(which gdb)

或在 Mojave (10.14) 之前,只需

codesign -fs gdb-cert $(which gdb)

如果 gdb 二进制文件位于普通用户无法写入的位置,您可能必须在此命令前加上 sudo。

如果您计划频繁构建 gdb,则可以通过传递 --enable-codesign=gdb-cert(再次假设 gdb-cert 是证书的名称)进行配置来自动执行此步骤。

控制:在终端类型

codesign -vv $(which gdb)

对于 10.14 (Mojave) 以后,还要检查权利:

codesign -d --entitlements - $(which gdb)

1.4. 刷新系统的证书和代码签名数据

最可靠的方法是重新启动系统。

一种侵入性较小的方法是通过终止当前正在运行的 taskgated 进程(在进程中的任何时间,但不晚于尝试再次运行 gdb 之前)来重新启动 taskgated 服务:

sudo killall taskgated

然而,有时 taskgated 服务在杀死它后不会成功重新启动,因此通过检查例如 ps $(pgrep -f taskgated) 确保它在这一步之后是活动的。或者只是重新启动系统,如上所述。