Forum Programmation.c passer une struct dans une shared memory POSIX

Posté par  .
Étiquettes : aucune
0
13
avr.
2005
Salut,
j'ai un probleme pour faire passer et recuperer une structure dans une shared memory POSIX.
J'ai 3 process (pour l'instant) : PS1 recoit des donnees saisies au clavier , les met dans une structure et la passe au PS2 par un tube nommé (jusque la pas de prob).
PS2 ouvre et mappe une shared memory et y passe la structure recuperee sur le tube
PS3 recupere la structure dans la shared memory et affiche le resultat

Les 3 ps passent bien la compilation, la comm est ok entre ps1 et ps2 mais a l'execution PS3 se met en erreur de segmentation (dumped core).
Ce code est compile et execute sur un alpha Tru64 v4.0
quelqu'un a une idee?

[code] PS2

/*___________________________________DECLARATIONS POUR MEMOIRE PARTAGEE GLOBLALE_____*/
int shm_etage1;
int shm_etage2;
caddr_t shm_ptr1;
//caddr_t shm_ptr2;

main (int argc, char *argv[])
{
printf("\n\t\tPROGRAMME PRINCIPAL");
int lire;
char lettre = 'A';
int i;

struct transport trajet;
int t=1;
trajet.actuel=0;
trajet.dest=0;
trajet.NB_pass=0;
lire = open("tube", O_RDONLY);
shm_etage1 = shm_open ( "/tmp/etage1", (O_CREAT | O_RDWR), 0 );
// shm_etage2 = shm_open ( "/tmp/etage2", (O_CREAT | O_RDWR), 0 );
ret_val = fchmod ( shm_etage1 , (mode_t) S_IRWXG | S_IRWXU | S_IRWXO );
// ret_val = fchmod ( shm_etage2 , (mode_t) S_IRWXG | S_IRWXU | S_IRWXO );
ret_val = ftruncate (shm_etage1, sizeof(struct transport));
// ret_val = ftruncate (shm_etage2, sizeof(struct transport));
shm_ptr1 = mmap ((caddr_t) 0, sizeof(struct transport), PROT_WRITE|PROT_READ, MAP_SHARED, shm_etage1, 0 );
// shm_ptr2 = mmap ((caddr_t) 0, sizeof(struct transport), PROT_WRITE|PROT_READ, MAP_SHARED, shm_etage2, 0 );
while(trajet.NB_pass != -1)
{
read(lire,(char*) &trajet,sizeof(struct transport));
printf("\nTrajet %d : %d passagers vont de l'etage %d a l'etage %d", t++, trajet.NB_pass, trajet.actuel, trajet.dest);
struct transport shm_ptr1= trajet;
}
//close("tube");
printf("\nFIN PROGRAMME");

ret_val = munmap ( shm_ptr1 , sizeof(struct transport) );
//ret_val = munmap ( shm_ptr2 , sizeof(struct transport) );
ret_val = close ( shm_etage1 );
//ret_val = close ( shm_etage2 );
ret_val = shm_unlink ( "/tmp/etage1" );
//ret_val = shm_unlink ( "/tmp/etage2" );
}


code PS3



/*___________________________________DECLARATIONS POUR MEMOIRE PARTAGEE GLOBLALE_____*/
int shm_etage1;
int shm_etage2;
caddr_t shm_ptr1;


main (int argc, char *argv[])
{

struct transport* transp_shm_ptr1 = (struct transport*) shm_ptr1;


struct transport trajet;
shm_etage1 = shm_open ( "/tmp/etage1", ( O_RDWR), 0 );
shm_ptr1 = mmap ((caddr_t) 0, 3, PROT_READ, MAP_SHARED, shm_etage1, 0 );
sleep(2);
trajet = *transp_shm_ptr1;
//trajet = *shm_ptr1;
printf("actuel %d, dest %d, nbpass %d", trajet.actuel, trajet.dest, trajet.NB_pass);
//printf("\n en memoire : %c", d);
ret_val = munmap ( shm_ptr1 , 3 );
ret_val = close ( shm_etage1 );

}

PS1 n'a pas d'interet
  • # ouh lala...

    Posté par  . Évalué à 3.

    Je me poses une question :

    Tu n'as jamais pense a traiter les cas possibles d'erreur pour tes appels de fonction ?

    Parce que nulle part dans ton soft tu ne verifies la valeur de retour des fonctions et regarde si l'appel a echoue, pas etonnant que ton soft s'ecrase dans ce cas.

    Lors d'une revue de code, le moindre appel de fonction ou la valeur de retour n'est pas verifiee est marque comme un bug, car c'en est un(sauf dans les cas tres rares ou on est sur a 100%(j'ai dit 100, pas 99) que l'appel ne _peut pas_ echouer), je te propose donc d'ajouter le code de verification manquant, ca evitera que ton soft plante, et ca te permettra de trouver ou se situe le probleme.
  • # Pointeur non initialisé

    Posté par  . Évalué à 2.

    Dans ps3.c, tu fais:

    caddr_t shm_ptr1;

    struct transport* transp_shm_ptr1 = (struct transport*) shm_ptr1;
    trajet = *transp_shm_ptr1;

    shm_ptr1 n'est pas initialisé. Tu mets cette valeur dans trans_shm_ptr1;
    Tu accèdes à la zone mémoire pointée par trans_shm_ptr1 ensuite.
    Et *boum*.

    Le code correct serait:

    struct transport* transp_shm_ptr1;

    [...]
    shm_ptr1 = mmap ((caddr_t) 0, 3, PROT_READ, MAP_SHARED,shm_etage1, 0 );
    transp_shm_ptr1 = (struct transport*) shm_ptr1;

    trajet = *transp_shm_ptr1;


    Tout cela n'enlève rien à la très pertinente remarque de pasBill sur le fait
    que tu DOIS tester le code de retour des fonctions.
    • [^] # Re: Pointeur non initialisé

      Posté par  . Évalué à 2.

      Ce qui me pique aussi un petit peu les yeux ce sont toutes ces variables declarees et non initialisees...

      Je suis peut-etre maniaque mais j'aime bien avoir un code ou toutes les variables et (en C++) toutes les instances de classes sont *bien* initialisees.

      Et il me semble pour finir, que ca fait partie des bonnes pratiques de developpement d'initialiser ses pointeurs a NULL ou 0... C'est pas tres fun les dangling pointers.

      PS: C'est sur que c'est toujours plus facile de voir les "bourdes"/maladresses du code de son prochain plutot que chez soi. :P

      PPS: D'ailleurs c'est un peu le principe de la relecture de code par ses pairs.
      • [^] # Re: Pointeur non initialisé

        Posté par  . Évalué à 1.

        voila g corrige et ca marche.....

        code PS2:



        #include <sys/types.h>
        #include <sys/mman.h>
        #include <sys/stat.h>
        #include <sys/fcntl.h>
        #include <fcntl.h>
        #include <errno.h>
        #include <stdio.h>
        #include <unistd.h>
        #include <signal.h>
        #include <semaphore.h>
        #include <sys/mode.h>

        struct ascenceur
        {
        int id;
        int charge;
        int portes;
        int NB_in;
        int NB_max;
        int dest;
        };

        struct etage
        {
        int id;
        int occupation;
        int asc_stop;
        };



        /*____________________________________DECLARATIONS POUR SEMAPHORES NOMMES_____________*/
        sem_t *ptr_sema=NULL ;
        sem_t *ptr_sema2=NULL;
        int oflags = O_CREAT ;
        mode_t mode = 0644 ;
        const char semname1 [] = "/tmp/semapn" ;
        const char semname2 [] = "/tmp/semapm" ;
        unsigned int value = 1 ;




        int ret_val ;
        struct transport
        {
        int actuel ;
        int dest ;
        int NB_pass;
        }trajet, trajet2;

        /*___________________________________DECLARATIONS POUR MEMOIRE PARTAGEE GLOBLALE_____*/
        int shm_etage1;
        int shm_etage2;
        caddr_t shm_ptr1;


        main (int argc, char *argv[])
        {
        printf("\n\t\tPROGRAMME PRINCIPAL");
        int lire;
        struct transport trajet;
        int t=1;
        trajet.actuel=3;
        trajet.dest=4;
        trajet.NB_pass=5;


        /*ouverture du tube*/
        lire = open("tube", O_RDONLY);
        /*creation memoire partagee*/
        shm_etage1 = shm_open ( "/tmp/etage1", (O_CREAT | O_RDWR), 0 );
        if(shm_etage1 == -1)
        perror("\nopen shm_etage1 failled:");
        /*modification des droits d'acces*/
        ret_val = fchmod ( shm_etage1 , (mode_t) S_IRWXG | S_IRWXU | S_IRWXO );
        if(ret_val == -1)
        perror("\nfchmod etage 1 failled:");
        /*creation d'un semaphore nomme*/
        ptr_sema = sem_open ( semname1, oflags, mode, value );
        if ( ptr_sema == (void *) -1 )
        { perror ( "\n\rMAIN : sem_open failed->sem1 !!!" ); exit( 1 ); }


        /*creation d'un semaphore nomme*/

        ptr_sema2 = sem_open ( semname2, oflags, mode, value );
        if ( ptr_sema == (void *) -1 )
        { perror ( "\n\rMAIN : sem_open failed ->sem2!!!" ); exit( 1 ); }
        printf("\n*****OK 2 SEMAPHORES CREES*****\n");


        /*positionnement de la taille de la memoire partagee*/
        ret_val = ftruncate (shm_etage1, sizeof(struct transport));
        if(ret_val == -1)
        perror("\nftruncate etage 1 failled:");
        /*mapping de la zone*/
        shm_ptr1 = mmap ( 0, sizeof(struct transport), PROT_WRITE|PROT_READ, MAP_SHARED, shm_etage1, 0 );
        if(ret_val == -1)
        perror("\nmmap etage 1 failled:");
        /*casting du pointeur d'adresse*/
        struct transport* transp_shm_ptr1 = (struct transport*) shm_ptr1;

        while(trajet.NB_pass != -1)
        {
        /*lecture du tube*/
        read(lire,(char*) &trajet,sizeof(struct transport));
        printf("\nTrajet %d : %d passagers vont de l'etage %d a l'etage %d", t++, trajet.NB_pass, trajet.actuel, trajet.dest);
        /*BLOQUAGE ACCES MEMOIRE -->EVITER VIOLATION DE PARTAGE */
        ret_val = sem_wait ( ptr_sema ) ;
        if ( ret_val == -1 )
        { perror ( "\n\rMAIN : sem_wait failed !!!" ); }

        /*ecrire en memoire*/
        *transp_shm_ptr1 = trajet;

        /*DEBLOQUAGE ACCES MEMOIRE*/
        ret_val = sem_post ( ptr_sema ) ;
        if ( ret_val == -1 )
        { perror ( "\n\rMAIN : sem_post failed !!!" ); }
        /*VALIDATION POUR SYNCHRO PROCESSUS*/
        ret_val = sem_post ( ptr_sema2) ;
        if ( ret_val == -1 )
        { perror ( "\n\rMAIN : sem_post failed !!!" ); }




        //sleep(4);


        }

        /*FERMETURE SEMAPHORE*/
        ret_val = sem_close (ptr_sema);
        if (ret_val == -1)
        { perror ("\n\rMAIN : sem_close failed !!!"); }
        /*DESTRUCTION SEMAPHORE*/
        ret_val = sem_unlink (semname1);
        if (ret_val == -1)
        { perror ("\n\rMAIN : sem_unlink failed !!!"); }
        printf("\n\r*****Fermeture et destruction de /tmp/semapm*****\n");

        ret_val = sem_close (ptr_sema2);
        if (ret_val == -1)
        { perror ("\n\rMAIN : sem_close failed !!!"); }

        ret_val = sem_unlink (semname2);
        if (ret_val == -1)
        { perror ("\n\rMAIN : sem_unlink failed !!!"); }
        printf("\n\r*****Fermeture et destruction de /tmp/semapn*****\n");


        printf("\nFIN PROGRAMME");
        /*de-mapping de la memoire*/
        ret_val = munmap ( shm_ptr1 , sizeof(struct transport) );
        /*fermeture memoire partagee*/
        ret_val = close ( shm_etage1 );
        /*destruction objet memoire*/
        ret_val = shm_unlink ( "/tmp/etage1" );
        }


        code PS3



        #include <sys/types.h>
        #include <sys/mman.h>
        #include <sys/stat.h>
        #include <sys/fcntl.h>
        #include <fcntl.h>
        #include <errno.h>
        #include <stdio.h>
        #include <unistd.h>
        #include <signal.h>
        #include <semaphore.h>
        #include <sys/mode.h>

        struct ascenceur
        {
        int id;
        int charge;
        int portes;
        int NB_in;
        int NB_max;
        int dest;
        };

        struct etage
        {
        int id;
        int occupation;
        int asc_stop;
        };

        struct transport
        {
        int actuel ;
        int dest ;
        int NB_pass;
        };

        /*____________________________________DECLARATIONS POUR SEMAPHORES NOMMES_____________*/
        sem_t *ptr_sema=NULL ;
        sem_t *ptr_sema2=NULL;
        int oflags = O_CREAT ;
        mode_t mode = 0644 ;
        const char semname1 [] = "/tmp/semapn" ;
        const char semname2 [] = "/tmp/semapm" ;
        unsigned int value = 0 ;
        int ret_val ;


        /*___________________________________DECLARATIONS POUR MEMOIRE PARTAGEE GLOBLALE_____*/
        int shm_etage1;
        int shm_etage2;
        caddr_t shm_ptr1;


        main (int argc, char *argv[])
        {
        struct transport* transp_shm_ptr1;
        struct transport trajet;
        trajet.actuel=0;
        trajet.dest=0;
        trajet.NB_pass=0;

        printf("\n\t\tSUPERVISION");
        printf("\n\t\t***********");

        // sleep(4);

        /*ouverture de la memoire partagee*/
        shm_etage1 = shm_open ( "/tmp/etage1", ( O_RDWR), 0 );
        if(shm_etage1 == -1)
        perror("\nopen etage 1 failled:");
        printf("\nmem ouverte");
        sleep(2);
        /*mapping de la memoire*/
        shm_ptr1=mmap(0,sizeof(struct transport),PROT_READ,MAP_SHARED,shm_etage1,0);
        if(ret_val == -1)
        perror("\nmmap etage 1 failled:");
        printf("\nmem mappee");
        /*casting du pointeur d'adresse*/
        transp_shm_ptr1=(struct transport*) shm_ptr1;
        /*OUVERTURE SEMAPHORE NOMME*/
        ptr_sema = sem_open ( semname1, oflags, mode, value );
        if ( ptr_sema == (void *) -1 )
        {perror ( "\n\rMAIN : sem_open failed !!!" );
        exit(1);}
        printf("\nsem1 ouvert");
        /*OUVERTURE DU SEMAPHORE NOMME DE SYNCHRONISATION*/
        ptr_sema2 = sem_open ( semname2, oflags, mode, value );
        if ( ptr_sema == (void *) -1 )
        {perror ( "\n\rMAIN : sem_open failed !!!" );
        exit(1);}
        printf("\nsem2 ouvert");
        while(transp_shm_ptr1->NB_pass != -1)
        {
        printf("\nDans boucle");
        /*ESSAIS DE LECTURE SANS BLOQUAGE*/
        ret_val = sem_trywait ( ptr_sema2 ) ;
        printf("\nsem try wait");
        /*BLOQUAGE ACCES MEMOIRE-->POUR EVITER VIOLATION DE PARTAGE*/
        ret_val = sem_wait ( ptr_sema ) ;
        if ( ret_val == -1 )
        { perror ( "\n\rMAIN : sem_wait failed sem_mem (PTR_SEMA)!!!" ); }
        printf("\nsem wait");
        /*lecture de la memoire champ a champ*/
        trajet.actuel=transp_shm_ptr1->actuel;
        trajet.dest = transp_shm_ptr1->dest;
        trajet.NB_pass = transp_shm_ptr1->NB_pass;


        printf("\nactuel %d, dest %d, nbpass %d", trajet.actuel, trajet.dest, trajet.NB_pass);
        /*DEBLOQUAGE ACCES MEMOIRE*/
        ret_val = sem_post ( ptr_sema ) ;
        if ( ret_val == -1 )
        { perror ( "\n\rMAIN: sem_post failed sem_mem for PTR_SEMA!!!" ); }

        }/*fin while*/


        //sleep(4);

        /*FERMETURE SEMAPHORE*/
        ret_val = sem_close (ptr_sema);
        if (ret_val == -1)
        { perror ("\n\rMAIN : sem_close failed !!!"); }


        ret_val = sem_close (ptr_sema2);
        if (ret_val == -1)
        { perror ("\n\rMAIN : sem_close failed !!!"); }



        /*de mapping de la memoire partagee*/
        ret_val = munmap ( shm_ptr1 , sizeof(struct transport) );
        if (ret_val == -1)
        { perror ("\n\rMAIN : munmap failed !!!"); }
        /*fermeture de la memoire*/
        ret_val = close ( shm_etage1 );
        if (ret_val == -1)
        { perror ("\n\rMAIN : close failed !!!"); }

        }


        Merci pour les conseils

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.