Partage
  • Partager sur Facebook
  • Partager sur Twitter

syscall signal provoque un segmentation fault

    21 avril 2006 à 0:20:59

    salut tout le monde,
    voilà je suis en train d'écrire une application serveur-client en c, et je dois utilisé les signaux. Mon probleme est que après chaque appel a la fonction kill, l'appel de la fonction handler(que j'ai construite) fonctionne bien, mais c'est lors du retour au programme que la j'ai un segmentation fault...

    Comme exemple j'utilise la fct alarm(nb_sec) pour que après nb_sec un signal de type SIGALRM soit lancé au process exécutant... dont le signal est catché traité, et lors du retour dans le programme vlan ca foire ... est-ce que qq aurait une idée de ce que ca pourrait être?

    je laisse des bouts de mon code qui concerne justement ce probleme :

    Déclaration de sigaction

    struct sigaction sig;
    sig.sa_handler = handler;
    sigemptyset(&sig.sa_mask);
    sigaction(SIGINT,&sig,NULL);
    sigaction(SIGALRM,&sig,NULL);


    la boucle principal de mon pgm

     while(1){
            if(nombre_de->joueur==1 && alarmEnvoi==0){
                alarm(30);
                alarmEnvoi=1;
                alarmOK=0;
            }
            if(jeux=0 && nombre_de->joueur==5){
                printf("DEBUT DE PARTIE : 5 joueurs\n");
                jeux=1;   
            }
            if(jeux==0 && alarmOK==1 && nombre_de->joueur>=2 && nombre_de->joueur<5){
                printf("DEBUT DE PARTIE : de 2 a 4 joueurs\n");
                jeux=1;
                joueurCourant=0;
                joue=1;
                msgMQ.pid = tabPid[joueurCourant];
                msgMQ.u.type= 'J';

                if(msgsnd(msgq_id,&msgMQ,sizeof(struct msgMQ),IPC_NOWAIT)<0){
                    perror("Erreur msgsnd");
                    exit(EXIT_FAILURE);
                }


            }
            if(read(fifo,&msgFifo,sizeof(struct msgFifo)) <=0){
                continue;
            }
            if(msgFifo.type=='I'){
                if(nombre_de->joueur<5 && jeux==0){
                    printf("Oh on doit inscrire quelqu un\n");
                    strcpy(joueurs->tabJoueur[nombre_de->joueur].nom,msgFifo.u.s.nom);
                    strcpy(joueurs->tabJoueur[nombre_de->joueur].prenom,msgFifo.u.s.prenom);
                    tabPid[nombre_de->joueur]=msgFifo.pid;
                    printf("SERVER a inscrit : %s %s, pid %d\n", joueurs->tabJoueur[nombre_de->joueur].nom, joueurs->tabJoueur[nombre_de->joueur].prenom,msgFifo.pid);
                    nombre_de->joueur++;
                   
                    msgMQ.pid = msgFifo.pid;
                    msgMQ.u.s.type = 'O';
                    msgMQ.u.s.numJoueur = nombre_de->joueur;
                   
                    if(msgsnd(msgq_id,&msgMQ,sizeof(struct msgMQ),IPC_NOWAIT)<0){
                        perror("Erreur msgsnd");
                        exit(EXIT_FAILURE);
                    }

                   
                }else{
                    msgMQ.pid = msgFifo.pid;
                    msgMQ.u.type = 'K';
                    if(msgsnd(msgq_id,&msgMQ,sizeof(struct msgMQ),IPC_NOWAIT)<0){
                        perror("Erreur msgsnd");
                        exit(EXIT_FAILURE);
                    }
                }           
            }

            printf("il y a %d joueur\n",nombre_de->joueur);
        }


    La fonction handler

        void handler(int numsig){
        if(numsig==SIGALRM){
            alarmOK=1;
        }
        if(numsig==SIGINT){
            int i=0;
            printf("SERVER CLOSING\n");
            for(i=0;i<nombre_de->joueur;i++){
                msgMQ.pid = tabPid[i];
                msgMQ.u.type = 'A';
                if(msgsnd(msgq_id,&msgMQ,sizeof(struct msgMQ),IPC_NOWAIT)<0){
                    perror("Erreur msgsnd");
                    exit(EXIT_FAILURE);
                }
            }
            if(close(fifo)<0){
                perror("Erreur close");
                exit(EXIT_FAILURE);
            }
            shmdt(repartition);
            shmdt(nombre_de);
             shmdt(joueurs);
            delmem(shm_id_nbr_nbj);
            delmem(shm_id_repart);
            delmem(shm_id_joueur);
            exit(EXIT_SUCCESS);
        }
    • Partager sur Facebook
    • Partager sur Twitter
      21 avril 2006 à 20:45:50

      Déjà, piste ça précisément avec un débogueur parce que "au retour de la fonction", j'y crois bof personnellement.
      Et mets aussi les déclarations des variables que tu utilises. Ensuite tu dis que tu appelles kill mais tu parles d'alarm, alors tu appelles kill ou les signaux viennent du système ?
      Si on cite le standard (POSIX) on trouve :

      Citation : posix 1003.1, 2004

      If the signal occurs other than as the result of calling abort(), raise(), [CX] [Option Start] kill(), pthread_kill(), or sigqueue(), [Option End] the behavior is undefined if the signal handler refers to any object with static storage duration other than by assigning a value to an object declared as volatile sig_atomic_t, or if the signal handler calls any function in the standard library other than one of the functions listed in Signal Concepts. Furthermore, if such a call fails, the value of errno is unspecified.


      • Partager sur Facebook
      • Partager sur Twitter
        21 avril 2006 à 22:41:44

        Le débugger j'avais penser mais il me dit rien de plus malheureusement :s, ensuite aujourd'hui j'ai vu un de mes prof et bon il a un peu debuggué mon pgm avec moi, et lui il en a convenu que c'était l'adresse d'une shared memory que j'avais modifier à l'ecole ca se voyait bien d'ailleur en affichant les adresses sur un vieux système unix... Mais chez moi de un je ne vois plus ce changement d'adresse alors que mon code n'a pas changé pendant le trajet unif->home. et de deux chez moi j'ai pas du tout la meme erreur et à un autre endroit, je suppose que c'est la différence de distribution mais bon...

        en fait je n'utilise pas kill mais alarm, mais le résultat est le même vu que c'est alarm qui au bout de qq seconde envoie le signal.

        je vais pas laissé tout mon code car ca fais 3 fichiers mais je le met en dl sur mon site ici

        comme tu m'as demandé les déclarations et que j'ai un peu bougé au code pour tester qq chose mais ca va toujours pas, et c'est toujour la meme erreur.. :(


        #include<stdio.h>
        #include<stdlib.h>
        #include<sys/ipc.h>
        #include<sys/types.h>
        #include <errno.h>
        #include<sys/shm.h>
        #include<sys/sem.h>
        #include <sys/stat.h>
        #include <fcntl.h>
        #include <string.h>
        #include <signal.h>
        #include "comonConf.h"

        void init();
        void delmem(int shid);
        void handler(int numsig);
        void shufflePion();
        void initJeux();
        char* distribDe(int joueur);

        int   shm_id_lecteur;
        int   shm_id_repart;
        int   shm_id_joueur;
        int   msgq_id;

        /*Declation pour semaphore*/
        int semid;
        /*Declaration pour fifo*/
        int fifo;
        int jeux;
        pid_t tabPid[5];
        int tabDistrib[28]={1,2,2,3,3,3,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,7};
        int alarmEnvoi;
        int alarmOK;
        int joueurCourant;
        int joue;

        struct st_shm_repart* repartition;
        struct lecteur* lecteur;
        struct shared_joueurs* joueurs;
        struct msgFifo msgFifo;
        struct msgMQ msgMQ;

        main(void){
               
                /*Declation pour sharedmemory*/
                key_t shm_k_repart;
                key_t shm_k_lecteur;
                key_t shm_k_joueur;
                key_t k_sem;
                key_t msgq_k;

                struct sigaction sig;
                sig.sa_handler = handler;
                if(sigemptyset(&sig.sa_mask)){
                        perror("ERREUR sigemptyset");
                        exit(EXIT_FAILURE);
                }
                if(sigaction(SIGINT,&sig,NULL)){
                        perror("ERREUR sigemptyset");
                        afficheErrno();
                        exit(EXIT_FAILURE);
                }
                if(sigaction(SIGALRM,&sig,NULL)){
                        perror("ERREUR sigemptyset");
                        afficheErrno();
                        exit(EXIT_FAILURE);
                }
               
                printf("SERVEUR DAMEMO : MAJ 2006-04-16\n");

        /********************SHARED MEM LECTEURS*****************************/ 
                shm_k_lecteur = keygen(1);
                if((shm_id_lecteur = shmget(shm_k_lecteur,sizeof(struct lecteur),IPC_CREAT|0666))<0){
                        perror("ERREUR : SHMGET : lecteur");
                        afficheErrno();
                        exit(EXIT_FAILURE);
                }
                if((lecteur = (struct lecteur*)shmat(shm_id_lecteur,NULL,0)) ==(void*)-1 ){
                        perror("ERREUR : SHMGAT : lecteur");
                        afficheErrno();
                        exit(EXIT_FAILURE);
                }
                printf("SHARED MEMORY : lecteur : ID : %d, cle : %d\n",shm_id_lecteur,shm_k_lecteur);

        /********************SHARED MEM REPARTITION DES PIONS*****************************/     
                shm_k_repart=keygen(2);
                if((shm_id_repart = shmget(shm_k_repart,sizeof(struct st_shm_repart),IPC_CREAT|0666))<0){
                        perror("ERREUR : SHMGET : repartition");
                        afficheErrno();
                        exit(EXIT_FAILURE);
                }
                if((repartition = (struct st_shm_repart*)shmat(shm_id_repart,NULL,0)) ==(void*)-1 ){
                        perror("ERREUR : SHMAT : repartition");
                        afficheErrno();
                        exit(EXIT_FAILURE);
                }
                printf("SHARED MEMORY : repartition : ID : %d, cle : %d\n",shm_id_repart,shm_k_repart);

        /********************SHARED MEM JOUEURS*****************************/   
                shm_k_joueur = keygen(9);
                if((shm_id_joueur = shmget(shm_k_joueur,sizeof(struct shared_joueurs),IPC_CREAT|0666))<0){
                        perror("ERREUR : SHMGET : joueurs");
                        afficheErrno();
                        exit(EXIT_FAILURE);
                }
                if((joueurs = (struct shared_joueurs*)shmat(shm_id_joueur,NULL,0)) ==(void*)-1 ){
                        perror("ERREUR : SHMAT : joueurs");
                        afficheErrno();
                        exit(EXIT_FAILURE);
                }
                printf("SHARED MEMORY : joueurs : ID : %d, cle : %d\n",shm_id_joueur,shm_k_joueur);

        /*******************MESSAGE QUEUE*************************/
                msgq_k = keygen(6);
                if((msgq_id = msgget(msgq_k,IPC_CREAT|0666))<0){
                        perror("Erreur message Q");
                        exit(EXIT_FAILURE);
                }

        /*******************SET SEMAPHORE********************************/
                k_sem=keygen(7);
                if((semid=semget(k_sem,1,IPC_CREAT|0666))<0){
                        perror("Erreur semget");
                        exit(EXIT_FAILURE);
                }
                if(semctl(semid,0,SETVAL,1)<0){
                        perror("Erreur semctl");
                        exit(EXIT_FAILURE);
                }/*note pour plutard sous HPUX on peut utiliser SETALL sans tableau...*/
                printf("SET SEMAPHORE : ID %d, cle : %d\n",semid,k_sem);
               
                init();
                afficheRepartition(repartition);

        /******************SET FIFO******************************************/
                if(mkfifo(PATH_FIFO,0777)<0){
                        if(errno!=EEXIST){
                                perror("Erreur mkfifo");
                                exit(EXIT_FAILURE);
                        }else{
                                perror("fifo already exists, but show must go on :p");
                        }
                }
                printf("jouvre la fifo qui se trouve %s\n", PATH_FIFO);
                if((fifo=open(PATH_FIFO,O_RDONLY))<0){
                        perror("Erreur open");
                        exit(EXIT_FAILURE);
                }
                printf("fifo ouverte en read\n");

        /****************ON COMMENCE LA PARTIE ICI******************************/       
                jeux=0;
                alarmEnvoi=0;
                alarmOK=0;
                joue=0;
                joueurCourant=0;
                while(1){
                       
                        if(jeux == 0 && joueurs->nb == 5){
                                printf("DEBUT DE PARTIE : 5 joueurs\n");
                                jeux=1
                                initJeux();
                        }
                        if(jeux == 0 && alarmOK == 1 && joueurs->nb >= 2 && joueurs->nb < 5){
                                printf("DEBUT DE PARTIE : de 2 a 4 joueurs\n");
                                jeux=1;
                                joueurCourant=0;
                                joue=1;
                                initJeux();

                                msgMQ.pid = tabPid[joueurCourant];
                                msgMQ.u.type= 'J';

                                if(msgsnd(msgq_id,&msgMQ,sizeof(struct msgMQ),IPC_NOWAIT)<0){
                                        perror("Erreur msgsnd");
                                        exit(EXIT_FAILURE);
                                }

                        }
                        if(read(fifo,&msgFifo,sizeof(struct msgFifo)) <=0){
                                if(errno==EINTR){
                                        continue;
                                }else{
                                        perror("ERREUR lecture fifo");
                                        exit(EXIT_FAILURE);
                                }
                        }
                        if(msgFifo.type=='I'){
                                if(joueurs->nb<5 && jeux==0){
                                        printf("Oh on doit inscrire quelqu un\n");
                                        strcpy(joueurs->tabJoueur[joueurs->nb].nom,msgFifo.u.s.nom);
                                        strcpy(joueurs->tabJoueur[joueurs->nb].prenom,msgFifo.u.s.prenom);
                                        tabPid[joueurs->nb]=msgFifo.pid;
                                        printf("SERVER a inscrit : %s %s, pid %d\n", joueurs->tabJoueur[joueurs->nb].nom, joueurs->tabJoueur[joueurs->nb].prenom,msgFifo.pid);
                                        joueurs->nb=joueurs->nb+1;
                                       
                                        msgMQ.pid = msgFifo.pid;
                                        msgMQ.u.s.type = 'O';
                                        msgMQ.u.s.numJoueur = joueurs->nb;
                                       
                                        if(msgsnd(msgq_id,&msgMQ,sizeof(struct msgMQ),IPC_NOWAIT)<0){
                                                perror("Erreur msgsnd");
                                                exit(EXIT_FAILURE);
                                        }
                                        if(joueurs->nb == 1 && alarmEnvoi == 0){
                                                alarm(30);
                                                alarmEnvoi=1;
                                                alarmOK=0;
                                        }
                                       
                                }else{
                                        msgMQ.pid = msgFifo.pid;
                                        msgMQ.u.type = 'K';
                                        if(msgsnd(msgq_id,&msgMQ,sizeof(struct msgMQ),IPC_NOWAIT)<0){
                                                perror("Erreur msgsnd");
                                                exit(EXIT_FAILURE);
                                        }
                                }                     
                        }
                        if(msgFifo.type=='P'){
                                printf("Oh c'est une proposition\n");
                                /*regarder dans tab des pion du joueur si la prop s'y trouve, si oui alors rajouter dans
                                 *la shared o bon endroit et avertir l'autre que c bon et qu'il doi joué on garde le joue=1
                                 *avertir les autre qu'il a eu bon
                                 *sinon ba dire a lautre que c rater joue=0 dire au autre qu'il a rate
                                 */

                        }
                        printf("il y a %d joueur\n",joueurs->nb);

                }
                printf("SERVER CLOSING\n");
                if(close(fifo)<0){
                        perror("Erreur close");
                        exit(EXIT_FAILURE);
                }
                shmdt(repartition);
                shmdt(lecteur);
                shmdt(joueurs);
                delmem(shm_id_lecteur);
                delmem(shm_id_repart);
                delmem(shm_id_joueur);
                exit(0);
        }
        void shufflePion(){
                int i; 
                int valrand1,valrand2;
                int tmp=0;
                srand((int)time(NULL));
                for(i=0;i<31;i++){
                        valrand1=rand()%28;
                        valrand2=rand()%28;
                        tmp=tabDistrib[valrand1];
                        tabDistrib[valrand1]=tabDistrib[valrand2];
                        tabDistrib[valrand2]=tmp;
                }
        }
        void initJeux(){
                int i;
                shufflePion();
                for(i=0;i<joueurs->nb;i++){
                        msgMQ.pid = tabPid[i];
                        msgMQ.u.type = 'D';
                        strcpy(msgMQ.u.s2.pion1, distribDe(1));
                        strcpy(msgMQ.u.s2.pion2, distribDe(2));
                        strcpy(msgMQ.u.s2.pion3, distribDe(3));
                        strcpy(msgMQ.u.s2.pion4, distribDe(4));
                        if(msgsnd(msgq_id,&msgMQ,sizeof(struct msgMQ),IPC_NOWAIT)<0){
                                perror("Erreur msgsnd");
                                exit(EXIT_FAILURE);
                        }
                }/*
                joueur->visible[];*/

                /*mettre a jour les shared mem avec les pions visibles*/
        }
        char* distribDe(int joueur){
                int i;
                char* chaine = (char*)malloc(sizeof(char)*repartition->repartTab[joueurs->nb][1]);
                char*ptr = chaine;
                for(i=0;i<repartition->repartTab[joueurs->nb][1]*joueur;i++){
                        strcpy(ptr,tabDistrib[i]+" ");
                        ptr++;
                }
                return chaine;
        }
        void delmem(int shid){
                if(shmctl(shid,IPC_RMID,NULL)<0){
                        perror("Erreur delete mem");
                        exit(1);
                }
        }
        void init(){
                joueurs->nb=0;
                lecteur->nb=0
                repartition->repartTab[0][0]= 2;
                repartition->repartTab[0][1]= 7;
                repartition->repartTab[0][2]= 7;
                repartition->repartTab[0][3]= 7;
                repartition->repartTab[1][0]= 3;
                repartition->repartTab[1][1]= 7;
                repartition->repartTab[1][2]= 7;
                repartition->repartTab[1][3]= 0;
                repartition->repartTab[2][0]= 4;
                repartition->repartTab[2][1]= 5;
                repartition->repartTab[2][2]= 4;
                repartition->repartTab[2][3]= 4;
                repartition->repartTab[3][0]= 5;
                repartition->repartTab[3][1]= 4;
                repartition->repartTab[3][2]= 4;
                repartition->repartTab[3][3]= 4;
        }
        void handler(int numsig){
                if(numsig==SIGALRM){
                        alarmOK=1;
                }
                if(numsig==SIGINT){
                        int i=0;
                        printf("SERVER CLOSING\n");
                        for(i=0;i<joueurs->nb;i++){
                                msgMQ.pid = tabPid[i];
                                msgMQ.u.type = 'A';
                                if(msgsnd(msgq_id,&msgMQ,sizeof(struct msgMQ),IPC_NOWAIT)<0){
                                        perror("Erreur msgsnd");
                                        exit(EXIT_FAILURE);
                                }
                        }
                        if(close(fifo)<0){
                                perror("Erreur close");
                                exit(EXIT_FAILURE);
                        }
                        shmdt(repartition);
                        shmdt(lecteur);
                       shmdt(joueurs);
                        delmem(shm_id_lecteur);
                        delmem(shm_id_repart);
                        delmem(shm_id_joueur);
                        exit(EXIT_SUCCESS);
                }
        }
        • Partager sur Facebook
        • Partager sur Twitter

        syscall signal provoque un segmentation fault

        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
        • Editeur
        • Markdown