【发布时间】:2016-04-23 16:54:37
【问题描述】:
问题
如果我从主机编译和运行,我可以设置并到达断点,但如果我从 docker 容器中执行此操作,gdb 不会到达设置的断点。
重现步骤(所有 sn-ps 都已准备好复制粘贴)
创建一个 docker 文件:
cat << EOF > Dockerfile
FROM ubuntu
RUN apt-get update
RUN apt-get install -y build-essential gdb
EOF
构建映像并在其中运行交互式会话:
docker build -t gdb_problem_testing . && docker run --rm -it gdb_problem_testing bash
从容器内部创建小的 main.cpp,编译并运行 gdb:
cat <<EOF > main.cpp && g++ -g main.cpp && gdb -ex 'break 5' -ex 'run' ./a.out
#include <iostream>
int main(int argc, const char *argv[])
{
std::cout << "hi\n";
return 0;
}
EOF
观察 gdb 输出:
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
[Skipped gdb greeting]
Reading symbols from ./a.out...done.
Breakpoint 1 at 0x40078c: file main.cpp, line 5.
1 #include <iostream>
2
3 int main(int argc, const char *argv[])
4 {
5 std::cout << "hi\n";
6 return 0;
7 }
Starting program: /a.out
hi
During startup program exited normally.
(gdb)
从输出可以看出断点没有被命中,虽然程序被执行(打印'hi')并成功退出。我想这里最重要的是程序确实运行了,并且消息在启动程序正常退出期间是一种异常行为(根据GDB ignores my breakpoints)
问题
是什么阻止了 gdb 设置断点以及如何解决这个问题?
到目前为止我尝试了什么
按照here 的建议,我尝试在
/etc/apparmor.d/docker中更改一行(我是在主机中完成的): 将profile docker-default flags=(attach_disconnected,mediate_deleted) {替换为profile docker-default flags=(attach_disconnected,mediate_deleted,complain) {。然后运行docker容器,编译,gdb。结果是一样的:During startup program exited normally。-
按照another answer 中的建议,在容器内,我尝试执行
strace -f -o syscall.txt gdb ./a.out,但出现以下错误:strace: test_ptrace_setoptions_followfork: PTRACE_TRACEME doesn't work: Permission denied strace: test_ptrace_setoptions_followfork: unexpected exit status 1但我不明白如何解决这个问题。我尝试以 root 身份启动容器:
sudo docker run --rm -it gdb_problem_testing bash,然后尝试了 strace——这给了我同样的错误。我必须承认我不明白 docker 是如何管理用户权限的,即容器内的 root 拥有哪些用户权限以及它从谁那里继承了这些权限(来自 docker 守护进程?)。由于我能够打断点,所以当我在主机中运行 gdb 时,我怀疑我的问题会归结为用户权限,但我不知道如何解决。 在主机中,我尝试按照 another answer 中的建议执行
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope。
【问题讨论】:
-
您的主机操作系统是什么(发行版和内核版本)?我们可以尝试重现错误。您的示例运行良好 - gdb 在第 5 行成功停止 - 在 Ubuntu 15.04 和 14.04.3 x86_64 的香草、完全修补版本上使用 Ubuntu 14.04.2 的 docker 映像。
-
非常感谢您试一试。它对你有用的事实给了我一个完全不同的观点。我的主机操作系统是 Ubuntu。 $ uname -a Linux LT0377 3.19.0-42-generic #48~14.04.1-Ubuntu SMP Fri Dec 18 10:24:49 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux。我不明白 Docker 映像中的 Ubuntu 版本是什么。如果我在容器内执行 uname -a 操作,我会得到与主机相同的输出。
-
@MarkPlotnick 你能告诉我你的 Docker 版本是什么吗?
-
我使用了 Ubuntu 存储库中的 docker 版本。在 14.04.3 和 15.04 上,它都是
Docker version 1.6.2, build 7c8fca2。 -
docker 存储库中的
ubuntu映像似乎是 14.04.3;我错了,它是 14.04.2。
标签: linux debugging permissions docker gdb