gdb -p 失败主因是内核 ptrace 限制:yama/ptrace_scope=1(默认)仅允附着子进程;目标进程被其他调试器占用、启用 ptrace 保护(如容器/setuid)、或无权限读 /proc//mem。

必须用 gdb -p <pid></pid> 附着,且目标进程不能被其他调试器占用、未被 ptrace 保护,否则会报 Operation not permitted 或 Permission denied
为什么 gdb -p <pid></pid> 会失败
常见错误现象是输入命令后立即退出,或提示 Cannot attach to process、Operation not permitted。这不是 gdb 本身的问题,而是内核级限制在起作用。
-
/proc/sys/kernel/yama/ptrace_scope值为1(默认)时,只允许调试子进程;附着到任意进程需设为0(需 root 权限) - 目标进程启用了
PR_SET_DUMPABLE以外的 ptrace 保护(如某些容器、systemd 服务或 setuid 程序),即使你是 root 也无法附着 - 进程已由另一个调试器(如 strace、另一实例 gdb)占用,
ptrace不允许多重 attach - 你没有权限读取该进程的内存映射(
/proc/<pid>/mem</pid>不可访问),gdb就无法读符号和堆栈
gdb -p <pid></pid> 成功后的关键操作
附着成功后,进程默认处于暂停状态(STOP),但 gdb 不会自动显示源码——因为很可能没加载调试信息,或当前执行位置不在你关心的函数里。
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
- 先运行
info proc mappings确认可执行文件路径,再用file /path/to/binary手动加载符号(尤其当进程是动态链接、且LD_LIBRARY_PATH被修改过时) - 用
bt查看当前调用栈;如果显示#0 0x... in ?? (),说明符号缺失,需确保二进制带-g且未 strip - 用
info threads检查是否多线程;若要切换线程,用thread <n></n>,再bt或info reg - 想继续运行但又不想 detach,用
c;想单步执行当前线程,用s或n(注意:其他线程仍可能并发运行) - 不能直接
print局部变量(除非当前帧有调试信息),但可以x/4xw $rsp查栈内容,或info registers看寄存器
附着后如何安全退出而不杀进程
很多人误用 quit 或 q,结果发现进程直接终止了——这是因为 gdb 默认在 detach 前会向进程发 SIGSTOP,而某些环境(如 systemd)会将未恢复的 STOP 视为异常退出。
- 正确做法是先执行
detach,它会让 gdb 断开连接并自动恢复进程运行(等价于向进程发SIGCONT) - 确认 detach 成功后,再输入
quit退出 gdb;此时进程完全不受影响 - 如果已经
quit退出但进程卡在T(TASK_STOPPED)状态,可用kill -CONT <pid></pid>手动唤醒 - 切勿在 attach 后直接
kill,那等于强制终止进程
真正难的不是命令怎么输,而是判断「这个进程到底能不能被 attach」——得先看 /proc/<pid>/status</pid> 里的 CapBnd 和 TracerPid,再查 yama 设置,最后才轮到 gdb。很多线上问题卡在这一步,不是不会用 gdb,是根本没权限碰它。

















