我正在尝试使用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;
}
但仍会返回相同的错误。我怎样才能将它附加到调试器上?
答案 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附加了这个过程。
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系统调用。 gdb
和strace
都使用它,一次只能有一个活动。
答案 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 main
和c
停在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
然后重启。