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

C 尝试锁定共享内存互斥锁时出现分段错误,c,mutex,shared-memory,C,Mutex,Shared Memory,共享内存互斥体上的分段错误。我有一个生产者和消费者分别处理,生产者初始化共享内存,共享内存互斥,并写入数据 使用者打开共享内存,尝试锁定和读取数据 如果没有互斥锁,使用者可以读取数据(数据将不一致,但不存在seg故障) 只有当使用者试图锁定互斥锁时,才会出现seg故障 更改了标志,结果是相同的,检查了attr和mutex inits的返回值,它们都很好 我有点迷路了,而且我对共享内存的研究还很陌生 指出的任何缺陷都会非常有用。谢谢 堆栈: Program received signal SIGS

共享内存互斥体上的分段错误。我有一个生产者和消费者分别处理,生产者初始化共享内存,共享内存互斥,并写入数据

使用者打开共享内存,尝试锁定和读取数据

如果没有互斥锁,使用者可以读取数据(数据将不一致,但不存在seg故障)

只有当使用者试图锁定互斥锁时,才会出现seg故障

更改了标志,结果是相同的,检查了attr和mutex inits的返回值,它们都很好

我有点迷路了,而且我对共享内存的研究还很陌生

指出的任何缺陷都会非常有用。谢谢

堆栈:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff79c0c8d in pthread_mutex_lock () from /lib64/libpthread.so.0
(gdb) bt
#0  0x00007ffff79c0c8d in pthread_mutex_lock () from /lib64/libpthread.so.0
#1  0x00000000004008ec in main (argc=1, argv=0x7fffffffde18 "\210\341\377\377\377\177") at cons.c:41
(gdb) p cons_ptr
$1 = (test_str_t *) 0x7ffff7ff7000
(gdb) p cons_ptr->data[0] 
$2 = 873422052  
(gdb) p cons_ptr->magic 
$3 = 43981  
(gdb) p cons_ptr->shm_lock
$4 = {__data = {__lock = 0, __count = 0, __owner = 0, __nusers = 0, __kind = 128, __spins = 0, __elision = 0, __list = {__prev = 0x0, __next = 0x0}}, 
  __size = '\000' <repeats 16 times>, "\200", '\000' <repeats 22 times>, __align = 0}
(gdb) 


// Header:  

const char *pathname = "test_shm";

typedef struct test_str_{
    uint64_t            magic;
    int                 data[1024];
    pthread_mutex_t     shm_lock;
    uint64_t            magic2;
}test_str_t;

// Producer:  

#include "test_header.h"
#include <time.h>

test_str_t *ptr;

void init_mutex(pthread_mutex_t *mutex){
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
    pthread_mutex_init(mutex, &attr);
    pthread_mutexattr_destroy(&attr);
}

int main(int argc, char *argv[]) {
    int fd, i = 0, num_int = 1024, rc = 0;
    int size = num_int * sizeof(int);
    fd = shm_open(pathname, O_CREAT|O_RDWR, 0666);
    if(fd == -1) {
        printf("\n shm_open failed \n");
        exit(0);
    }
    rc = ftruncate(fd, sizeof(test_str_t));
    ptr = (test_str_t *)mmap(NULL, sizeof(test_str_t),
                    PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
    if(ptr == MAP_FAILED) {
        printf("\n mmap failed \n");
        exit(0);
    }
    rc = init_mutex(&(ptr->shm_lock));
    if(rc != 0) {
        printf("Mutex Init failed: rc:[%d]\n", rc);
        exit(0);
    }
    ptr->magic = 0xABCD;
    ptr->magic2 = 0xEF12;
    srand(time(0));
    for(i = 0; i < 5; i++) {
        pthread_mutex_lock(&(ptr->shm_lock));
        ptr->data[i] = i;
        pthread_mutex_unlock(&(ptr->shm_lock));
    }
    return 0;
}

// Consumer:  

#include "test_header.h"
#include <time.h>

test_str_t *cons_ptr;

int main(int argc, char *argv[]) {
    int fd, i = 0, num_int = 1024, rc = 0;
    int try_lock = 0;
    int size = num_int * sizeof(int);
    fd = shm_open(pathname, O_RDONLY, 0666);
    if(fd == -1) {
        printf("\n shm_open failed \n");
        exit(0);
    }
    cons_ptr = (test_str_t *)mmap(NULL, sizeof(test_str_t),
                    PROT_READ, MAP_SHARED, fd, 0);
    if(cons_ptr == MAP_FAILED) {
        printf("\n mmap failed \n");
        exit(0);
    }
    if(cons_ptr == NULL) {
        printf("\n NULL Ptr\n");
        return 0;
    }
    printf("Magic: [0x%x] [0x%x]\n", cons_ptr->magic, cons_ptr->magic2);
    //int try_lock = pthread_mutex_lock(&(cons_ptr->shm_lock)); // SEG FAULT
    for(i = 0; i < 5; i++) {
        printf("\nNumber:[%d]\n", cons_ptr->data[i]);
        sleep(1);
    }
    //pthread_mutex_unlock(&(cons_ptr->shm_lock)); // SEG FAULT
    return 0;
}
程序接收信号SIGSEGV,分段故障。
/lib64/libpthread.so.0中pthread_mutex_lock()中的0x00007FF79C0C8D
(gdb)英国电信
#0 0x00007FF79C0C8D,位于/lib64/libpthread.so.0中的pthread_mutex_lock()中
#1 0x00000000004008ec(argc=1,argv=0x7fffffffde18“\210\341\377\377\377\177”)位于cons.c:41处
(gdb)p cons_ptr
$1=(测试结构*)0x7ffff7ff7000
(gdb)p cons_ptr->数据[0]
$2 = 873422052  
(gdb)p cons_ptr->magic
$3 = 43981  
(gdb)p cons_ptr->shm_锁
$4={{{uuuuuu data={{uuuuuu lock=0,{uuuuu count=0,{uuuuuuu owner=0,{uuuuu nusers=0,{uuuuuuuu kind=128,{uuuuuuuuu spins=0,{uuuuuuuuuuuu elision=0,{uuuuuuuuuuuuuuuuuuu-prev=0x0,},
__大小='\000',“\200','\000',\uuu align=0}
(gdb)
//标题:
const char*pathname=“test\u shm”;
类型定义结构测试_{
uint64_t魔术;
int数据[1024];
pthread_mutex_t shm_lock;
uint64_t magic2;
}测试强度;
//制作人:
#包括“test_header.h”
#包括
测试str*ptr;
void init_mutex(pthread_mutex_t*mutex){
pthread_mutextatr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_setpshared(&attr,pthread_PROCESS_SHARED);
pthread_mutex_init(mutex和attr);
pthread_mutexattr_destroy(&attr);
}
int main(int argc,char*argv[]){
intfd,i=0,num_int=1024,rc=0;
int size=num_int*sizeof(int);
fd=shm_open(路径名,O|u create | O|u RDWR,0666);
如果(fd==-1){
printf(“\n shm_open失败\n”);
出口(0);
}
rc=ftruncate(fd,sizeof(test_str_t));
ptr=(test_str_t*)mmap(NULL,sizeof(test_str t)),
保护写入,保护读取,映射共享,fd,0);
如果(ptr==MAP_失败){
printf(“\n mmap失败\n”);
出口(0);
}
rc=init_互斥锁(&(ptr->shm_锁));
如果(rc!=0){
printf(“互斥初始化失败:rc:[%d]\n”,rc);
出口(0);
}
ptr->magic=0xABCD;
ptr->magic2=0xEF12;
srand(时间(0));
对于(i=0;i<5;i++){
pthread_mutex_lock(&(ptr->shm_lock));
ptr->数据[i]=i;
pthread_mutex_unlock(&(ptr->shm_lock));
}
返回0;
}
//消费者:
#包括“test_header.h”
#包括
测试压力*控制压力;
int main(int argc,char*argv[]){
intfd,i=0,num_int=1024,rc=0;
int try_lock=0;
int size=num_int*sizeof(int);
fd=shm_open(路径名,O_RDONLY,0666);
如果(fd==-1){
printf(“\n shm_open失败\n”);
出口(0);
}
cons_ptr=(test_str_t*)mmap(NULL,sizeof(test_str t)),
保护读取,地图共享,fd,0);
如果(cons_ptr==MAP_失败){
printf(“\n mmap失败\n”);
出口(0);
}
如果(cons_ptr==NULL){
printf(“\n空Ptr\n”);
返回0;
}
printf(“Magic:[0x%x][0x%x]\n”,cons_ptr->Magic,cons_ptr->magic2);
//int try_lock=pthread_mutex_lock(&(cons_ptr->shm_lock));//SEG故障
对于(i=0;i<5;i++){
printf(“\n编号:[%d]\n”,cons_ptr->data[i]);
睡眠(1);
}
//pthread_mutex_unlock(&(cons_ptr->shm_lock));//SEG故障
返回0;
}
(1)这里有一个问题:
ptr->data=rand();
数据是一个int*,您已将该指针替换为一个随机地址。你在几个地方这样做,我看不出到底发生了什么,但这是我现在看到的最明显的错误

(2) 我看到的下一件事是,在使用者中,您以只读方式打开文件并将内存映射为只读,但是pthread_mutex_lock和pthread_mutex_unlock需要能够修改互斥,因此这可能会导致一些问题。

(1)这里有一个问题: ptr->data=rand(); 数据是一个int*,您已将该指针替换为一个随机地址。你在几个地方这样做,我看不出到底发生了什么,但这是我现在看到的最明显的错误


(2) 我看到的下一件事是,在使用者中,您以只读方式打开文件并将内存映射为只读,但是pthread_mutex_lock和pthread_mutex_unlock需要能够修改互斥,因此这可能会导致一些问题。

首先检查堆栈跟踪是否存在segfault。所有
pthread_*()
函数是否返回?您应该首先确保它们正常工作。@Andrew Henle我检查了返回值,它们都返回0。它们很好。当我试图锁定生产者进程时,返回值为0。@SergeyA-我已经添加了跟踪,它看起来确实不错。@Gerhardh-你能告诉我哪些信息缺失吗?从检查堆栈跟踪的segfault开始。所有
pthread_*()
函数返回什么?您应该首先确保它们正常工作。@Andrew Henle我检查了返回值,它们都返回0。它们很好。返回值是0,当我试图锁定生产者进程时。@SergeyA-我添加了跟踪,它看起来确实不错。@Gerhardh-你能告诉我丢失了哪些信息吗?谢谢,我将数据[I]改为指向I本身的值,很遗憾,我仍然得到相同的SEG错误。但是消费者仍然能够检索i的值,即0到4。是的!这就是诀窍,将其设置为写p