无法访问.bss部分中的内存,但gdb'info files'显示地址范围在

问题描述:

我有一个生成Bus error (core dumped)消息的二进制文件。当我在调试器(gdb)下运行它时,它无法访问.bss部分中的内存位置。无法访问.bss部分中的内存,但gdb'info files'显示地址范围在

 
Program received signal SIGBUS, Bus error. 
0x0000000000412275 in ??() 

在这个位置的代码是:

 
    41226f:  0f 8f 33 ff ff ff  jg  4121a8 
    412275:  8b 35 51 b5 22 00  mov 0x22b551(%rip),%esi  # 63d7cc 
    41227b:  85 f6     test %esi,%esi 

因此,它试图在位置0x63d7cc这显然是.bss段内访问内存:0x63c4e0 - 0x63d7e0

gdb(有/ PROC/$ PID /地图一起)示出了为映射此存储器:

 
(gdb) info proc mappings 
process 16533 
Mapped address spaces: 

      Start Addr   End Addr  Size  Offset objfile 
      0x400000   0x43a000 0x3a000  0x0 /somepath/someapp 
      0x639000   0x63e000  0x5000 0x39000 /somepath/someapp 
      0x63e000   0x65f000 0x21000  0x0 [heap] 
 
(gdb) info files 
Symbols from "/somepath/someapp". 
... 
     0x0000000000639c80 - 0x000000000063c498 is .data 
     0x000000000063c4e0 - 0x000000000063d7e0 is .bss 

ELF节的两个检查:

 
% readelf -S someapp 
... 
    [24] .data    PROGBITS   0000000000639c80 00039c80 
     0000000000002818 0000000000000000 WA  0  0  32 
    [25] .bss    NOBITS   000000000063c4e0 0003c498 
     0000000000001300 0000000000000000 WA  0  0  32 
    [26] .gnu_debuglink PROGBITS   0000000000000000 0003c498 
     000000000000000c 0000000000000000   0  0  1 
... 

和段示出该存储器如图所示:

 
% readelf -l someapp 
... 
    LOAD   0x0000000000000000 0x0000000000400000 0x0000000000400000 
       0x000000000003976c 0x000000000003976c R E 200000 
    LOAD   0x0000000000039770 0x0000000000639770 0x0000000000639770 
       0x0000000000004070 0x0000000000004070 RW  200000 
... 

gdb无法访问它(以及应用程序失败的原因)。有趣的是gdb能够访问.bss存储起来,直到0x63d000

 
(gdb) x 0x63d7cc 
0x63d7cc:  Cannot access memory at address 0x63d7cc 
(gdb) x 0x63cff8 
0x63cff8:  0x00000000 
(gdb) x 0x63cffc 
0x63cffc:  0x00000000 
(gdb) x 0x63cffd 
0x63cffd:  Cannot access memory at address 0x63d000 

的问题是:
什么能阻止这一访问?
还有哪些其他方法可用于检查运行时内存访问权限?
还有什么可以修改正在运行的进程的访问权限?

+0

也许告诉我们一些关于你如何构建应用程序和这是什么平台。如果你尝试创建一个[MCVE](https://*.com/help/mcve)会很好,你可能会通过尝试创建它而发现错误。 – Downvoter

+0

核心文件和可执行文件可能不匹配。 –

+0

这是在桌面/服务器平台上还是在嵌入式系统上?如果是嵌入式系统,您是使用来自电路板供应商的经过测试的,经过验证的BSP,还是家庭酿造? – phonetagger

在这个位置的代码是:

.bss是不正常的可执行文件,所以可能这就是为什么你想跳,就当越来越SIGBUS

您的readelf输出显示RW标志(注意缺少E xecutable标志)。

您将需要mprotect该部分先添加执行权限。

注意某些环境中,如SELinux,禁止存储器映射带RWE,并且改变所述映射以将R-E导致程序不能够写入其(通常可写的)全局数据。这就是为什么把可执行代码放入.bss可能不是最好的想法之一。