- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个生成 Bus error (core dumped)
消息的二进制文件。当我在调试器 (gdb
) 下运行它时,它无法访问 .bss
部分中的内存位置。
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/maps 一起)将此内存显示为已映射:
(gdb) info proc mappingsprocess 16533Mapped 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 filesSymbols 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...
并且 Segments 将此内存显示为已映射:
% 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 0x63d7cc0x63d7cc: Cannot access memory at address 0x63d7cc(gdb) x 0x63cff80x63cff8: 0x00000000(gdb) x 0x63cffc0x63cffc: 0x00000000(gdb) x 0x63cffd0x63cffd: Cannot access memory at address 0x63d000
问题是:
是什么阻止了这种访问?
还有哪些其他方法可用于检查运行时内存访问权限?
还有什么可以修改正在运行的进程的访问权限?
最佳答案
The code at this location is:
.bss
通常是不可执行的,所以很可能这就是您在尝试跳转到它时得到 SIGBUS
的原因。
您的 readelf
输出显示 RW
标志(注意缺少 E
xecutable 标志)。
您需要先mprotect
该部分以添加执行权限。
请注意,某些环境,例如SELinux
,禁止使用RWE
进行内存映射,将映射更改为R-E
会导致程序无法写入其(通常可写的)全局数据。这就是为什么将可执行代码放入 .bss
可能不是最好的主意。
关于无法访问 .bss 部分中的内存,但 gdb 'info files' 显示地址在范围内,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45360082/
我一直假设链接器分配了任何库的 bss 部分并将其映射到进程中。该部分的大小将取决于库报告的 bss 的大小。 我查看了进程的/proc/[PID]/maps 文件,并计算了加载库的 bss 部分的大
这个问题已经有答案了: No .BSS in PE file (2 个回答) 已关闭 6 年前。 我使用 NASM 组装了以下代码: global _start section .data v
我正在编写一些适用于 .o 文件的自定义 ELF 二进制后处理代码。部分处理包括对二进制数据执行重定位。输入文件由 GNU 汇编程序根据我自己的汇编代码生成。 看看 GNU 汇编程序生成的这些疯狂的重
“.bss”命令在 MSP430 汇编代码中起什么作用?例如,“.bss beep_cnt,2”对变量 beep_cnt2 有何作用? .bss beep_cnt,2
我知道 BSS 段存储未初始化的全局和静态变量并将它们初始化为零。但是如果全局/静态变量被初始化并且我的第二个问题是我读到 BSS 段不消耗内存,那么它存储这些变量的位置呢?谢谢 最佳答案 您可能读到
我一直在研究减少应用程序的内存占用。继上一个问题后:GDB - can I find large data elements in memory我已经找到并删除了大多数最大的罪魁祸首。 nm --si
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: .bss section in elf file 你好, BSS(Block started by symb
这个问题在这里已经有了答案: Why is the .bss segment required? (6 个答案) 关闭 4 年前。 .bss 部分的意义是什么,因为我们已经有单独的数据部分。它比数据
这个问题在这里已经有了答案: Why is the .bss segment required? (6 个答案) 关闭 6 年前。 在C编程中,当一个程序执行时,程序中使用的所有数据都会被放在不同的
这是简短的控制台应用程序示例 static char buffer[4096]; int main() { for(int i=0;i<4096;i++) { buffer[i
正如我们所知,.bss 包含未初始化的变量。如果在 C 代码中,程序员在使用它们之前初始化变量。那么在执行 C 代码之前.bss 不必为零。 我说得对吗? 谢谢 最佳答案 在 C 代码中,任何具有静态
我正在使用一个测试程序来了解内核版本为 2.6.32-279.el6.x86_64 的 linux 6.3 上的 C 内存模型。 首先我编译了下面的代码, #include int main(voi
我想在编译时声明我的 C 程序中的所有变量,例如: char cache[CACHE_SIZE]; char udp_ring[MAX_UDP_PACKET_SIZE*MAX_REQUESTS]; i
我知道 .bss 的默认对齐方式对于 GCC 是 8 字节,正如这个问题中提到的 Why the int type takes up 8 bytes in BSS section but 4 byte
我有一个功能: void testfunction() { static char_t theChar1 = 1; static unsigned char smallArray[1]; sta
据我所知,如果设置了 -fzero-initialized-in-bss,则未明确初始化的静态变量(并且对于 GCC,即使是那些明确初始化为零的变量,默认情况下就是这种情况)通常存储在 BSS 段中。
静态内存布局的 BSS 部分 [应该] 用于“未初始化的全局变量”或“设置为 0 的全局变量”。 我正在运行一些测试,突然注意到局部静态变量也在增加 BSS 段的大小。 例子:- 在任何静态变量之前
静态内存布局的 BSS 部分 [应该] 用于“未初始化的全局变量”或“设置为 0 的全局变量”。 我正在运行一些测试,突然注意到局部静态变量也在增加 BSS 段的大小。 例子:- 在任何静态变量之前
我正在学习虚拟内存管理和进程内存分配。并对此做一些实验。有以下一些容易混淆的地方: 案例1 #include int main() { return 0; } 编译代码并使用二进制文件运行
希望有人能帮助我了解我在大学学习的一个漏洞。 在c代码中有一个未绑定(bind)的strcat strcat(buffer, argv[1]); 目的是将该缓冲区溢出到保存的 EIP 中,并让它显示在
我是一名优秀的程序员,十分优秀!