Posix 共享内存导致总线错误

Posted

技术标签:

【中文标题】Posix 共享内存导致总线错误【英文标题】:Posix shared memory cause bus error 【发布时间】:2014-10-20 10:38:40 【问题描述】:

我在 mips 中使用了 posix 共享内存。程序抱怨:

i: 516095
i: 516096
Bus error

在 x86 中执行相同的程序是可以的。我想获得内核最大支持共享内存大小。

int ret;
int bufsize = 517120;

shmfd = shm_open(NAME_SHM, O_RDWR|O_CREAT|O_EXCL, FILE_OP);
shm_unlink(NAME_SHM);
if(shmfd < 0) 
        sys_err("Create share memory failed: %s\n", strerror(errno));
        exit(-1);


ret = ftruncate(shmfd, bufsize);
if(ret < 0) 
        sys_err("Alloc share memory failed: %s\n", strerror(errno));
        exit(-1);


char *ptr = mmap(NULL, bufsize,
        PROT_READ|PROT_WRITE, MAP_SHARED, shmfd, 0);
if(ptr == MAP_FAILED) 
        sys_err("Mmap failed: %s\n", strerror(errno));
        exit(-1);


struct stat buf;
fstat(shmfd, &buf);
printf("size: %d, total: %d\n", buf.st_size, bufsize);

int i;
for(i = 0; i < bufsize; i++) 
        printf("i: %d\n", i);
        ptr[i] = 0;

我检查了 ipcs,但男人说:

Linux ipcs 实用程序与 POSIX ipcs 实用程序不完全兼容。

root@AnyWiFi:~# ipcs -lm

------ Shared Memory Limits --------
max number of segments = 4096
max seg size (kbytes) = 3
max total shared memory (pages) = 2097152
min seg size (bytes) = 1

root@AnyWiFi:~# cat /proc/sys/kernel/shmmax 
3740

root@AnyWiFi:~# cat /proc/sys/kernel/shmall
2097152

root@AnyWiFi:~# cat /proc/sys/kernel/shmmni 
4096

最大 seg 大小为 3k,但我的程序可以使用 (516096 / 1024 = 504k)?

我对 sysv ipc 和 posix ipc 感到困惑?

【问题讨论】:

为什么shm_unlink这么早就被调用了? 【参考方案1】:

shm_unlink() 只是在 shm_open() 之后调用,因此这会删除共享内存对象名称,并且一旦所有进程都取消映射该对象,就会取消分配并销毁相关内存区域的内容。成功 shm_unlink() 后,尝试 shm_open() 具有相同名称的对象将失败(除非指定了 O_CREAT,在这种情况下会创建一个新的、不同的对象)。

因此,您遇到了总线错误,这是由于处理器在其总线上检测到异常情况而导致的机器语言指令执行中的致命故障。可能是由于无效的地址对齐(访问奇数地址的多字节数)或访问其地址空间之外的内存位置不存在。

此外,您可能需要使用sysctl 命令检查资源限制并设置程序所需的正确限制(如果它更小)

$ipcs -l

------ Shared Memory Limits --------
max number of segments = 4096
max seg size (kbytes) = 32768
max total shared memory (kbytes) = 8388608
min seg size (bytes) = 1

------ Semaphore Limits --------
max number of arrays = 128
max semaphores per array = 250
max semaphores system wide = 32000
max ops per semop call = 32
semaphore max value = 32767

------ Messages Limits --------
max queues system wide = 15747
max size of message (bytes) = 8192
default max size of queue (bytes) = 16384

【讨论】:

【参考方案2】:

在 Linux 上,您可以使用 proc(5) 例如/proc/ 中的伪文件(读取速度很快;您需要像管道一样顺序读取它们并快速关闭它们)。

特别是,您可能会阅读/proc/sys/kernel/shmmax/proc/sysvipc/shm 等...

另见shm_overview(7)

您可能应该比您晚得多地致电shm_unlink(3),即在您使用完您的共享内存之后。

【讨论】:

以上是关于Posix 共享内存导致总线错误的主要内容,如果未能解决你的问题,请参考以下文章

为啥我可以使用 POSIX 创建比 /dev/shm 上安装的大小更大的共享内存?

Posix 共享内存与映射文件

Posix共享内存

POSIX 共享内存 - 有多少个内存副本

POSIX 共享内存 - 自动客户端通知的方法

POSIX 共享内存写入/读取