简体   繁体   English

Linux共享内存段错误

[英]Linux shared memory segfault

I have been having difficulties getting a useable shared memory region in a sample C program (RHEL 6). 我一直很难在示例C程序(RHEL 6)中获得可用的共享内存区域。 It should be quite basic so I'm not sure what I'm doing wrong but when I allocate the memory region it appears to be accessible initially. 它应该是非常基本的,所以我不确定我在做什么错,但是当我分配内存区域时,它最初似乎是可访问的。 However, when I return from an initialization function the memory region is no longer accessible and I get a segfault when I try to access the memory region. 但是,当我从初始化函数返回时,无法再访问该存储区域,并且在尝试访问该存储区域时出现段错误。

I have tried running it through GDB and all I see is a segfault on the line where I try to do this memcpy: 我已经尝试通过GDB运行它,而我所看到的只是在我尝试执行此memcpy的那一行上出现的段错误:

memcpy(ptr, &x, sizeof(x));

It's probably something minor that I just cannot see for some reason! 由于某种原因,我可能看不到它,这可能是很小的事情! Thanks. 谢谢。

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <errno.h>


void* shared_mem[2];

int init(int *memAddress);

int main() {

  if(init((int*)&shared_mem[0]) < 0) {
    printf("Error initializing, exiting\n");
    exit(1);
  }

  int *ptr=shared_mem[0];

  int x=278;
  memcpy(ptr, &x, sizeof(x));
  printf("data written to memAddress: %d\n", shared_mem[0]);

}

// Initialize shared memory region and insert test data
int init(int *memAddress) {
    key_t key = 234324;
    int size = sizeof(int);
    static const unsigned int flags = S_IRUSR | S_IWUSR | S_IRGRP |
                                       S_IWGRP | S_IROTH | S_IWOTH | IPC_CREAT;
    int id = shmget(key, size, flags);
    if (id < 0)
    {
        return(-3);
    }
    *memAddress = shmat(id,0,0);
    if ((int)memAddress == -1)
    {
        return(-4);
    }

    int z=123;
    memcpy(memAddress, &z, sizeof(z));
    printf("data written to memAddress: %d\n", memAddress[0]);
    return(0);
}

Something is completely wrong here and it begins with the following line: 这是完全错误的,它从以下几行开始:

int init(int *memAddress)

You pass a pointer to shared_mem to the function "init". 您将指向shared_mem的指针传递给函数“ init”。 Therefore memAddress will point to the 8- or 16-byte (depending on the CPU type) array shared_mem . 因此, memAddress将指向8或16字节(取决于CPU类型)数组shared_mem

*memAddress = shmat(id,0,0);

If sizeof(void *) == sizeof(int) this would work however then you'd have to do other pointer casts. 如果sizeof(void *) == sizeof(int)可以,但是您必须进行其他指针转换。 shared_mem[0] will contain a pointer to the memory, casted to int . shared_mem[0]将包含一个指向内存的指针,该指针被强制转换为int

If sizeof(void *) != sizeof(int) you'll already have problems here. 如果sizeof(void *) != sizeof(int)您将在这里遇到问题。

(int)memAddress == -1

This will not work in any case: 这在任何情况下均不起作用:

(int)memAddress is the address of the array shared_mem and not the value returned by shmat . (int)memAddress是数组shared_mem的地址,而不是shmat返回的值。

memcpy(memAddress, &z, sizeof(z));

This will write the value 123 into shared_mem[0] . 这会将值123写入shared_mem[0] Therefore the following instruction: 因此,以下说明:

memcpy(ptr, &x, sizeof(x));

... will be equal to: ...将等于:

memcpy((void *)123, &x, sizeof(x));

... which will cause the error. ...这将导致错误。

The correct function would look like this: 正确的函数如下所示:

int init(void **memAddress) {     // void **
    ...
    *memAddress = shmat(id,0,0);  // This was correct!
    if ((int)(*memAddress) == -1) // Note the "*"
        ...
    memcpy(*memAddress, &z, sizeof(z)); // Note the "*"
}

Your init function isn't modifiying shared_mem with the allocated memory address - the parameter to init() needs to be declared as int **memaddress for example look at your line *memaddress=shmget(...) with parameter defined as int *memaddress this is storing the result of shmget as an integer, that isn't right. 您的init函数未使用分配的内存地址修改shared_mem-init()的参数需要声明为int **memaddress ,例如,查看您的行*memaddress=shmget(...) ,其参数定义为int *memaddressint *memaddress shmget的结果存储为整数,这是不对的。 You need to check all the related uses of memaddress are correct. 您需要检查memaddress的所有相关用法是否正确。 You can check this in gdb, look at the result of shmget, make sure that is being stored in shared_mem[0]. 您可以在gdb中进行检查,查看shmget的结果,确保将其存储在shared_mem [0]中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM