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

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

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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
<think>我们正在处理一个在Debian系统中运行程序时遇到的"mmap error: Operation not permitted"错误。根据提供的引用信息,特别是引用[1]中提到的: "Profiler为目标进程的每个线程分配8kB性能事件缓冲区,在非特权用户下运行时,请确保/proc/sys/kernel/perf_event_mlock_kb值足够大(大于8*总的线程数),否则将打印消息“perf_event mmap failed:Operation not allowed”,并且不会收集本机堆栈跟踪;" 这个错误通常与`perf_event_mlock_kb`设置有关,该设置限制了非特权用户可以锁定的内存量(用于性能事件缓冲区)。如果这个值设置得太小,当程序尝试分配性能事件缓冲区时,就会遇到“Operation not permitted”错误。 因此,解决方案是增加`perf_event_mlock_kb`的值,使其大于8kB乘以程序运行时的线程总数。 具体步骤: 1. 检查当前的`perf_event_mlock_kb`值: ```bash cat /proc/sys/kernel/perf_event_mlock_kb ``` 2. 计算程序运行时的总线程数,然后乘以8(因为每个线程需要8kB)。如果无法确定确切的线程数,可以设置一个较大的值(例如,如果系统有多个线程,可以设置为512或1024)。 3. 临时修改(重启后失效): ```bash sudo sysctl kernel.perf_event_mlock_kb=<新值> ``` 例如:`sudo sysctl kernel.perf_event_mlock_kb=1024` 4. 永久修改(需要编辑sysctl配置文件): - 打开或创建配置文件:`/etc/sysctl.conf` 或者 `/etc/sysctl.d/`目录下的文件(例如`/etc/sysctl.d/99-perf.conf`)。 - 添加一行:`kernel.perf_event_mlock_kb = <新值>` - 保存并退出,然后运行:`sudo sysctl -p`(对于`/etc/sysctl.conf`)或`sudo sysctl -p /etc/sysctl.d/99-perf.conf`(如果使用该文件)来使更改生效。 注意:如果程序运行在容器中,可能需要调整容器的权限或者宿主机的设置。 另外,引用[2]中提到了一个可能相关的修复(虽然不直接是mmap错误,但也是权限问题),但当前问题更符合引用[1]的描述。 如果上述方法不能解决问题,还需要考虑其他可能导致mmap操作被拒绝的原因,例如: - 文件系统权限(如果mmap的是文件,确保有读权限) - 内存限制(如ulimit设置) - SELinux或AppArmor安全策略 - 内存地址空间不足(可能性较小) 但根据错误信息和引用,我们首先应该尝试调整`perf_event_mlock_kb`。 §§相关问题§§ 1. 如何检查当前系统的线程数限制? 2. 除了`perf_event_mlock_kb`,还有哪些系统参数可能影响mmap操作? 3. 如何诊断程序运行时的线程数量?</think>### Debian系统中运行程序出现"mmap error: Operation not permitted"的原因与解决方案 #### 错误原因分析 根据引用[1]的信息,当在非特权用户下运行时,如果系统参数`/proc/sys/kernel/perf_event_mlock_kb`的值不足,会导致`mmap`操作失败并出现"Operation not permitted"错误。具体机制是: 1. 分析器为每个线程分配**8kB性能事件缓冲区** 2. 所需总内存 = `8kB × 线程总数` 3. 当`perf_event_mlock_kb < 8 × 线程数`时,系统拒绝内存映射操作[^1] #### 解决方案 **步骤1:检查当前值** ```bash cat /proc/sys/kernel/perf_event_mlock_kb ``` **步骤2:计算所需值** ```bash # 获取目标进程的线程数(替换<pid>为实际进程ID) ps -T -p <pid> | wc -l # 所需值 = 线程数 × 8 ``` **步骤3:临时修改(重启失效)** ```bash sudo sysctl kernel.perf_event_mlock_kb=<新值> # 示例:sudo sysctl kernel.perf_event_mlock_kb=2048 ``` **步骤4:永久修改** ```bash # 编辑配置文件 sudo nano /etc/sysctl.conf # 添加以下内容(示例值) kernel.perf_event_mlock_kb = 2048 # 应用配置 sudo sysctl -p ``` **步骤5:验证结果** ```bash # 检查新值是否生效 cat /proc/sys/kernel/perf_event_mlock_kb ``` #### 其他可能原因 1. **SELinux/AppArmor限制** 检查安全模块日志: ```bash sudo dmesg | grep -i denied sudo aa-status ``` 2. **文件系统权限问题** 确保目标文件有读权限: ```bash ls -l /path/to/mapped_file chmod +rw /path/to/mapped_file ``` 3. **内存限制** 检查用户内存限制: ```bash ulimit -a | grep locked # 修改限制(临时) ulimit -l unlimited ``` #### 补充说明 - 对于容器环境(如Docker),需在宿主机修改参数 - 如果使用性能分析工具(如perf),需同时确保`kernel.perf_event_max_stack`设置合理[^1] - 内核版本要求:Linux 4.8+ 支持动态调整这些参数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值