在尝试将GDB附加到进程时如何解决“ptrace操作不允许”?

时间:2013-10-06 23:31:44

标签: c linux debugging gdb strace

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

  

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

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

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

我将“kernel.yama.ptrace_scope”1更改为0并将“/ proc / sys / kernel / yama / ptrace_scope”1更改为0并尝试使用以下方法“设置环境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;
}

但仍会返回相同的错误。我怎样才能将它附加到调试器上?

15 个答案:

答案 0 :(得分:98)

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

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

答案 1 :(得分:31)

这是由于Linux中的内核强化;您可以echo 0 > /proc/sys/kernel/yama/ptrace_scope禁用此行为,也可以在/etc/sysctl.d/10-ptrace.conf

中修改此行为

另请参阅this article about it in Fedora 22(包含文档的链接)和this comment thread about Ubuntu以及。

答案 2 :(得分:7)

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

问题:碰巧我用sudo启动了我的程序,因此在启动gdb时它给了我ptrace: Operation not permitted

解决方案sudo gdb ...

答案 3 :(得分:7)

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

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

答案 4 :(得分:2)

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

  • ps -ef | grep gdb

gdb不能将相同的进程连接两次。

答案 5 :(得分:2)

只想强调一个相关的answer。假设您是root并且已经完成:

strace -p 700

并获得:

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

检查:

cat /proc/700/status | grep TracerPid

如果您看到类似TracerPid: 12的信息,即不为零,则表示该程序的PID已在使用ptrace系统调用。 gdbstrace都使用它,一次只能有一个活动。

答案 6 :(得分:1)

如果权限有问题,您可能需要使用gdbserver。 (出于多种原因,我几乎总是在使用gdb或不使用docker时,总是使用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镜像中运行的/sbin/ip addr list报告的docker镜像的IP地址。这将附加在main运行之前的某个时刻。您可以tb mainc停在main或任何您喜欢的地方。在cgdb,emacs,vim或什至在某些IDE或普通环境下运行gdb。您可以在源代码或构建树中运行gdb,这样它就知道一切在哪里。 (如果找不到您的资源,请使用dir命令。)这通常比在docker映像中运行它要好得多。

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

如果部署到其他OS或嵌入式目标,则可以在其中运行gdbserver或gdb存根,并以相同的方式运行gdb,从而跨真实网络甚至通过串行端口(/dev/ttyS0)进行连接。 / p>

答案 7 :(得分:1)

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

此外,我还尝试在已安装的目录(usr / bin / gdb)中使用gdb的set features命令,它可以工作:/sbin/setcap CAP_SYS_PTRACE=+eip /usr/bin/gdb。 确保以root特权运行此命令。

答案 8 :(得分:1)

我要回答这个旧问题,因为它不被接受,其他任何答案都没有意义。真正的答案可能已经写在class Bad2Util : public Util { public: Bad2Util() : suffix("Bad2"), Util(suffix) {} private: const std::string suffix; }; 中,这是我在Ubuntu下的情况。该文件显示:

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

因此,请执行与上述相同的操作:将/etc/sysctl.d/10-ptrace.conf保留为1,然后在被调试者中添加/proc/sys/kernel/yama/ptrace_scope。然后,被调试者将允许调试器对其进行调试。无需prctl(PR_SET_PTRACER, debugger_pid, 0, 0, 0);且无需重新启动即可使用。

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

答案 9 :(得分:1)

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


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

       securityContext:
          capabilities:
            add: [ "SYS_PTRACE" ]

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

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

      securityContext:
        runAsUser: 0
        runAsGroup: 0
        fsGroup: 101

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

现在你可以这样做:

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

您不会再获得拒绝权限!

注意:这是潘多拉盒子。不建议在生产中使用它。

答案 10 :(得分:0)

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

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

如果这不起作用那么你确实遇到了问题。

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

答案 11 :(得分: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,但我不明白它是什么!!

最后,我删除了目标文件(foo.c),我尝试使用PTRACE_ATTACH系统调用将其附加到vid gdb和tracer 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

答案 12 :(得分:0)

Jesup的答案是正确的;这是由于Linux内核强化。就我而言,我正在使用Mac的Docker社区,并且要更改标志,我必须使用贾斯汀·柯马克(Justin Cormack)的nsenter(参考:https://www.bretfisher.com/docker-for-mac-commands-for-getting-into-local-docker-vm/)进入LinuxKit外壳。

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

  

/#cat / etc / issue

     

欢迎使用LinuxKit

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

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

     

1

     

/#回声0> / proc / sys / kernel / yama / ptrace_scope

     

/#退出

答案 13 :(得分:0)

其他信息

如果要在界面中进行更改(例如添加ovs桥),则必须使用--privileged而不是--cap-add NET_ADMIN

sudo docker run -itd --name=testliz --privileged --cap-add=SYS_PTRACE --security-opt seccomp=unconfined ubuntu

答案 14 :(得分:0)

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

security.bsd.unprivileged_proc_debug=0

security.bsd.unprivileged_proc_debug=1

然后重启。