Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
430 views
in Technique[技术] by (71.8m points)

c - POSIX semaphores - cannot determine what causes segmentation fault

I'm working on the sleeping barber problem (using FIFO queue and shared memory), and I have a problem. I try to run this program just to see what is shown, however, I get segmentation fault every time. In the code I check, if semaphores are created successfully, if shared memory is created properly, but the program crashing must come from different place, which I cannot seem to find. I also tried to use Valgrind but what I got is:

Valgrind for the newer version of code: However, when I try to run the code I still get segfault

==187== Memcheck, a memory error detector
==187== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==187== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==187== Command: ./barber
==187==
Error while executing program, invalid amount of arguments==187==
==187== HEAP SUMMARY:
==187==     in use at exit: 0 bytes in 0 blocks
==187==   total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
==187==
==187== All heap blocks were freed -- no leaks are possible
==187==
==187== For lists of detected and suppressed errors, rerun with: -s
==187== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==124== Memcheck, a memory error detector
==124== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==124== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==124== Command: ./barber
==124==
==124== Invalid read of size 1
==124==    at 0x1094DD: main (in /mnt/c/users/Czaro/ubuntu/lab6posix/barber)
==124==  Address 0x2 is not stack'd, malloc'd or (recently) free'd
==124==
==124==
==124== Process terminating with default action of signal 11 (SIGSEGV)
==124==  Access not within mapped region at address 0x2
==124==    at 0x1094DD: main (in /mnt/c/users/Czaro/ubuntu/lab6posix/barber)
==124==  If you believe this happened as a result of a stack
==124==  overflow in your program's main thread (unlikely but
==124==  possible), you can try to increase the size of the
==124==  main thread stack using the --main-stacksize= flag.
==124==  The main thread stack size used in this run was 8388608.
glut==124==
==124== HEAP SUMMARY:
==124==     in use at exit: 125 bytes in 4 blocks
==124==   total heap usage: 5 allocs, 1 frees, 1,149 bytes allocated
==124==
==124== LEAK SUMMARY:
==124==    definitely lost: 0 bytes in 0 blocks
==124==    indirectly lost: 0 bytes in 0 blocks
==124==      possibly lost: 0 bytes in 0 blocks
==124==    still reachable: 125 bytes in 4 blocks
==124==         suppressed: 0 bytes in 0 blocks
==124== Reachable blocks (those to which a pointer was found) are not shown.
==124== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==124==
==124== For lists of detected and suppressed errors, rerun with: -s
==124== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault

I'd greatly appreciate every kind of help! The code for barber (newer version, with changes given by @AndrewHenle looks like this:

#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "functions.h"
#include <sys/mman.h>
#include <unistd.h>

int main(char* argv[], int argc)
{
    if(argc < 2){
        printf("Error while executing program, invalid amount of arguments");
        return 0;
    }
    sem_t *barber;
    sem_t *queue;
    int seats;
    int sharedmem, waitRoomSize;
    struct Queue waitroom;
    
    barber = sem_open("Barber", O_CREAT | O_RDWR, 0666, 1);
     if((barber == SEM_FAILED)){
        printf("Error while creating semaphore for barber");
        exit(1);
        }
    queue = sem_open("Queue", O_CREAT | O_RDWR, 0666, 1);
     if((queue  == SEM_FAILED)) {
        printf("Error while creating semaphore for queue");
        exit(1);
      }
    seats = atoi(argv[1]);
    void *space;
    queueinit(waitroom, seats);


    sharedmem = shm_open("Queue", O_RDWR, 0666);
    if(sharedmem==-1){
       printf("Error while getting shared memory");
       exit(1);
    }
    waitRoomSize = ftruncate(sharedmem, sizeof(waitroom));
    if((waitRoomSize ==-1)){
       printf("Error while getting size");
       exit(1);
       }
    space = mmap(NULL, sizeof(struct Queue), PROT_READ | PROT_WRITE, MAP_SHARED, sharedmem, 0);
    if((space == MAP_FAILED)){
       printf("B31d podczas mapowania pamiêci");
       exit(1);
       }

    while(1)
    {
        printf("Starting work...");
       sem_wait(queue);
       sem_post(queue);
       if(isEmpty(waitroom)) {
            sem_wait(barber);
            printf("Falling asleep 
");
            sem_post(barber);
            printf("Waking up 
");
       }
       sem_wait(queue);
       sem_post(queue);

       int id = get(waitroom);
       printf("Customer: %d, please sit on the chair", id);
       printf("I start making haircut: %d", id);
       sleep(2);
       printf("Finished making haircut for: %d", id);
    }
    sem_close(barber);
    sem_unlink("Barber");
    sem_close(queue);
    sem_unlink("Queue");
}

Previous version:

#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "functions.h"
#include <sys/mman.h>
#include <unistd.h>

int main(char* argv, int argc)
{
    sem_t *barber;
    sem_t *queue;
    int seats;
    int sharedmem, waitRoomSize;
    struct Queue waitroom;
   
    barber = sem_open("Barber", O_CREAT | O_RDWR, 0666, 1);
     if((barber == SEM_FAILED)){
        printf("Error while creating semaphore for barber");
        exit(1);
        }
    queue = sem_open("Queue", O_CREAT | O_RDWR, 0666, 1);
     if((queue  == SEM_FAILED)) {
        printf("Error while creating semaphore for queue");
        exit(1);
      }
    seats = atoi(argv[1]);
    void *space;
    queueinit(waitroom, seats);



    if((sharedmem = shm_open("Queue", O_RDWR, 0666)==-1)){
       printf("Error while getting shared memory");
       exit(1);
       }
    if((waitRoomSize = ftruncate(sharedmem, sizeof(waitroom))==-1)){
       printf("Error while getting size");
       exit(1);
       }
    if((space = mmap(NULL, sizeof(struct Queue), PROT_READ | PROT_WRITE, MAP_SHARED, sharedmem, 0) == MAP_FAILED)){
       printf("B??d podczas mapowania pami?ci");
       exit(1);
       }

    while(1)
    {
        printf("Starting work...");
       sem_wait(queue);
       sem_post(queue);
       if(isEmpty(waitroom)) {
            sem_wait(barber);
            printf("Falling asleep 
");
            sem_post(barber);
            printf("Waking up 
");
       }
       sem_wait(queue);
       sem_post(queue);

       int id = get(waitroom);
       printf("Customer: %d, please sit on the chair", id);
       printf("I start making haircut: %d", id);
       sleep(2);
       printf("Finished making haircut for: %d", id);
    }
    sem_close(barber);
    sem_unlink("Barber");
    sem_close(queue);
    sem_unlink("Queue");
}

The FIFO queue is implemented like this:

#ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED
#include <stdlib.h>
#include <unistd.h>
struct Queue{
    int* elems;
    int qsize;
    int head;
    int tail;
    int capacity;
};

void queueinit(struct Queue q, int capacity)
{
    q.elems = malloc(capacity*(sizeof(int)));
    q.capacity = capacity;
    q.head = 0;
    q.qsize = 0;
    q.tail = capacity-1;

}

int isFull(struct Queue q)
{
    return (q.qsize == q.capacity);
}

int isEmpty(struct Queue q)
{
    return (q.qsize == 0);
}


void push(struct Queue q, int val)
{
    if(isFull(q)){
        printf("Kolejka pe3na");
        return;
    }
    q.tail = (q.tail +1) % q.capacity;
    q.elems[q.tail] = val;
    q.qsize = q.qsize +1;
    printf("%d zajmuje miejsce w kolejce", val);
}

int get(struct Queue q)
{
    if(isEmpty(q))
    {
        printf("kolejka pusta");
        return -1;
    }
    int val = q.elems[q.head];
    q.head = (q.head +1) % q.capacity;
    q.qsize = q.qsize -1;
    printf("%d opuszcza zak3ad", val);
}
#endif // FUNCTIONS_H_INCLUDED

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...