Linux 尝试将 GDB 附加到进程时如何解决“不允许 ptrace 操作”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19215177/
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
How to solve "ptrace operation not permitted" when trying to attach GDB to a process?
提问by user2850750
I'm trying to attach a program with gdb but it returns:
我试图用 gdb 附加一个程序,但它返回:
Attaching to process 29139
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
ptrace: Operation not permitted.
附加到进程 29139
无法附加到进程。如果您的 uid 与目标进程的 uid 匹配,请检查 /proc/sys/kernel/yama/ptrace_scope 的设置,或以 root 用户身份重试。有关更多详细信息,请参阅 /etc/sysctl.d/10-ptrace.conf
ptrace:不允许操作。
gdb-debugger returns "Failed to attach to process, please check privileges and try again."
gdb-debugger 返回“无法附加到进程,请检查权限并重试。”
strace returns "attach: ptrace(PTRACE_ATTACH, ...): Operation not permitted"
strace 返回“附加:ptrace(PTRACE_ATTACH,...):不允许操作”
I changed "kernel.yama.ptrace_scope" 1 to 0 and /proc/sys/kernel/yama/ptrace_scope
1 to 0 and tried set environment LD_PRELOAD=./ptrace.so
with this:
我将 "kernel.yama.ptrace_scope" 1 改为 0 和/proc/sys/kernel/yama/ptrace_scope
1 改为 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;
}
But it still returns the same error. How can I attach it to debuggers?
但它仍然返回相同的错误。如何将其附加到调试器?
回答by Zan Lynx
I don't know what you are doing with LD_PRELOAD or your ptrace function.
我不知道你在用 LD_PRELOAD 或你的 ptrace 函数做什么。
Why don't you try attaching gdb to a very simple program? Make a program that simply repeatedly prints Hello or something and use gdb --pid [hello program PID] to attach to it.
为什么不尝试将 gdb 附加到一个非常简单的程序?制作一个简单地重复打印 Hello 或其他内容的程序,并使用 gdb --pid [hello program PID] 附加到它。
If that does not work then you really do have a problem.
如果这不起作用,那么您确实有问题。
Another issue is the user ID. Is the program that you are tracing setting itself to another UID? If it is then you cannot ptrace it unless you are using the same user ID or are root.
另一个问题是用户 ID。您正在跟踪的程序是否将自身设置为另一个 UID?如果是,则除非您使用相同的用户 ID 或者是 root,否则您无法对其进行 ptrace。
回答by jesup
This is due to kernel hardening in Linux; you can disable this behavior by echo 0 > /proc/sys/kernel/yama/ptrace_scope
or by modifying it in /etc/sysctl.d/10-ptrace.conf
这是由于 Linux 中的内核强化;您可以通过echo 0 > /proc/sys/kernel/yama/ptrace_scope
或修改它来禁用此行为/etc/sysctl.d/10-ptrace.conf
See also this article about it in Fedora 22(with links to the documentation) and this comment thread about Ubuntuand .
另请参阅Fedora 22 中有关它的这篇文章(带有指向文档的链接)以及有关 Ubuntu和 .
回答by Maxim Chetrusca
Not really addressing the above use-case but I had this problem:
没有真正解决上述用例,但我遇到了这个问题:
Problem: It happened that I started my program with sudo
, so when launching gdb it was giving me ptrace: Operation not permitted
.
问题:碰巧我开始我的程序sudo
,所以当启动 gdb 时它给了我ptrace: Operation not permitted
。
Solution: sudo gdb ...
解决方案:sudo gdb ...
回答by Raymond
Maybe someone has attached this process with gdb.
也许有人用 gdb 附加了这个过程。
- ps -ef | grep gdb
- ps -ef | grep gdb
can't gdb attach the same process twice.
不能 gdb 两次附加相同的进程。
回答by wisbucky
If you are using Docker, you will probably need these options:
如果您使用 Docker,您可能需要以下选项:
docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined
回答by husin alhaj ahmade
I have faced the same problem and try a lot of solution but finally, I have found the solution, but really I don't know what the problem was. First I modified the ptrace_conf value and login into Ubuntu as a root but the problem still appears. But the most strange thing that happened is the gdb showed me a message that says:
我遇到了同样的问题并尝试了很多解决方案,但最后,我找到了解决方案,但我真的不知道问题是什么。首先我修改了 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.
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.
With ps command terminal, the process 3755 was not listed.
使用 ps 命令终端,未列出进程 3755。
I found the process 3755 in /proc/$pid but I don't understand what was it!!
我在 /proc/$pid 中找到了进程 3755 但我不明白它是什么!!
Finally, I deleted the target file (foo.c) that I try to attach it vid gdb and tracer c program using PTRACE_ATTACH syscall, and in the other folder, I created another c program and compiled it.
最后,我删除了我尝试使用 PTRACE_ATTACH 系统调用将其附加到 vid gdb 和 tracer c 程序的目标文件 (foo.c),并在另一个文件夹中,我创建了另一个 c 程序并对其进行了编译。
the problem is solved and I was enabled to attach to another process either by gdb or ptrace_attach syscall.
问题解决了,我可以通过 gdb 或 ptrace_attach 系统调用附加到另一个进程。
(gdb) attach 4416
(gdb) attach 4416
Attaching to process 4416
Attaching to process 4416
and I send a lot of signals to process 4416. I tested it with both gdb and ptrace, both of them run correctly.
我发送了很多信号来处理 4416。我用 gdb 和 ptrace 测试了它,它们都运行正确。
really I don't know the problem what was, but I think it is not a bug in Ubuntu as a lot of sites have referred to it, such https://askubuntu.com/questions/143561/why-wont-strace-gdb-attach-to-a-process-even-though-im-root
我真的不知道问题是什么,但我认为这不是 Ubuntu 中的错误,因为很多网站都提到了它,例如https://askubuntu.com/questions/143561/why-wont-strace- gdb-attach-to-a-process-even-though-im-root
回答by Juraj Or?uli?
I would like to add that I needed --security-opt apparmor=unconfined
along with the options that @wisbucky mentioned. This was on Ubuntu 18.04 (both Docker client and host). Therefore, the full invocation for enabling gdb debugging within a container is:
我想补充一下我需要的--security-opt apparmor=unconfined
以及@wisbucky 提到的选项。这是在 Ubuntu 18.04(Docker 客户端和主机)上。因此,在容器内启用 gdb 调试的完整调用是:
docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --security-opt apparmor=unconfined
docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --security-opt apparmor=unconfined
回答by YudhiWidyatama
Jesup's answer is correct; it is due to Linux kernel hardening. In my case, I am using Docker Community for Mac, and in order to do change the flag I must enter the LinuxKit shell using justin cormack's nsenter (ref: https://www.bretfisher.com/docker-for-mac-commands-for-getting-into-local-docker-vm/).
Jesup 的回答是正确的;这是由于Linux内核加固。就我而言,我使用的是 Mac 的 Docker 社区,为了更改标志,我必须使用 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
docker run -it --rm --privileged --pid=host justincormack/nsenter1
/ # cat /etc/issue
Welcome to LinuxKit
## . ## ## ## == ## ## ## ## ## === /"""""""""""""""""\___/ === { / ===- \______ O __/ \ \ __/ \____\_______/
/ # cat /proc/sys/kernel/yama/ptrace_scope
1
/ # echo 0 > /proc/sys/kernel/yama/ptrace_scope
/ # exit
/ # cat /etc/issue
欢迎使用 LinuxKit
## . ## ## ## == ## ## ## ## ## === /"""""""""""""""""\___/ === { / ===- \______ O __/ \ \ __/ \____\_______/
/ # cat /proc/sys/kernel/yama/ptrace_scope
1
/ # echo 0 > /proc/sys/kernel/yama/ptrace_scope
/ # 出口
回答by LIZ AGUIRRE
Extra information
额外的信息
If you wanna make changes in the interfaces such as add the ovs bridge, you must use --privileged
instead of --cap-add NET_ADMIN
.
如果要在接口中进行更改,例如添加 ovs 桥接器,则必须使用--privileged
代替--cap-add NET_ADMIN
。
sudo docker run -itd --name=testliz --privileged --cap-add=SYS_PTRACE --security-opt seccomp=unconfined ubuntu
回答by Nathan Myers
If permissions are a problem, you probably will want to use gdbserver. (I almost always use gdbserver when I gdb, docker or no, for numerous reasons.) You will need gdbserver (Deb) or gdb-gdbserver (RH) installed in the docker image. Run the program in docker with
如果权限有问题,您可能需要使用 gdbserver。(出于多种原因,当我使用 gdb、docker 或不使用 gdb 时,我几乎总是使用 gdbserver。)您需要在 docker 映像中安装 gdbserver (Deb) 或 gdb-gdbserver (RH)。在 docker 中运行程序
$ sudo gdbserver :34567 myprogram arguments
(pick a port number, 1025-65535). Then, in gdb on the host, say
(选择一个端口号,1025-65535)。然后,在主机上的 gdb 中,说
(gdb) target remote 172.17.0.4:34567
where 172.17.0.4
is the IP address of the docker image as reported by /sbin/ip addr list
run in the docker image. This will attach at a point before main
runs. You can tb main
and c
to stop at main
, or wherever you like. Run gdb under cgdb, emacs, vim, or even in some IDE, or plain. You can run gdb in your source or build tree, so it knows where everything is. (If it can't find your sources, use the dir
command.) This is usually much better than running it in the docker image.
172.17.0.4
docker 镜像中/sbin/ip addr list
run报告的 docker 镜像的 IP 地址在哪里。这将在main
运行前附加到某个点。您可以tb main
并c
停在main
,或您喜欢的任何地方。在 cgdb、emacs、vim 甚至一些 IDE 中运行 gdb,或者普通。您可以在源代码或构建树中运行 gdb,因此它知道一切都在哪里。(如果找不到您的源,请使用该dir
命令。)这通常比在 docker 映像中运行要好得多。
gdbserver relies on ptrace
, so you will also need to do the other things suggested above. --privileged --pid=host
sufficed for me.
gdbserver 依赖于ptrace
,因此您还需要执行上面建议的其他操作。--privileged --pid=host
对我来说足够了。
If you deploy to other OSes or embedded targets, you can run gdbserver or a gdb stub there, and run gdb the same way, connecting across a real network or even via a serial port (/dev/ttyS0
).
如果您部署到其他操作系统或嵌入式目标,您可以在那里运行 gdbserver 或 gdb 存根,并以相同的方式运行 gdb,通过真实网络甚至通过串行端口 ( /dev/ttyS0
) 进行连接。