bug: mmap 没理解好导致的Bus error (core dumped)

本文通过一个实例介绍了由于不正确使用mmap导致的Bus error和程序崩溃问题。在调试中发现,当尝试一次性映射超过文件长度的数据时,会出现这个问题。解决方案是分段进行映射,确保BUF_SIZE_W不超过实际文件长度,以避免core dump的发生。

Bus error (core dumped) 

 

gdb:

Program received signal SIGBUS, Bus error.
0x00000000004027c0 in MyTask::finish_the_work (this=0x7fffffffd7c0) at task.cc:233
233            p_w[i]=data_[i];
(gdb)

 

 

 

部分代码:

	
	int	off_r=0;
	int	off_w=0;
	//const char *filename_read = filename.c_str();//filename 
	//fd_r = open(filename_read,O_RDWR);
	//assert(fd_r);

	filename_write="letter";
	//fd_w = open(filename_write,O_RDWR|O_CREAT|O_TRUNC|O_APPEND,0644);
	fd_w = open(filename_write,O_RDWR|O_CREAT|O_TRUNC,0644);
	assert(fd_w);

	//length_r = lseek(fd_r,0,SEEK_END);
	//length_w = lseek(fd_w,BUF_SIZE_W,SEEK_CUR);
	
	cout<<"length_r:"<<length_r<<endl;
	//cout<<"length_w:"<&l
`Bus error (core dumped)` 是一种在程序运行时发生的严重错误,通常表明程序试图访问系统总线(bus)无法处理的内存地址或访问方式。这种错误会导致程序异常终止,并生成一个核心转储文件core dump),用于后续的调试分析。 ### 错误的含义 `Bus error` 的名称来源于硬件层面的“总线”概念,它通常与内存访问的对齐问题或无效的内存映射有关。当程序尝试访问未正确对齐的内存地址,或者尝试访问一个无效的内存区域(例如,未映射的内存或受保护的内存区域),就会触发 `SIGBUS` 信号,从而导致程序终止并生成核心转储文件。 ### 可能的产生原因 1. **内存对齐问题** 某些处理器架构要求数据在内存中必须按照特定的边界对齐(例如,4字节对齐或8字节对齐)。如果程序尝试访问未正确对齐的数据,可能会导致 `Bus error`。这种情况在处理结构体或直接操作内存时尤为常见。 2. **无效的内存访问** 程序可能尝试访问一个未映射的内存地址,或者访问了一个受保护的内存区域。例如,使用 `mmap` 函数映射文件时,如果文件的大小不足以覆盖程序试图访问的内存区域,可能会导致 `Bus error` [^3]。 3. **指针操作不当** 如果程序中的指针操作不当,例如直接赋值指针而未实际拷贝数据内容,可能会导致访问无效的内存地址。例如,在图像数据处理中,如果直接使用 `=` 赋值 `unsigned char*` 类型的指针,而未使用 `memcpy()` 拷贝实际数据内容,可能会导致 `Bus error` [^4]。 4. **共享内存不足** 在某些情况下,特别是在容器化环境中(如 Docker),如果程序需要较大的共享内存,但系统未分配足够的共享内存,也可能导致 `Bus error`。例如,在运行 PyTorch 相关的 Docker 容器时,可以通过增加共享内存来避免此类问题 [^5]。 5. **特定版本的软件缺陷** 某些版本的编程语言或框架可能存在特定的缺陷,导致 `Bus error`。例如,在 Node.js 的 7.x 版本中,某些代码可能导致 `Bus error`,而在 6.9.4 版本中则不会出现此问题 [^2]。 ### 调试与解决方法 1. **检查系统日志** 可以通过 `dmesg` 命令查看系统日志,获取更详细的错误信息。例如,使用 `dmesg | grep -i bus` 可以过滤出与 `Bus error` 相关的日志信息 [^1]。 2. **使用调试工具** 可以使用 `gdb` 等调试工具分析核心转储文件,定位具体的错误位置。例如,通过 `gdb` 可以查看程序崩溃时的堆栈信息,从而确定问题的根源 [^3]。 3. **确保内存对齐** 在处理结构体或直接操作内存时,确保数据在内存中的对齐方式符合处理器的要求。 4. **检查指针操作** 确保在处理指针时,不仅赋值指针本身,还需要拷贝实际的数据内容。例如,在处理图像数据时,使用 `memcpy()` 而不是直接赋值指针 [^4]。 5. **增加共享内存** 在容器化环境中,确保分配了足够的共享内存。例如,在运行 Docker 容器时,可以使用 `--shm-size` 参数增加共享内存的大小 [^5]。 ### 示例代码 以下是一个简单的示例,展示了如何使用 `memcpy()` 正确拷贝图像数据: ```c #include <cstring> void copyImageData(unsigned char* dest, const unsigned char* src, size_t size) { memcpy(dest, src, size); } ``` 在调试 `Bus error` 时,可以使用 `gdb` 分析核心转储文件: ```bash gdb ./my_program core ``` 在 `gdb` 中,可以使用 `bt` 命令查看堆栈信息: ```gdb (gdb) bt ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值