升级后,gdb不会附加到进程中


66

我最近刚从10.04升级到11.04,gdb不允许我再附加到进程,我得到了错误

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

如何解决此问题,以便无需sudo即可再次调试?

Answers:


105

在Maverick Meerkat(10.10)中,Ubuntu引入了一个修补程序,以禁止非root用户(即)跟踪非子进程。只有作为另一个进程的父进程的进程才能为普通用户跟踪它-而root仍然可以跟踪每个进程。因此,为什么可以使用gdb仍然通过sudo进行附加。

您可以通过以下方法暂时禁用此限制(并恢复为允许用户使用ptrace(gdb)其他任何进程的旧行为):

echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope

要永久地允许它编辑/etc/sysctl.d/10-ptrace.conf并更改该行:

kernel.yama.ptrace_scope = 1

读书

kernel.yama.ptrace_scope = 0

有关为何进行此更改的一些背景信息,请参见Ubuntu Wiki。


4
谢谢。我将临时文件添加到用户bin文件中的命令中,以便可以将其打开和关闭。
安德鲁·雷德

我编辑/etc/sysctl.d/10-ptrace.conf文件。它非常适合我。:)
soroosh

8
如果您对/etc/sysctl.d中的文件进行了一些编辑,则可以通过“ sudo service procps restart”自动应用它们
弗兰克斯特(Frankster)2013年

@alexmurray-您的有用回答还应该指出,必须先进行某种重启才能使更改/etc/sysctl.d生效。对我来说,重新启动系统就足够了,但可能已经过头了-请参阅上方的弗兰克斯特评论。重新启动后,from的值/etc/sysctl.d被复制到中/proc/sys/kernel/yama/ptrace_scope。(此外,就我而言,即使使用sudo,我也无法直接编辑ptrace_scope。)
Andy Thomas

无需重新启动。只需运行:sysctl -p/etc/sysctl.conf和应用更改即可/etc/sysctl.d/*。对于此特定更改,在Ubuntu 15.04 Vivid中,文件为/etc/sysctl.d/10-ptrace.conf
Mircea Vutcovici 2015年

3

如果您希望将/proc/sys/kernel/yama/ptrace_scope其设置保留为默认值1,那么作为一种解决方法,您可以考虑使用gdb运行您要调试的程序。然后,您只需按即可启动调试器^C。例如,要调试(无聊)程序sleep 60,请执行以下操作:

$ gdb -q sleep -ex 'run 60'

这是一个完整的例子。

$ gdb -q sleep -ex 'run 60'
Reading symbols from sleep...(no debugging symbols found)...done.
Starting program: /bin/sleep 60
^C
Program received signal SIGINT, Interrupt.
0x00007ffff7ad5d60 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:81
81      ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) backtrace
#0  0x00007ffff7ad5d60 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:81
#1  0x0000000000403cd7 in ?? ()
#2  0x0000000000403b88 in ?? ()
#3  0x00000000004016c9 in ?? ()
#4  0x00007ffff7a35ec5 in __libc_start_main (main=0x401540, argc=2, argv=0x7fffffffea08, init=<optimized out>, 
    fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe9f8) at libc-start.c:287
#5  0x00000000004017d5 in ?? ()
(gdb) continue
Continuing.
[Inferior 1 (process 3531) exited normally]
(gdb) quit

由于/bin/sleep(毫无意外地)编译时没有调试信息,因此上述回溯包含的信息很少。


2
您没有附加,而是启动了它。这是完全不同的,因为在这种情况下gdb,调试对象是调试对象的直接父对象,即使使用,也拥有调试它的一切权利ptrace_scope==1。如果您改为附加它,那是行不通的,即做了类似的事情sleep 60& gdb -ex "attach $!"
Ruslan 2016年

Ruslan提出的(计数器?)示例sleep 60& gdb -ex "attach $!"不是“使用gdb运行程序”,因此不是对我工作的质疑。Ruslan的示例是使用shell首先运行sleep,然后再运行gdb。我的解决方法有效,这是我所关心的。我不知道,也不管我是否真的在乎gdb它的孩子。我关心能够调试孩子。我的解决方法可以达到目的。尽管如此,为了清楚起见,我已经改写了我的答案。
mpb
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.