共享内存父进程无权限求助:shmat返回-1引发段错误
C语言共享内存shmat权限被拒及段错误问题
问题现象
父进程调用shmat返回-1,提示Permission denied,后续对指针解引用触发段错误;子进程shmat同样返回(void*) -1,但因未对指针操作而正常退出。原本预期父子进程均可正常挂载并操作共享内存。
代码实现
#include "sys/ipc.h" #include "sys/shm.h" #include "unistd.h" #include "sys/types.h" #include "sys/wait.h" #include "stdio.h" #include "stdlib.h" int main(){ key_t key = ftok("shmfile.txt", 65); int shmid = shmget(key, sizeof(int), IPC_CREAT); if (fork() != 0){ int * ptr = (int *) shmat(shmid, 0, 0); // 该行返回-1,仅父进程出现此情况 printf("shmid parent = %d\n", shmid); perror("Error "); *ptr = 6; shmdt(ptr); wait(NULL); shmctl(shmid, IPC_RMID, NULL); } else{ printf("shmid child = %d\n", shmid); int * ptr = (int *) shmat(shmid, 0, 0); // 符合预期运行 printf("ptr address = %p\n", ptr); shmdt(ptr); printf("Now child can exit normally"); } return 0; }
GDB调试输出
shmid parent = 45 Error : Permission denied shmid child = 45 ptr address = 0xffffffffffffffff Now child can exit normally Program received signal SIGSEGV, Segmentation fault. 0x00005555555552d0 in main () at main_2.c:20 20 *ptr = 6;
更新信息
- 更新1:父进程与子进程的
ptr均为(void *) -1,无法让shmat返回正常值 - 更新2:
shmfile.txt与可执行文件main位于同一目录
解决方案
1. 修复shmget权限参数
shmget创建共享内存时必须指定权限掩码,否则默认权限会导致进程无法挂载。修改shmget调用,在IPC_CREAT后添加权限位(例如0666,表示所有用户可读可写,可根据需求调整):
int shmid = shmget(key, sizeof(int), IPC_CREAT | 0666);
2. 添加shmat返回值检查
在使用shmat返回的指针前,必须检查是否挂载成功,避免对无效指针操作引发段错误:
int *ptr = (int *)shmat(shmid, 0, 0); if (ptr == (void*)-1) { perror("shmat failed"); exit(EXIT_FAILURE); }
原因说明
- 未指定权限位的共享内存,默认权限极低,导致进程没有挂载权限,
shmat返回-1。 - 子进程未触发段错误,是因为它没有执行
*ptr = 6;这样的指针解引用操作,而父进程对无效指针赋值直接触发了SIGSEGV信号。
内容的提问来源于stack exchange,提问作者Khang Truong
相关产品推荐
相关产品推荐

