使用共享内存时出现分段错误

Posted

技术标签:

【中文标题】使用共享内存时出现分段错误【英文标题】:Segmentation fault while using shared memory 【发布时间】:2020-02-15 10:18:55 【问题描述】:

此代码执行以下操作: 读取“读取”文本文件的内容并将其写入共享内存空间。代码一直工作到昨天,但相同的代码今天显示分段错误。你能帮我弄清楚我在哪里犯了错误吗?

#include<sys/ipc.h>
#define NULL 0
#include<sys/shm.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h> 
#include<sys/wait.h> 
#include<ctype.h>
#include<fcntl.h>
#include<stdio_ext.h>

int main()


char *a;
char name[20];
int id,n;
char buf[50];
int fd;
fd=open("read",O_RDONLY);   
int s1=read(fd,&buf,50);

id=shmget(200,50,IPC_CREAT);

    a=shmat(id,NULL,0);
    strcpy(a,buf);
    wait(NULL);
    shmdt(a);

shmctl(id,IPC_RMID,NULL);
return 0;

 

【问题讨论】:

如果您通过验证所有函数调用的返回值来进行错误处理,您将拥有更健壮的代码并发现它更容易调试。例如,如果open 返回-1,则程序应使用perror 打印错误,然后退出。 您确定从您的文件中读取的数据包含终止空字节吗?如果没有,您的strcpy 将溢出。改用memcpy 不是更安全吗? 另外,wait(NULL) 的意义何在?您的进程此时没有子进程,因此它只会立即返回-1(您从不检查)。这条线的目的是什么? 【参考方案1】:

您必须检查您在代码中使用的每个函数的返回值。调用strcpy(a,buf); 时出现分段错误。如果您检查a 的值,它没有有效的内存地址,那是因为您从未检查过从shmat() 调用返回的值,您需要仔细检查此函数所采用的参数(手册页)。

下面,我评论了段错误发生的位置:

int main()

  //char name[20]; // never used
  int id; 

  char *a;
  char buf[50];
  int fd;
  fd=open("read",O_RDONLY); // check return value
  //make sure you provide the correct path for your "read" text file
  int restlt = read(fd,&buf,50); // check return value


  key_t mem_key = ftok(".", 'a');
  id = shmget(mem_key, 50, IPC_CREAT | 0666);
  //id = shmget(200,50,IPC_CREAT); //check the return value
  if (id < 0) 
      printf("Error occured during shmget() call\n");
      exit(1);
  
  a = shmat(id,NULL,0); //check the return value
  if ((int) a == -1) 
       printf("Error occured during shmat() call\n");
       exit(1);
  
  printf("Value of pointer a = %p \n", a);
  strcpy(a,buf); // better to use strncpy(a, buf, n);

  printf("Value of a[0]  = %c \n", *a);

  wait(NULL);
  shmdt(a);
  shmctl(id,IPC_RMID,NULL);

  return 0;

 

查看此链接:http://www.csl.mtu.edu/cs4411.ck/www/NOTES/process/shm/shmat.html

【讨论】:

以上是关于使用共享内存时出现分段错误的主要内容,如果未能解决你的问题,请参考以下文章

尝试锁定共享内存互斥体时出现分段错误

访问共享进程内存时出现分段错误(核心转储)

Linux 共享内存分段错误

通过共享内存和管道的 IPC 给出分段错误:C 中的 11

查询从内存映射文件中检索的 Rtree 时出现分段错误

尝试从 docker 容器访问共享内存时出现“权限被拒绝”,即使 --ipc 设置为“主机”