我有一个生成Bus error (core dumped)
消息的二进制文件。当我在调试器 ( gdb
) 下运行它时,它无法访问该.bss
部分中的内存位置。
程序收到信号 SIGBUS,总线错误。 0x0000000000412275 在?? ()
这个位置的代码是:
41226f:0f 8f 33 ff ff ff jg 4121a8 412275: 8b 35 51 b5 22 00 移动 0x22b551(%rip),%esi # 63d7cc 41227b: 85 f6 测试%esi,%esi
所以它试图访问0x63d7cc
明显在该.bss
部分内的位置的内存:0x63c4e0 - 0x63d7e0
.
gdb
(与 /proc/$pid/maps 一起)将此内存显示为已映射:
(gdb) info proc 映射 进程 16533 映射地址空间: 开始地址结束地址大小偏移objfile 0x400000 0x43a000 0x3a000 0x0 /somepath/someapp 0x639000 0x63e000 0x5000 0x39000 /somepath/someapp 0x63e000 0x65f000 0x21000 0x0 [堆]
(gdb) 信息文件 来自“/somepath/someapp”的符号。 ... 0x0000000000639c80 - 0x000000000063c498 是 .data 0x000000000063c4e0 - 0x000000000063d7e0 是 .bss
ELF部分的两个检查:
% readelf -S someapp ... [24] .data 程序 0000000000639c80 00039c80 0000000000002818 0000000000000000 西澳 0 0 32 [25] .bss NOBITS 000000000063c4e0 0003c498 0000000000001300 0000000000000000 西澳 0 0 32 [26] .gnu_debuglink 程序 0000000000000000 0003c498 000000000000000c 0000000000000000 0 0 1 ...
和 Segments 将此内存显示为已映射:
% readelf -l 一些应用程序 ... 加载 0x00000000000000000 0x0000000000400000 0x0000000000400000 0x000000000003976c 0x000000000003976c RE 200000 加载 0x0000000000039770 0x0000000000639770 0x0000000000639770 0x0000000000004070 0x0000000000004070 读写 200000 ...
但gdb
无法访问它(以及应用程序失败的原因)。有趣gdb
的是能够访问.bss
内存直到0x63d000
:
(gdb) x 0x63d7cc 0x63d7cc:无法访问地址 0x63d7cc 的内存 (gdb) x 0x63cff8 0x63cff8: 0x00000000 (gdb) x 0x63cffc 0x63cffc: 0x00000000 (gdb) x 0x63cffd 0x63cffd:无法访问地址 0x63d000 处的内存
问题是:
什么会阻止这种访问?
还有哪些其他方法可以检查运行时内存访问权限?
还有什么可以修改正在运行的进程的访问权限?