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


80

我正在尝试使用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使用此方法:

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

Answers:


177

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


53
即使问题没有提到Docker,我也因此而来到这里。这为我解决了,感谢您超越问题。
Perennialista

这对我在Docker上运行GCC 8.2和GDB 8.1的工作有效
ThetaSinner '18

1
在执行docker build而不是run时如何执行此操作?似乎没有这些参数?(我有一个奇怪的错误,只有在使用Dockerfile时才会发生)
fersarr

3
在docker-compose.yml中,我只需要cap_add: - SYS_PTRACE在容器规范中添加(在冒号后添加新行)。
拉斐尔·G。20年

1
在更新的Docker版本18+中,--security-opt seccomp=unconfined不再需要。
BZ

63

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

另请参阅Fedora 22中有关此文章的文章(以及指向文档的链接)以及有关Ubuntu和的注释线程


3
echo ...在我的情况下,如果我开了一个根控制台与第一只没有工作sudo -isudo echo ...没有工作,由于重定向符号)
[R尤达

有些shell构造很难在sudo等命令的参数中使用。
jesup

17
使用sudo和重定向时,您可以使用echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
Daniel Serodio

13

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

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


这不能为问题提供答案。一旦您拥有足够的声誉,您就可以在任何帖子中发表评论;相反,请提供不需要问询者澄清的答案。-评论
拉斐尔

2
@Rafael的答案已使用完整的命令行更新。它的确为现在的问题提供了完全独立的答案。
尤拉·奥尔舒利奇(JurajOršulić)'18年

11

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

问题:碰巧我用来启动程序sudo,所以启动gdb时给了我ptrace: Operation not permitted

解决方案sudo gdb ...


1
但是请注意,sudo gdb如果echo 3 | sudo tee /proc/sys/kernel/yama/ptrace_scopekernel.org/doc/Documentation/security/Yama.txt)也不起作用,它将看不到您的.gdbinit脚本。
西罗Santilli郝海东冠状病六四事件法轮功

3

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

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

/#猫/ etc / issue

欢迎使用LinuxKit

/#猫/ proc / sys / kernel / yama / ptrace_scope

1个

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

/ # 出口


2

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

  • ps -ef | grep gdb

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


2

通过在Debian Distribution中设置set capacity命令,我以更高的特权运行代码来处理以太网原始套接字。我尝试了上述解决方案: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特权运行此命令。


2

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

并获得:

检查:

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


1

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

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

这里172.17.0.4是泊坞窗图像的IP地址,通过报道/sbin/ip addr list泊坞窗图像中运行。这将在main运行之前附加在一个点上。你可以tb mainc停在main,或者你喜欢的地方。在cgdb,emacs,vim或什至在某些IDE或普通环境下运行gdb。您可以在源代码或构建树中运行gdb,这样它就知道一切在哪里。(如果找不到您的资源,请使用dir命令。)通常比在docker映像中运行它要好得多。

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

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


1

我要回答这个旧问题,因为它不被接受,其他任何答案都没有意义。真正的答案可能已经写好了/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。


0

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

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

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

另一个问题是用户ID。您要跟踪的程序是否将自身设置为另一个UID?如果是,则无法ptrace它,除非您使用相同的用户ID或是root用户。


它附加了简单的程序,但是我试图附加一个crackme文件。它具有反调试保护这样
user2850750 2013年

@ user2850750:我在答案中又增加了一点。
Zan Lynx

我正在尝试将其作为根
user2850750 2013年

@ user2850750:好的。那么,gdb是否有可能以某种方式在共享库中调用ptrace函数?如果在带有预加载对象的hello world程序上运行gdb,它也会失败吗?
Zan Lynx

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 syscall将其附加到vid gdb和tracer c程序中,并在另一个文件夹中创建了另一个c程序并进行了编译。

该问题已解决,并且可以通过gdb或ptrace_attach syscall附加到另一个进程。

(gdb) attach 4416

Attaching to process 4416

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

确实我不知道问题出在哪里,但是我认为这不是Ubuntu中的错误,因为很多网站都提到了它,例如/ubuntu/143561/why-wont-strace- gdb附加到一个进程,即使我是root


0

额外的信息

如果要在接口中进行更改(例如添加ovs桥),则必须使用--privileged代替--cap-add NET_ADMIN

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.