114

我正在尝试使用 gdb 附加一个程序,但它返回:

附加到进程 29139
无法附加到进程。如果您的 uid 与目标进程的 uid 匹配,请检查 /proc/sys/kernel/yama/ptrace_scope 的设置,或以 root 用户身份重试。有关更多详细信息,请参阅 /etc/sysctl.d/10-ptrace.conf
ptrace:不允许操作。

gdb-debugger 返回“无法附加到进程,请检查权限并重试。”

strace 返回“附加:ptrace(PTRACE_ATTACH,...):不允许操作”

我将 "kernel.yama.ptrace_scope" 1 更改为 0 和/proc/sys/kernel/yama/ptrace_scope1 更改为 0 并尝试set environment LD_PRELOAD=./ptrace.so这样做:

#include <stdio.h>
int ptrace(int i, int j, int k, int l) {
    printf(" ptrace(%i, %i, %i, %i), returning -1\n", i, j, k, l);
    return 0;
}

但它仍然返回相同的错误。如何将它附加到调试器?

4

15 回答 15

220

如果您使用的是 Docker,您可能需要以下选项:

docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined

如果您使用的是 Podman,您可能也需要它的--cap-add选项:

podman run --cap-add=SYS_PTRACE
于 2017-10-10T22:16:36.857 回答
80

这是由于 Linux 中的内核强化所致;echo 0 > /proc/sys/kernel/yama/ptrace_scope您可以通过或修改它来禁用此行为/etc/sysctl.d/10-ptrace.conf

另请参阅Fedora 22 中关于它的这篇文章(带有文档链接)以及关于 Ubuntu和 .

于 2015-08-28T15:28:57.663 回答
16

我想补充一下我需要--security-opt apparmor=unconfined的选项以及@wisbucky 提到的选项。这是在 Ubuntu 18.04(Docker 客户端和主机)上。因此,在容器中启用 gdb 调试的完整调用是:

docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --security-opt apparmor=unconfined

于 2018-10-06T21:40:34.267 回答
12

没有真正解决上述用例,但我遇到了这个问题:

问题:碰巧我开始我的程序sudo,所以当启动 gdb 时它给了我ptrace: Operation not permitted

解决方案sudo gdb ...

于 2015-12-04T14:51:54.923 回答
6

只是想强调一个相关的答案。假设你是 root 并且你已经完成了:

strace -p 700

并得到:

strace: attach: ptrace(PTRACE_SEIZE, 700): Operation not permitted

查看:

grep TracerPid /proc/700/status

如果你看到类似的东西TracerPid: 12,即不是 0,那是已经在使用ptrace系统调用的程序的 PID。两者都gdb使用strace它,一次只能有一个活动。

于 2020-09-25T09:46:36.430 回答
5

由于我们大多数人都因 Docker 问题而来到这里,所以我将添加Kubernetes答案,因为它可能对某人派上用场......


您必须SYS_PTRACE在 pod 的安全上下文中添加该功能spec.containers.securityContext

       securityContext:
          capabilities:
            add: [ "SYS_PTRACE" ]

在 2 个不同的地方有 2securityContext把钥匙。如果它告诉您密钥未被识别,那么您放错了位置。试试另一个。

您可能还需要一个 root 用户作为默认用户。因此,在其他安全上下文 ( spec.securityContext) 中添加:

      securityContext:
        runAsUser: 0
        runAsGroup: 0
        fsGroup: 101

仅供参考:0 是根。但是我不知道 fsGroup 的值。对于我在做什么,我不在乎,但你可能会。

现在你可以这样做:

strace -s 100000 -e write=1  -e trace=write -p 16

您将不再获得拒绝的权限!

当心:这是潘多拉魔盒。不建议在生产中使用它。

于 2021-06-17T11:58:04.733 回答
4

通过在 Debian Distribution 中设置 set capability 命令,我以更高的权限运行我的代码来处理以太网原始套接字。我尝试了上述解决方案:echo 0 > /proc/sys/kernel/yama/ptrace_scope 或者通过修改它,/etc/sysctl.d/10-ptrace.conf但这对我不起作用。

此外,我还尝试在已安装目录(usr/bin/gdb)中为 gdb 设置功能命令,它可以工作:/sbin/setcap CAP_SYS_PTRACE=+eip /usr/bin/gdb. 确保以 root 权限运行此命令。

于 2020-05-18T16:24:29.257 回答
3

Jesup 的回答是正确的;这是由于Linux内核加固。就我而言,我正在使用 Docker Community for Mac,为了更改标志,我必须使用 justin cormack 的 nsenter 进入 LinuxKit shell(参考:https ://www.bretfisher.com/docker-for-mac-commands -for-getting-into-local-docker-vm/)。

docker run -it --rm --privileged --pid=host justincormack/nsenter1

/#猫/etc/issue

欢迎使用 LinuxKit

                    ##         .
              ## ## ##        ==
           ## ## ## ## ##    ===
       /"""""""""""""""""\___/ ===
      {                       /  ===-
       \______ O           __/
         \    \         __/
          \____\_______/

/#cat /proc/sys/kernel/yama/ptrace_scope

1

/ # echo 0 > /proc/sys/kernel/yama/ptrace_scope

/ # 出口

于 2019-05-12T12:05:45.640 回答
2

我打算回答这个老问题,因为它不被接受,任何其他答案都没有意义。真正的答案可能已经写好了,/etc/sysctl.d/10-ptrace.conf因为这是我在 Ubuntu 下的情况。该文件说:

对于启动需要 PTRACE 的崩溃处理程序的应用程序,被调试者可以通过在 segfault 处理程序中特别声明哪个进程将在被调试者上使用 PTRACE 来注册异常:prctl(PR_SET_PTRACER, debugger_pid, 0, 0, 0);

所以只要做和上面一样的事情:保持/proc/sys/kernel/yama/ptrace_scope为1并添加prctl(PR_SET_PTRACER, debugger_pid, 0, 0, 0);被调试者。然后被调试者将允许调试器对其进行调试。这在没有sudo和没有重新启动的情况下都有效。

通常,被调试者还需要调用waitpid以避免崩溃后退出,以便调试器可以找到被调试者的pid。

于 2020-06-11T12:27:58.817 回答
2

也许有人已经用 gdb 附加了这个过程。

  • ps -ef | grep gdb

gdb 不能两次附加相同的进程。

于 2017-05-18T05:56:19.290 回答
1

如果权限是一个问题,您可能会想要使用 gdbserver。(当我使用 gdb、docker 或不使用 gdb 时,我几乎总是使用 gdbserver,原因有很多。)您需要在 docker 映像中安装 gdbserver (Deb) 或 gdb-gdbserver (RH)。在 docker 中运行程序

$ sudo gdbserver :34567 myprogram arguments

(选择一个端口号,1025-65535)。然后,在主机上的 gdb 中,说

(gdb) target remote 172.17.0.4:34567

172.17.0.4在docker 镜像中运行报告的 docker 镜像的 IP 地址在哪里/sbin/ip addr list。这将附加在main运行前的某个点。你可以停在tb main,或任何你喜欢的地方。在 cgdb、emacs、vim 下运行 gdb,甚至在某些 IDE 中运行 gdb。您可以在源代码或构建树中运行 gdb,因此它知道所有内容在哪里。(如果找不到您的源代码,请使用该命令。)这通常比在 docker 映像中运行它要好得多。cmaindir

gdbserver 依赖于ptrace,因此您还需要执行上面建议的其他操作。--privileged --pid=host对我来说足够了。

如果您部署到其他操作系统或嵌入式目标,您可以在那里运行 gdbserver 或 gdb 存根,并以相同的方式运行 gdb,通过真实网络甚至通过串行端口 ( /dev/ttyS0) 连接。

于 2020-04-22T18:28:25.347 回答
0

我不知道你在用 LD_PRELOAD 或你的 ptrace 函数做什么。

为什么不尝试将 gdb 附加到一个非常简单的程序?制作一个简单地重复打印 Hello 或其他内容的程序,并使用 gdb --pid [hello program PID] 附加到它。

如果这不起作用,那么您确实有问题。

另一个问题是用户 ID。您正在跟踪的程序是否将自己设置为另一个 UID?如果是,那么除非您使用相同的用户 ID 或者是 root,否则您无法对其进行 ptrace。

于 2013-10-06T23:35:42.183 回答
0

额外的信息

如果要对接口进行更改,例如添加 ovs 网桥,则必须--privileged使用--cap-add NET_ADMIN.

sudo docker run -itd --name=testliz --privileged --cap-add=SYS_PTRACE --security-opt seccomp=unconfined ubuntu
于 2019-11-14T08:53:06.393 回答
0

如果您使用的是 FreeBSD,请编辑/etc/sysctl.conf、更改行

security.bsd.unprivileged_proc_debug=0

security.bsd.unprivileged_proc_debug=1

然后重新启动。

于 2021-05-03T20:40:19.983 回答
0

我遇到了同样的问题并尝试了很多解决方案,但最后,我找到了解决方案,但我真的不知道问题是什么。首先我修改了 ptrace_conf 值并以 root 身份登录到 Ubuntu,但问题仍然出现。但发生的最奇怪的事情是 gdb 向我显示了一条消息,上面写着:

Could not attach to process. If your uid matches the uid of the target process, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try again as the root user.
For more details, see /etc/sysctl.d/10-ptrace.conf warning: process 3767 is already traced by process 3755 ptrace: Operation not permitted.

使用 ps 命令终端,未列出进程 3755。

我在 /proc/$pid 中找到了进程 3755,但我不明白它是什么!!

最后,我删除了我尝试使用 PTRACE_ATTACH 系统调用将其附加到 vid gdb 和 tracer c 程序的目标文件 (foo.c),在另一个文件夹中,我创建了另一个 c 程序并对其进行了编译。

问题解决了,我可以通过 gdb 或 ptrace_attach 系统调用附加到另一个进程。

(gdb) attach 4416

Attaching to process 4416

我向进程 4416 发送了很多信号。我用 gdb 和 ptrace 对其进行了测试,它们都运行正常。

真的我不知道问题是什么,但我认为这不是 Ubuntu 中的错误,因为很多网站都提到了它,例如https://askubuntu.com/questions/143561/why-wont-strace- gdb-attach-to-a-process-even-though-im-root

于 2017-12-07T10:56:51.847 回答