c - 在 docker 下运行 objdump 显示不同的结果
问题描述
假设这段c
代码:
int main(){
return 0;
}
gcc
在正常运行的linux机器下编译,运行objdump -d
输出如下:
00000000004004cd <main>:
4004cd: 55 push %rbp
4004ce: 48 89 e5 mov %rsp,%rbp
4004d1: b8 00 00 00 00 mov $0x0,%eax
...
我可以使用地址轻松地breakpoints
在 gdb 中设置。0x4004cd
在 Docker 容器中执行相同操作在左侧 ( 5fa
) 侧有奇怪的内存地址,我无法在它们上设置断点。为什么会这样?
00000000000005fa <main>:
5fa: 55 push %rbp
5fb: 48 89 e5 mov %rsp,%rbp
5fe: b8 00 00 00 00 mov $0x0,%eax
解决方案
为什么会这样?
Docker 容器中的编译器默认配置为构建与位置无关的可执行文件。
您可以通过运行来验证这一点file a.out
,它应该显示ELF 64-bit LSB pie executable
在 docker 和ELF 64-bit LSB executable, x86-64
它之外。
您可以使用以下命令禁用构建 PIE:gcc -no-pie -fno-pie ...
。
我不能在他们身上断点
您不能在指令处设置断点,0x5fa
因为那不是二进制文件实际运行的地址。相反,请执行以下操作:
(gdb) start
(gdb) disas main
上面的命令将显示二进制文件在运行时重定位的位置,您现在应该能够在重定位的地址上设置断点。
推荐阅读
- c++ - 如何在 LLVM 后端的机器级别找到 def-use 链
- java - Log4J 文件不打印日志数据
- timezone - 如何在 Presto 中存储 UTC 日期时间/时间戳和时区以便于本地时间转换?
- javascript - 在 Angular Material 中急切地加载和注入选项卡内容
- powershell - 本地 New-PSSession 在基于官方 powershell linux 的 docker 映像中失败
- c# - 在 MVVM 上下文中隐藏满足多个条件的 DataGrid 中的行
- c# - 检索类调用者在运行时使用了哪个接口
- jquery - 在给定文本框的另一个跨度之后插入一个跨度
- datetime - Modelica 打印当前时间
- depth-first-search - 我们可以在不回溯的情况下进行 DFS 吗?