简体   繁体   中英

C - getting error *** stack smashing detected ***

I know it might be a duplicate question but I couldn't find a solution for my problem yet.

What I want to do

I'm trying to write in C a sort of simulation of a growing society where there are 2 types of persons, A and B (2 people in my example).

  • A accepts "engagement proposals" from B
  • The communication between A , B and gestore is handled with message queues
  • gestore decides attributes of every "person" and then creates them with execve , passing each attribute as argument
  • There is a main message queue where each A process sends a message with its info and the key of his private message queue
  • B reads from the main message queue and then communicates with A using the given key found in the message

I'm under Linux Mint 18.3 32 bit.

The problem

It always gives the error stack smashing detected in file

My files

header.h

#ifndef _HEAD_H
#define _HEAD_H

#include <unistd.h>
#include <sys/msg.h>

#define OFFSET 1000000

union semun {
    int val;
    struct semid_ds *buf;
    unsigned short *array;
    struct seminfo *__buf;
};

struct person{
    char type;
    int name;
    unsigned long genome;
};

struct msg_text {
    pid_t pid;
    char type;
    int name;
    unsigned long genome;
    int key_of_love;
    pid_t partner;
};

struct mymsg { 
    long mtype;
    struct msg_text mtxt;
};

int initSemAvailable(int, int);
int initSemInUse(int, int);
int reserveSem(int, int);
int releaseSem(int, int);
#endif

header.c

#include <sys/sem.h>
#include <sys/types.h>
#include "header.h"

int initSemAvailable(int semId, int semNum)
{
    union semun arg;
    arg.val = 1;
    return semctl(semId, semNum, SETVAL, arg);
}

int initSemInUse(int semId, int semNum)
{
    union semun arg;
    arg.val = 0;
    return semctl(semId, semNum, SETVAL, arg);
}

int reserveSem(int semId, int semNum) {
    struct sembuf sops;
    sops.sem_num = semNum;
    sops.sem_op = -1;
    sops.sem_flg = 0;
    return semop(semId, &sops, 1);
}

int releaseSem(int semId, int semNum) {
    struct sembuf sops;
    sops.sem_num = semNum;
    sops.sem_op = 1;
    sops.sem_flg = 0;
    return semop(semId, &sops, 1);
}

gestore.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <time.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "header.h"

#ifndef MAX_PEOPLE
#define MAX_PEOPLE 5
#endif

#ifndef GENES
#define GENES 1000000
#endif

#ifndef BIRTH_DEATH
#define BIRTH_DEATH 5
#endif

#define SIZE_N 15

//handle signals
struct sigaction sa;
sigset_t my_mask;
void handle_signal(int);

//remove every IPC object
void remove_all();

//terminate every child
void terminate_children();

//free memory
void free_all();

//print every field of message
void print_msg(struct mymsg);

unsigned int init_people;
int * child_status;
pid_t * initial_children;
char * child_name;
char * child_genome;
char * child_sem;
char * child_sem2;
char * child_msgq_a;
//message queue
struct msqid_ds msq;
int msgq_a;
//semaphores
int sem_init_people;
int sem_init_people2;

int main(void)
{
    init_people = 0;//will contain initial number of people
    int i = 0;
    pid_t child;//fork value
    unsigned long random_ulong = 0;
    child_name = (char *)calloc(SIZE_N, sizeof(char));
    child_genome = (char *)calloc(SIZE_N, sizeof(char));
    child_sem = (char*)calloc(SIZE_N, sizeof(char));
    child_sem2 = (char*)calloc(SIZE_N, sizeof(char));
    child_msgq_a = (char*)calloc(SIZE_N, sizeof(char));
    char * args[8] = {};
    char * envs[] = {NULL};

    if( child_name == NULL || child_genome == NULL
    || child_sem == NULL || child_sem2 == NULL
    || child_msgq_a == NULL){
        perror("there's a null variable");
        exit(EXIT_FAILURE);
    }

    //handle signals
    sa.sa_handler = &handle_signal;
    sa.sa_flags = 0;
    sigemptyset(&my_mask);
    sigaction(SIGALRM, &sa, NULL);
    sigaction(SIGUSR1, &sa, NULL);

    printf("\nSTARTING SIMULATION\n\n");

    init_people = 2;
    initial_children = (pid_t *)calloc(init_people,
    sizeof(pid_t));

    //create 2 semaphores

    sem_init_people = semget(IPC_PRIVATE, 1,
    0666|IPC_CREAT|IPC_EXCL);
    if( sem_init_people == -1 ){
        if(errno == EEXIST){
            if( semctl(sem_init_people, 0,
            IPC_RMID, NULL) == -1 ){
                perror("rm sem_init_people");
                exit(EXIT_FAILURE);
            }
        }else{
            perror("semget init_people");
            exit(EXIT_FAILURE);
        }
    }

    sem_init_people2 = semget(IPC_PRIVATE, 1,
    0666|IPC_CREAT|IPC_EXCL);
    if( sem_init_people2 == -1 ){
        if(errno == EEXIST){
            if( semctl(sem_init_people2, 0,
            IPC_RMID, NULL) == -1 ){
                perror("remove sem_init_people2");
                exit(EXIT_FAILURE);
            }
        }else{
            perror("semget sem_init_people2");
            exit(EXIT_FAILURE);
        }
    }

    //create message queue
    msgq_a = msgget(IPC_PRIVATE, 0666|IPC_CREAT|IPC_EXCL);
    if(msgq_a == -1){
        if( errno == EEXIST ){//if exists
            // delete message queue
            if( msgctl(msgq_a, IPC_RMID, &msq) == -1 )
                perror("rmid");
        }else
            perror("msgget queue A");
        exit(EXIT_FAILURE);
    }

    //initialize sem_init_people to 0 (reserved)
    if( initSemInUse(sem_init_people, 0) == -1 ){
        perror("initSemInUse for sem_init_people");
        exit(EXIT_FAILURE);
    }

    //initialize sem_init_people2 to 0 (reserved)
    if( initSemInUse(sem_init_people2, 0) == -1 ){
        perror("initSemInUse for sem_init_people");
        exit(EXIT_FAILURE);
    }

    //RWX permissions for people processes
    if( chmod("./A", 0777) != 0 ){
        perror("chmod person A");
        exit(EXIT_FAILURE);
    }
    if( chmod("./B", 0777) != 0 ){
        perror("chmod person B");
        exit(EXIT_FAILURE);
    }

    printf("Generating %u people\n\n", init_people);

    //generate initial population
    for(i = 0; i < init_people; i++){

        //TYPE
        if( i%2 == 0 )
            args[0] = "./A";
        else
            args[0] = "./B";

        //NAME
        if( sprintf(child_name, "%d", i+65) < 0 ){
            perror("printf NAME execve");
            exit(EXIT_FAILURE);
        }
        args[1] = child_name;

        //GENOME
        if( sprintf(child_genome, "%lu",
        (long)i+100000) < 0 ){
            perror("sprintf GENOME execve");
            exit(EXIT_FAILURE);
        }
        args[2] = child_genome;

        //semaphore 1
        if( sprintf(child_sem, "%d",
        sem_init_people) < 0 ){
            perror("sprintf sem_init_prople execve");
            exit(EXIT_FAILURE);
        }
        args[3] = child_sem;

        //semaphore 2
        if( sprintf(child_sem2, "%d",
        sem_init_people2) < 0 ){
            perror("sprintf sem_init_prople2 execve");
            exit(EXIT_FAILURE);
        }
        args[4] = child_sem2;

        //msg queue
        if( sprintf(child_msgq_a, "%d", msgq_a) < 0 ){
            perror("sprintf child_msgq_a execve");
            exit(EXIT_FAILURE);
        }
        args[5] = child_msgq_a;

        //final argument
        args[6] = NULL;


        switch(child = fork()){

            case -1:{ //error
                perror("fork init_people");
                exit(EXIT_FAILURE);
            }

            case 0:{//child

                if( execve(args[0], args, envs) == -1 ){
                    perror("execve");
                }
                //execve didnt't work
                exit(EXIT_FAILURE);
            }

            default:{//parent

                printf("[type:%c][name:%c][pid:%d][gen:%s][sem1:%s]\
[sem2:%s][msgq:%s]\n",
                    args[0][2],
                    atoi(args[1]),
                    (int)child,
                    args[2],
                    args[3],
                    args[4],
                    args[5] );

                //add every child in the array
                initial_children[i] = child;
            }
        }//-switch
    }//-for

    //wait for every child to be ready to start
    for(i = 0; i < init_people; i++){
        if( reserveSem(sem_init_people, 0) != 0 ){
            perror("reserveSem sem_init_people");
            exit(EXIT_FAILURE);
        }
    }

    //allow every child to start
    for(i = 0; i < init_people; i++){
        if( releaseSem(sem_init_people2, 0) != 0 ){
            perror("releaseSem sem_init_people2");
            exit(EXIT_FAILURE);
        }
    }

    //wait for termination of every child
    if( waitpid(-1, child_status, (int)WNOHANG) == -1 ){
        perror("waitpid");
    }

    printf("Father is now waiting...\n");
    for(i = 0; i < 3; i++){
        sleep(3);
    }

    terminate_children();
    remove_all();
    free_all();

    return EXIT_SUCCESS;
}


void handle_signal(int signum)
{
    switch(signum){

        case SIGUSR1:{

            pid_t pidA = 0, pidB = 0;
            unsigned long genomeA = 0, genomeB = 0;
            struct mymsg msg1, msg2;
            int msg_flag = 0;

            //ignore sigusr1
            if( sigaddset(&my_mask, SIGUSR1) == -1 ){
                perror("sigaddset");
                exit(EXIT_FAILURE);
            }

            //read for every message
            while(msg_flag == 0){
                if( msgrcv(msgq_a, &msg1, sizeof(msg1),
                OFFSET+getpid(), IPC_NOWAIT) == -1 ){
                    if( errno == ENOMSG ){
                        msg_flag = -1;
                        printf("gestore is empty\n");
                    }else{ //random error happened
                        perror("msgrcv parent A and B");
                        exit(EXIT_FAILURE);
                    }
                }else{
                    print_msg(msg1);
                    msg_flag = 0;
                }

            }

            //do not ignore SIGUSR1
            if( sigdelset(&my_mask, SIGUSR1) == -1 ){
                perror("sigdelset");
                exit(EXIT_FAILURE);
            }

            break;
        }

        default:{}
    }
}

void terminate_children()
{
    int i = 0;
    for(i = 0; i < init_people; i++){
        if( kill(initial_children[i], 0) == 0 ){
            if( kill(initial_children[i], SIGTERM) == -1){
                perror("kill sigterm to child");
            }
        }
    }
}

void remove_all()
{
    //...
}

void free_all()
{
    //...
}

void print_msg(struct mymsg msg)
{
    printf("gestore rcv [mtype:%lu][pid:%d][type:%c]\
[name:%c][gen:%lu][key<3:%d][pid<3:%d]\n",
        msg.mtype,
        (int)msg.mtxt.pid,
        msg.mtxt.type,
        msg.mtxt.name,
        msg.mtxt.genome,
        msg.mtxt.key_of_love,
        (int)msg.mtxt.partner );
}

personA.c

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "header.h"

#define NMEMB 50

void accept_lover(int msgq, int love_msg_queue,
    struct mymsg love_letter, struct person myself);

void reject_lover(int, struct mymsg love_letter);

struct sigaction sa;
void handle_signal(int);

void print_rcvd_msg(struct mymsg);
void print_sent_msg(struct mymsg);

struct msqid_ds msq;
int love_msg_queue;

int main(int argc, char** argv)
{
    if(argc < 6){
        perror("A argc");
        exit(EXIT_FAILURE);
    }

    struct person myself;//info of A process
        myself.type = 'A';
        myself.name = (int)atoi(argv[1]);
        myself.genome = (unsigned long)atol(argv[2]);
    int sem_init_people, sem_init_people2;
        sem_init_people = (int)atoi(argv[3]);
        sem_init_people2 = (int)atoi(argv[4]);
    int msgq = atoi(argv[5]);
    struct mymsg msg_out, love_letter;
    struct msqid_ds msq;
    int engaged = -1;
    int count_refused = 0;

    sa.sa_handler = &handle_signal;
    sigaction(SIGTERM, &sa, NULL);

    //tell parent you're ready
    if( releaseSem(sem_init_people, 0) != 0 ){
        perror("releaseSem sem_init_people");
        exit(EXIT_FAILURE);
    }

    //wait for parent permission
    if( reserveSem(sem_init_people2, 0) != 0 ){
        perror("reserveSem sem_init_people2");
        exit(EXIT_FAILURE);
    }

    //create personal message queue of love
    love_msg_queue = msgget(IPC_PRIVATE,
    0666|IPC_CREAT|IPC_EXCL);
    if( love_msg_queue == -1 ){
        if( errno == EEXIST ){//if exists
            // delete message queue
            if( msgctl(love_msg_queue,
            IPC_RMID, &msq) == -1 ){
                perror("rmid queue of love");
                exit(EXIT_FAILURE);
            }
        }else{
            perror("msgget queue of love");
            exit(EXIT_FAILURE);
        }
    }

    //create message with correct info of process A
    msg_out.mtype = myself.genome;
    msg_out.mtxt.pid = getpid();
    msg_out.mtxt.type = myself.type;
    msg_out.mtxt.genome = myself.genome;
    msg_out.mtxt.name = myself.name;
    msg_out.mtxt.key_of_love = love_msg_queue;
    msg_out.mtxt.partner = -1;

    //when A accepts B engaged = 0
    while(engaged != 0){

        //send info in message queue
        if( msgsnd(msgq, &msg_out, sizeof(msg_out), 0)
        == -1 ){
            if(errno == EINTR)
                perror("A caught a signal and failed \
a blocked msgsnd");
            else
                perror("A msgsnd"); 
            exit(EXIT_FAILURE);
        }
        print_sent_msg(msg_out);

        //wait for love letter from B
        if( msgrcv(love_msg_queue, &love_letter,
            sizeof(love_letter), 0, 0) == -1 ){
            perror("A msgrcv love letter from B");
            exit(EXIT_FAILURE);
        }
        print_rcvd_msg(love_letter);

        //accept B if..
        if( count_refused >= 2 ){
            engaged = 0;//B is good, EXIT loop
            accept_lover(msgq, love_msg_queue,
            love_letter, myself);
            printf("[A:%d]accepted[B:%d]\n",(int)getpid(),
                (int)love_letter.mtxt.pid);
        }else{
            reject_lover(love_msg_queue,love_letter);
            printf("[A:%d] refused %d times\n",
                (int)getpid(),count_refused+1);
            count_refused++;
        }

    }

    pause();
    return EXIT_SUCCESS;
}

void handle_signal(int signum)
{
    switch(signum){

        case SIGTERM:{
            printf("A SIGTERM from parent\n");

            // delete message queue if exists
            if( (msgctl(love_msg_queue, IPC_RMID,
                &msq) == -1) && (errno != EIDRM) ){
                perror("A rmid 2");
            }
            break;
        }

        default:{}
    }
}

void accept_lover(int msgq, int love_msg_queue,
    struct mymsg love_letter, struct person myself)
{
    struct mymsg
        msg_to_B, msg_to_gestore1, msg_to_gestore2;

    //tell B you accept his request (key_of_love = 0)
    msg_to_B.mtype = love_letter.mtype; //pid of B
    msg_to_B.mtxt.pid = getpid();
    msg_to_B.mtxt.type = 'A';
    msg_to_B.mtxt.name = myself.name;
    msg_to_B.mtxt.genome = myself.genome;
    msg_to_B.mtxt.key_of_love = 0; //0 means accepted
    msg_to_B.mtxt.partner = -1;

    //send msg to B in queue of love
    if( msgsnd(love_msg_queue, &msg_to_B,
        sizeof(msg_to_B), 0) == -1 ){
        perror("A msgsnd to B accept lover");
        exit(EXIT_FAILURE);
    }
    print_sent_msg(msg_to_B);

    //tell gestore that A accepted a request from B
        //send message with info of A
        //send message with info of B

    //A
    msg_to_gestore1.mtype = OFFSET + getppid();
    msg_to_gestore1.mtxt.pid = getpid();
    msg_to_gestore1.mtxt.type = 'A';
    msg_to_gestore1.mtxt.name = myself.name;
    msg_to_gestore1.mtxt.genome = myself.genome;
    msg_to_gestore1.mtxt.key_of_love = 0;
    msg_to_gestore1.mtxt.partner = love_letter.mtype;

    //B
    msg_to_gestore2.mtype = OFFSET + getppid();
    msg_to_gestore2.mtxt.pid = love_letter.mtype;
    msg_to_gestore2.mtxt.type = 'B';
    msg_to_gestore2.mtxt.name = love_letter.mtxt.name;
    msg_to_gestore2.mtxt.genome = love_letter.mtxt.genome;
    msg_to_gestore2.mtxt.key_of_love = 0;
    msg_to_gestore2.mtxt.partner = getpid();

    //send msg B
    if( msgsnd(msgq, &msg_to_gestore2,
        sizeof(msg_to_gestore2), 0) == -1 ){
        perror("A msg_to_gestore2");
        exit(EXIT_FAILURE);
    }

    //send msg A
    if( msgsnd(msgq, &msg_to_gestore1,
        sizeof(msg_to_gestore1), 0) == -1 ){
        perror("A msg_to_gestore1");
        exit(EXIT_FAILURE);
    }

    print_sent_msg(msg_to_gestore2);
    print_sent_msg(msg_to_gestore1);

    /*messages for gestore have mtype=OFFSET+father_pid
    so that others can't read messages with mtype greater
    than OFFSET and father can directly receive messages
    knowing both OFFSET and his pid. */
}

void reject_lover(int love_msg_queue,
    struct mymsg love_letter)
{
    love_letter.mtxt.key_of_love = -1;
    if( (msgsnd(love_msg_queue, &love_letter,
        sizeof(love_letter), 0) == -1) ){
        perror("A error refusing B in msgsnd");
        exit(EXIT_FAILURE);
    }
    print_sent_msg(love_letter);
}

void print_rcvd_msg(struct mymsg msg)
{
    printf("A received [mtype:%lu][pid:%d][type:%c]\
[name:%c][gen:%lu][key<3:%d][pid<3:%d]\n",
        msg.mtype,
        (int)msg.mtxt.pid,
        msg.mtxt.type,
        msg.mtxt.name,
        msg.mtxt.genome,
        msg.mtxt.key_of_love,
        (int)msg.mtxt.partner );
}

void print_sent_msg(struct mymsg msg)
{
    printf("A sent [mtype:%lu][pid:%d][type:%c][name:%c]\
[gen:%lu][key<3:%d][pid<3:%d]\n",
        msg.mtype,
        (int)msg.mtxt.pid,
        msg.mtxt.type,
        msg.mtxt.name,
        msg.mtxt.genome,
        msg.mtxt.key_of_love,
        (int)msg.mtxt.partner );
}

personB.c

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include "header.h"

//send message to A process and wait for response
int flirt(struct mymsg msg, struct person myself);

void print_rcvd_msg(struct mymsg);
void print_sent_msg(struct mymsg);

int main(int argc, char** argv)
{
    if(argc < 6){
        perror("B argc");
        exit(EXIT_FAILURE);
    }

    struct person myself;
        myself.type = 'B';
        myself.name = (int)atoi(argv[1]);
        myself.genome = (unsigned long)atol(argv[2]);
    int sem_init_people, sem_init_people2;
        sem_init_people = (int)atoi(argv[3]);
        sem_init_people2 = (int)atoi(argv[4]);
    int love_response = 1;
    int msgq = atoi(argv[5]);
    struct mymsg msg_out, msg_in;
    struct msqid_ds msq;

    //tell parent you're ready
    if( releaseSem(sem_init_people, 0) != 0 ){
        perror("release sem_init_people child proc");
        exit(EXIT_FAILURE);
    }

    //wait for parent permission to start living
    if( reserveSem(sem_init_people2, 0) != 0 ){
        perror("reserve sem_init_people2 child proc");
        exit(EXIT_FAILURE);
    }

    //when love_response is 0 A accepted B requests
    while(love_response != 0){

        //read message from queue
        if( msgrcv(msgq, &msg_in, sizeof(msg_in),
            -OFFSET, 0) < 1 ){
            perror("msgrcv");
            exit(EXIT_FAILURE);
        }
        print_rcvd_msg(msg_in);

        //send message to A process and wait for a response
        love_response = flirt(msg_in, myself);
        printf("2----------------------------\n");
    }
    //TODO: get ready to terminate
    return 0;
}

int flirt(struct mymsg msg, struct person myself)
{
    int queue_of_love = msg.mtxt.key_of_love;
    pid_t pid_A = msg.mtxt.pid;
    struct mymsg love_letter, msg_in;

    //create love letter
    love_letter.mtype = getpid();
    love_letter.mtxt.pid = getpid();
    love_letter.mtxt.type = 'B';
    love_letter.mtxt.name = myself.name;
    love_letter.mtxt.genome = myself.genome;
    love_letter.mtxt.key_of_love = -1;
    love_letter.mtxt.partner = -1;

    //send love letter to A to introduce yourself
    if( msgsnd(queue_of_love, &love_letter,
    sizeof(love_letter), 0) == -1 ){
        perror("B - msg send love");
        exit(EXIT_FAILURE);
    }
    printf("[B:%d] sent<3to [A:%d][mtype:%d][pid:%d]\
[type:%c][gen:%lu][name:%c][love:%d]\n",
        (int)getpid(), (int)pid_A,
        (int)love_letter.mtype,
        (int)love_letter.mtxt.pid,
        (int)love_letter.mtxt.type,
        (unsigned long)love_letter.mtxt.genome,
        love_letter.mtxt.name,
        love_letter.mtxt.key_of_love );

    //wait for response from A
    if( msgrcv(queue_of_love, &msg_in, sizeof(msg_in),
    getpid(), 0) == -1 ){
        perror("B can't wait for A's response");
        exit(EXIT_FAILURE);
    }
    print_rcvd_msg(msg_in);

    //if key of love 0 then accepted love request 

    printf("1 ----------------------------\n");
    return msg_in.mtxt.key_of_love;
}

void print_rcvd_msg(struct mymsg msg)
{
    printf("B received [mtype:%lu][pid:%d][type:%c]\
[name:%c][gen:%lu][key<3:%d][pid<3:%d]\n",
        msg.mtype,
        (int)msg.mtxt.pid,
        msg.mtxt.type,
        msg.mtxt.name,
        msg.mtxt.genome,
        msg.mtxt.key_of_love,
        (int)msg.mtxt.partner );
}

void print_sent_msg(struct mymsg msg)
{
    printf("B sent [mtype:%lu][pid:%d][type:%c]\
[name:%c][gen:%lu][key<3:%d][pid<3:%d]\n",
        msg.mtype,
        (int)msg.mtxt.pid,
        msg.mtxt.type,
        msg.mtxt.name,
        msg.mtxt.genome,
        msg.mtxt.key_of_love,
        (int)msg.mtxt.partner );
}

To compile and execute the project

  1. gcc -c header.c
  2. gcc -c personA.c header.c
  3. gcc -c personB.c header.c
  4. gcc -Wall -Wextra -Wconversion -pedantic -std=gnu11 -o A personA.o header.o
  5. gcc -Wall -Wextra -Wconversion -pedantic -std=gnu11 -o B personB.o header.o
  6. gcc -c gestore.c header.c
  7. gcc -Wall -Wextra -Wconversion -std=gnu11 -pedantic -o gestore gestore.o header.o
  8. ./gestore

Note the lines of code in personB.c .

  • printf("1----------------------------\\n");
  • printf("2----------------------------\\n");

The second line doesn't get printed because of the error.

Thank you in advance for the help.

Ouput

output error, stack smashing detected

Valgrind valgrind --leak-check=full -v ./gestore gives this output:

==8647== HEAP SUMMARY:
==8647==     in use at exit: 0 bytes in 0 blocks
==8647==   total heap usage: 7 allocs, 7 frees, 4,179 bytes allocated
==8647== 
==8647== All heap blocks were freed -- no leaks are possible
==8647== 
==8647== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==8647== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

EDIT

Should I link and compile like this?

  1. gcc -c -Wall -Wextra -Wconversion -std=gnu11 -ggdb header.c
  2. gcc -c -Wall -Wextra -Wconversion -std=gnu11 -ggdb personA.c header.c
  3. gcc -c -Wall -Wextra -Wconversion -std=gnu11 -ggdb personB.c header.c
  4. gcc -Wall -pedantic -ggdb -o A personA.o header.o
  5. gcc -Wall -pedantic -ggdb -o B personB.o header.o
  6. gcc -c -Wall -Wextra -Wconversion -std=gnu11 -ggdb gestore.c header.c
  7. gcc -Wall -pedantic -ggdb -o gestore gestore.o header.o

I 'heavily' edited this answer and removed statements that no longer applied, due to OPs modifying the posted code.

Note: when modifying the posted code, in general, DO NOT modify the original posted code, rather post the modified code as an EDIT. For the current question, suggest just posting interleaved code, perhaps via

#if 0
    <old code> 
#else 
    <new code> 
#endif 

===================

in the 'main() function that repeatedly calls system()` Suggest the compile steps enable the warnings. At a minimum use these compile options:

-Wall -Wextra -Wconversion -pedantic -std=gnu11

Note: the above parameters need to be in the compile statements, not the link statements.

and to make debugging much easier, suggest the compile and link options include:

-ggdb

Also, that main() function will perform ALL the steps every time. Suggest writing a makefile (and executing it with make ) so only those files that have changed will be re-compiled/ re-linked

================

Note: there is the setup for a message queue that the code omits, so the default values will be used. Those default values may not be correct for the OPs application.

Here is a cut/paste of a typical setup of a message queue:

Note: the code is from an application that contains LOTS of message queues taskSelector selects which message queue

  /* initialize the queue attributes */
    attr[taskSelector].mq_flags   = 0;
    attr[taskSelector].mq_maxmsg  = 10;
    attr[taskSelector].mq_msgsize = 
        sizeof(struct structITC) 
        + dWEB_PAYLOAD_OVERHEAD  
        + dMAX_DATA_BLOCK_SIZE;
    attr[taskSelector].mq_curmsgs = 0;

================

the posted code fails to define:

struct msqid_ds   -- oops it is defined in one of the header files

=================

when a check of argc indicates that the user did not enter all the needed command line parameters, then the code should output a USAGE message and exit. Something similar to:

fprintf( stderr, "USAGE: %s ..description of all needed parameters..\n", argv[0] );
exit( EXIT_FAILURE );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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