我有一个生成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 处的内存
问题是:
什么会阻止这种访问?
还有哪些其他方法可以检查运行时内存访问权限?
还有什么可以修改正在运行的进程的访问权限?