Warm tip: This article is reproduced from serverfault.com, please click

getting SEGFAULT when reading an array from shared memory

发布于 2020-12-02 23:50:26

I'm new to using shared memory and for the first file the implementation is working fine but for the second file it is unable to read some of the structures from the shared memory . I think the problem is in my mmap but not quite sure what exactly

first file which works nicely:

  struct Sh_Mem* open_res(int nb_tables)
    {
        size_t mem_size = MEM_SIZE(nb_tables);
        int shm_fd=shm_open(MEM_NAME,O_RDWR|O_CREAT | O_TRUNC, 0600);
        if(shm_fd<0)
            raler("shm_open");
        
        ftruncate(shm_fd,mem_size);
        
        struct Sh_Mem * res=mmap(NULL,mem_size,PROT_READ| PROT_WRITE,MAP_SHARED,shm_fd,0);
        if(res == NULL)
            raler("mmap");
        res->nb_tables=nb_tables;
        res->size = mem_size;
        
        return res;
    }
int main(int argc, char const *argv[])
{

    if (argc < 3)
        raler("Usage : ./restaurant <duree_repas> <capacite_des_tables>");
    
    
    int dinner_time = atoi(argv[1]);
    int nb_tables = argc -2;
    int fermeture=0;
    struct table* tables=malloc(nb_tables*sizeof(struct table));
    
    if (dinner_time < 100 )
        raler("Duree de repas tres courte");

    struct Sh_Mem* res=open_res(nb_tables);
    res->table = malloc(nb_tables*sizeof(struct table));

    for(int i = 2; i < (argc); i++)
    {
        if(atoi(argv[i])>6 || atoi(argv[i])<1 )
        {
            printf("\nERROR : %s\n ",argv[i] ); 
            raler("Max Capacity of Tables is 6 ");
        }
        tables[i-2].size = atoi(argv[i]);
        
    }
    res->table=tables;
    shm_unlink(MEM_NAME);
    return 0;
}

Second file which give me a segmentation fault :

struct Sh_Mem* first_guest(char * nom)
{

    int shm_fd=shm_open(MEM_NAME,O_RDWR, 0600);
    if(shm_fd<0)
        raler("shm_open");
    struct stat stat;
    if(fstat(shm_fd, &stat) < 0) {
        perror("fstat");
        exit(1);
    }
    struct Sh_Mem * guests=mmap(NULL,stat.st_size,PROT_READ| PROT_WRITE,MAP_SHARED,shm_fd,0);
    if(guests == NULL)
        raler("mmap");  
return guests;
}
int main(int argc, char const *argv[])
{
    if (argc != 3)
        raler("Usage : ./convive <nom_du_convive> <nombres_de_personnes_dans_le_groupe/nom_du_premier_convive>");
    
    if(strlen(argv[1])>10)
        raler("Name has to be less or equal to 10 char ");
    
    if(isdigit(argv[1][0]))
        raler("First argument has to start with a character");

    if (isdigit(argv[2][0]))
    {
struct Sh_Mem* res=first_guest((char*)argv[1]);
        for (int i = 0; i < res->nb_tables; i++)
        {
            if(res->table[i].used==1)
            {

                continue;
            }
            if(res->table[i].size == atoi(argv[2]))
                {
                    found =1;

                    res->table[i].name=(char *)argv[1];
                    res->table[i].used =1;
                }
                printf("%s\n",res->table[i].name );
        }

the error happens whenever i pass by a res->tables. i tested if it was equal to null but it isn't also here is the struct:

void raler(char *msg)
{
    perror(msg);
    exit(1);
}
struct table
{
    int id;
    int size;
    char* name;
    int nb_left;
    int used;

};
struct Sh_Mem{

int nb_tables;
size_t size;
struct table* table;
};
#define MEM_NAME "/guest"
#define MEM_SIZE(nb_table) sizeof (struct Sh_Mem) + (nb_table)*sizeof (struct convive)+ (nb_table)*sizeof (struct table)
Questioner
Kaspercold 1
Viewed
0
David Schwartz 2020-12-03 07:58:10
                res->table[i].name=(char *)argv[1];
            }
            printf("%s\n",res->table[i].name );

This doesn't work. You are putting a pointer into the current process' address space into shared memory. This means nothing to any other process.

You can fix this by making name a fixed-length array or by allocating some shared memory and having name point to that. Just be careful -- each process will have to compute the correct local pointer to the shared memory since different processes may map the same shared memory segment at different addresses.