Partage
  • Partager sur Facebook
  • Partager sur Twitter

segmentation fault lors en réception d'un signal

Sujet résolu
    22 mai 2022 à 18:51:32

    (re)Bonjour.

    Je fais un td qui a pour but de me faire programmer un scheduler qui tourne sur une machine, les coeurs de la machine sont des pthreads et les threads de la machine sont des contextes. Mon problème est que lorsque j'envoie un signal à un thread (pour la 2e fois), au lieu d'appeler le signal handler, il fait un segmentation de fault.  Il est un peu gros, mais je vous met les parties utiles à la compréhension de mon problème.

    Le thread principal attends sur join. Il y a un autre thread qui appelle la fonction rr (pour roundrobin). Elle s'applique sur un tableau de threads (vcpu_tab) de taille nb_vcpu. La voici.

    void* rr(void* param){
    	while(1){
    		
    		redistribution();
    		
    		dring();
    		
    		sleep(scheduler.quantum);
    	}
    	
    }
    void dring() {//envoie à chacun des nb_vcpu threads un signal sigusr1

    for (int i = 0 ; i < nb_vcpu ; i++) {

    pthread_kill(vcpu_tab[i].thread,SIGUSR1);
    }
    }
    void redistribution(){


    if(nb_vcpu>=nb_uth){//si pas trop de uth, assigner les vcpu aux uthreads de façon cannonique
    for(int i=0;i<nb_uth;i++){
    vcpu_tab[i].next_uthread=i;

    }
    for(int i=nb_uth;i<nb_vcpu;i++){
    vcpu_tab[i].next_uthread=-1;
    }
    scheduler.nxt_uth = 0 ;
    }
    else{//si plus de uth que de vcpu, faire les rotations
    for(int i=0;i<nb_vcpu;i++){
    vcpu_tab[i].next_uthread=scheduler.nxt_uth;
    scheduler.nxt_uth=(scheduler.nxt_uth+1)%nb_uth;
    }

    }


    }

     Chaque thread du tableau est lancé sur la fonction :

    void* idle_vcpu(void* vcpu) {
    	
    	vcpu_t* vcp=(vcpu_t*)vcpu;
    	vcp->tid=pthread_self();
    	
    	//configuration du signal handler
    	struct sigaction sa;
    	sa.sa_handler = idle_handlersig;
    	sa.sa_flags = SA_RESTART;
        
    	sigaction(SIGUSR1,&sa,NULL);
    	
    	
    	sigemptyset(&sa.sa_mask);
    	//sigaddset(&sa.sa_mask,SIGUSR1); 
    	//SIGUSR1 sera le signal qui servira à faire les changements de uThreads
        	while(1){
    		sigsuspend(&sa.sa_mask);
    		printf("Pause dans le sigsuspend\n");
    	}
    	return NULL;
    }
    

    Le sigaction du signal SIGUSR1 est

    void idle_handlersig(int signal){
    	printf("On rentre dans handlesignal\n");
    	int i;
    	if(signal==SIGUSR1){
    		
    		i=get_vcpu_indice();
    		printf("Le i c'est %d\n",i);
    		if (i!=-1 && vcpu_tab[i].current_uthread == -1) { // Alors, c'est qu'on est au moment où l'on dit à un vcpu d'effectuer son premier uThread
    			printf("E1\n");
    			int nxt=vcpu_tab[i].next_uthread;	
    			printf("E2\n");	
    					
    			printf("Le vcpu %d va s'occupper du uthread %d.\n",i,nxt);
    			
    			if(nxt!=-1 && nxt!=vcpu_tab[i].current_uthread){
    				//passage du contexte idle au contexte spécifié
    				
    				vcpu_tab[i].current_uthread=nxt;
    				swapcontext(&(vcpu_tab[i].idle_contxt),&uth_tab[nxt]);
    			}
    		}
    		else { // Sinon, c'est un signal que le Scheduler lui envoie pour qu'il passe à son prochain uThread.
    			int nxt = vcpu_tab[i].next_uthread;
    			int cur = vcpu_tab[i].current_uthread ;
    			printf("Le vcpu %d va s'occupper du uthread %d.\n",i,nxt);
    			
    			if(nxt!=-1){
    				//passage d'un contexte à un autre
    				swapcontext(&uth_tab[cur],&uth_tab[nxt]);
    			}
    			else{
    				//passage d'un contexte à idle
    				swapcontext(&uth_tab[nxt],&(vcpu_tab[i].idle_contxt));
    			}
    			
    		}
    			
    			
    	}
    }

    En gros a la réception du signal sigusr1, un threads du tableau vcpu_tab peut switcher de context, pour la fonction que j'ai mis en main:

    void g(){
    	//int* a=d;
    	
    	while(1){
    		printf("Salut uthread ecrit %d ( c la fct g la)\n",5);
    	
    		sleep(1);
    	}
    }
    
    int main(){
    	
    	
    	
    	
    	config_sched(ROUND_ROBIN,3);
    	create_vcpu(1);
    	
    	
    	
    	
    	int arg1=1;
    	//int  arg2=2, arg3=3;
    	
    	uthread_create(&g,&arg1);
    	//uthread_create(&f,&arg2);
    	//uthread_create(&f,&arg3);
    	
    	
    	
    	
    	
    	run();
    	
    	
    	
    	
    	
    	
    	join();
    }

    Et à l'éxecution, la fonction f se lance une fois, puis au 2e tour de roundrobin, j'ai le message "Segmentation fault". En débogant, j'ai vu que cette erreur apparait en réception de sigusr1, avant le début de l'appel au signal handler. Entre la réception des deux signaux, il y a un context switch.

    J'ai conscience du fait que j'envoie un pavé, mais je ne m'en sors pas. Merci de votre aide.

    -
    Edité par BelhouariSéhane 22 mai 2022 à 18:54:29

    • Partager sur Facebook
    • Partager sur Twitter
    Le basheur
      22 mai 2022 à 19:21:24

      BelhouariSéhane a écrit:

      [...]

      J'ai conscience du fait que j'envoie un pavé, mais je ne m'en sors pas. Merci de votre aide.

      -
      Edité par BelhouariSéhane il y a 21 minutes


      Bonjour,

      lorsque tu as des segfault il y a un outil indispensable : valgrind.

      Installe le, compile ton projet en activant les options de debug (-g avec gcc/clang), lance ton appli avec valgrind en lui donnant les options --leak-check=full --track-origins=yes --show-reachable=yes.

      Tu auras un log précis de ce qui cause ton segfault. Éventuellement tu peux utiliser un debuger pour bien cibler en mode pas à pas … mais en général le log valgrind suffit. Comme tu fais du multithread, note bien les TID pour t'y retrouver.

      Si tu as des soucis de compréhension du log, reviens vers nous.

      Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson.
      Confucius.

      • Partager sur Facebook
      • Partager sur Twitter
        22 mai 2022 à 19:31:01

        Ok. J'ai essayé, mais quand je lance le projet avec vargrind, le segfault n'apparait pas, et le programme fonctionne, alors que lancé normalement, il y a u segfault

        • Partager sur Facebook
        • Partager sur Twitter
        Le basheur
          22 mai 2022 à 19:41:34

          Malgré qu'il s'exécute il devrait quand même y avoir des messages, tu es sûr que valgrind ne marque rien ?

          ps: en utilisant les optiond cités par white-crow

          -
          Edité par zvheer 22 mai 2022 à 19:42:04

          • Partager sur Facebook
          • Partager sur Twitter
            22 mai 2022 à 19:58:32

            En effet, j'ai manqué d'attention.

            Apparement il y aurait un problème l: un dépassement de mémoire de taille 8

            char* stack=malloc(sizeof(char)*16284);
            	
            	
            	ucontext_t cont;
            	
            	
            	getcontext(&cont);
            	cont.uc_stack.ss_sp = stack;
            	cont.uc_stack.ss_size = sizeof(stack);
            	cont.uc_link = &idle;
            
            	
            	makecontext(&cont,func,0);


            Le message :

            Address 0x4a745a8 is 8 bytes before a block of size 16,284 alloc'd
            ==26100==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-lin

            Je vois pas comment. Ais-je mal utilisé le contexte ?

            -
            Edité par BelhouariSéhane 22 mai 2022 à 20:09:48

            • Partager sur Facebook
            • Partager sur Twitter
            Le basheur
              22 mai 2022 à 20:10:42

              uthread est une structure et j'imagine que la définition se trouve dans une fonction vu le malloc sur stack donc oui peut être faudrait t'il l'allouer aussi

              pense aussi à vérifier que le retour de malloc ne soit pas NULL sur tes allocations

              -
              Edité par zvheer 22 mai 2022 à 20:11:46

              • Partager sur Facebook
              • Partager sur Twitter
                22 mai 2022 à 20:22:39

                uthread=ucontext_t

                Du coup j'ai modifié la fonction. Toute mémoire est mallocée maintenant.

                uthread uthread_create(void (*func)(), void* arg){
                
                
                	if(uth_tab==NULL){
                		uth_tab=malloc(sizeof(uthread) * NB_UTH_MAX);
                	}
                	else{
                		
                		if(nb_uth>NB_UTH_MAX){
                			printf("Nombre maximal de uth dépassé\n");
                			exit(0);
                		}
                	
                	}
                	
                	
                	char* stack=malloc(sizeof(char)*16284);
                	
                	
                	
                	getcontext(&(uth_tab[nb_uth]));
                	uth_tab[nb_uth].uc_stack.ss_sp = stack;
                	uth_tab[nb_uth].uc_stack.ss_size = sizeof(stack);
                	uth_tab[nb_uth].uc_link = &idle;
                
                	//makecontext(&cont,func,1,(int)arg);
                	
                	makecontext(&(uth_tab[nb_uth]),func,0);
                	
                	nb_uth++;
                	
                	
                	//printf("ptr : %ld  nb_uth%d size: %ld\n", uth_tab, nb_uth,sizeof(uthread));	
                	
                	
                	return uth_tab[nb_uth-1];
                }	
                


                Le message de valgrind estle même:

                Invalid write of size 8
                ==27422==    at 0x48D4154: makecontext (makecontext.c:113)
                ==27422==    by 0x10944E: uthread_create (uthread.c:35)
                ==27422==    by 0x109DA3: main (main.c:63)
                ==27422==  Address 0x4ab0de8 is 8 bytes before a block of size 16,284 alloc'd
                ==27422==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
                ==27422==    by 0x10938C: uthread_create (uthread.c:24)
                ==27422==    by 0x109DA3: main (main.c:63)
                



                -
                Edité par BelhouariSéhane 22 mai 2022 à 20:22:59

                • Partager sur Facebook
                • Partager sur Twitter
                Le basheur
                  22 mai 2022 à 20:28:06

                  ce que je disais c'était simplement de faire

                  char* stack=malloc(sizeof(char)*16284);

                  if(stack != NULL)

                  {

                  // suite du code

                  }

                  et là dans le code que tu as envoyé où se trouve la définition du uth_tab que tu test à null

                  en reprenant le premier code que tu as envoyé 

                  tenter

                  char* stack=malloc(sizeof(char)*16284);
                  ucontext_t* cont = malloc(sizeof(ucontext*) );
                  if(stack != NULL && cont != NULL)
                  {
                  getcontext(&cont);
                  cont->uc_stack.ss_sp = stack;
                  cont->uc_stack.ss_size = sizeof(stack);
                  cont->uc_link = &idle;
                  makecontext(&cont,func,0);
                  }
                  forcément la manière d'appeller getcontext et makecontext changera

                  -
                  Edité par zvheer 22 mai 2022 à 20:31:37

                  • Partager sur Facebook
                  • Partager sur Twitter
                    22 mai 2022 à 20:33:22

                    Ok. j'ai rajouté le test sur les pointeurs, et dans la 2e version uth_tab est alloué via malloc. L'erreur ne change cependant pas.

                    Dans le doute voici le code:

                    uthread uthread_create(void (*func)(), void* arg){
                    
                    
                    	if(uth_tab==NULL){
                    		uth_tab=malloc(sizeof(uthread) * NB_UTH_MAX);
                    		if(uth_tab==NULL){
                    			printf("Error: Echec de l'initialisation de uth_tab");
                    			exit(0);
                    		}
                    	}
                    	else{
                    		
                    		if(nb_uth>NB_UTH_MAX){
                    			printf("Nombre maximal de uth dépassé\n");
                    			exit(0);
                    		}
                    	
                    	}
                    	
                    	
                    	char* stack=malloc(sizeof(char)*16284);
                    	if(stack==NULL){
                    		printf("Error: Echec de l'initialisation de stack");
                    		exit(0);
                    	}
                    	
                    	
                    	getcontext(&(uth_tab[nb_uth]));
                    	uth_tab[nb_uth].uc_stack.ss_sp = stack;
                    	uth_tab[nb_uth].uc_stack.ss_size = sizeof(stack);
                    	uth_tab[nb_uth].uc_link = &idle;
                    
                    	//makecontext(&cont,func,1,(int)arg);
                    	
                    	makecontext(&(uth_tab[nb_uth]),func,0);
                    	
                    	nb_uth++;
                    	
                    	
                    	//printf("ptr : %ld  nb_uth%d size: %ld\n", uth_tab, nb_uth,sizeof(uthread));	
                    	
                    	
                    	return uth_tab[nb_uth-1];
                    }



                    • Partager sur Facebook
                    • Partager sur Twitter
                    Le basheur
                      22 mai 2022 à 20:37:37

                      Où est ce que tu sors le uth_tab que tu test et que tu affectes ? c'est une variable globale au code ?
                      • Partager sur Facebook
                      • Partager sur Twitter
                        22 mai 2022 à 20:39:08

                        Oui il y a ça dans le .h

                        int nb_uth=0;
                        
                        uthread* uth_tab=NULL;



                        • Partager sur Facebook
                        • Partager sur Twitter
                        Le basheur
                          22 mai 2022 à 20:50:11

                          tu n'as aucune erreur dès la compilation avec -wall?

                          struct sigaction sa;

                          non alloué 

                          ensuite l'affection de stack a  à uc_stack.ss si c'est une chaine il est mieux de passer par strcpy 

                          uthread uthread_create(void (*func)(), void* arg){
                          if(uth_tab==NULL){
                          uth_tab=malloc(sizeof(uthread) * NB_UTH_MAX);
                          if(uth_tab == NULL)
                          {
                          printf("chec d'allocation");
                          exit(1);
                          }
                          }
                          else{
                          if(nb_uth>NB_UTH_MAX){
                          printf("Nombre maximal de uth dépassé\n");
                          exit(0);
                          }
                          }
                          char* stack=malloc(sizeof(char)*16284);
                          getcontext(&(uth_tab[nb_uth]));
                          uth_tab[nb_uth].uc_stack.ss_sp = stack;
                          uth_tab[nb_uth].uc_stack.ss_size = sizeof(stack);
                          uth_tab[nb_uth].uc_link = &idle;
                          //makecontext(&cont,func,1,(int)arg);
                          makecontext(&(uth_tab[nb_uth]),func,0);
                          nb_uth++;
                          //printf("ptr : %ld  nb_uth%d size: %ld\n", uth_tab, nb_uth,sizeof(uthread));  
                          return uth_tab[nb_uth-1];
                          }  
                          dans ton code a quoi correspondent leslignes données par valgrind
                          Invalid write of size 8
                          ==27422==    at 0x48D4154: makecontext (makecontext.c:113)
                          ==27422==    by 0x10944E: uthread_create (uthread.c:35)
                          ==27422==    by 0x109DA3: main (main.c:63)
                          ==27422==  Address 0x4ab0de8 is 8 bytes before a block of size 16,284 alloc'd
                          ==27422==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
                          ==27422==    by 0x10938C: uthread_create (uthread.c:24)
                          ==27422==    by 0x109DA3: main (main.c:63)

                          -
                          Edité par zvheer 22 mai 2022 à 21:03:09

                          • Partager sur Facebook
                          • Partager sur Twitter
                            22 mai 2022 à 20:54:42

                            Non il n'y en a pas.

                            Un autre problème est apparmement qu'un thread 2 utilise malloc, met le pointeur dans une variable globale, qu'un autre thread 3 utilise et génère un segfault. Comment rendre l'adresse comune ?

                            -
                            Edité par BelhouariSéhane 22 mai 2022 à 20:57:14

                            • Partager sur Facebook
                            • Partager sur Twitter
                            Le basheur
                              22 mai 2022 à 20:58:50

                              Essaie de relire le message au dessus je l'ai modifié.

                              • Partager sur Facebook
                              • Partager sur Twitter
                                22 mai 2022 à 21:08:34

                                J'ai réécris sa:

                                struct sigaction *sa=malloc(sizeof(struct sigaction));

                                Je vois pas la différence dans le code. Je pense pas qu'il faille utiliser strcpy puisque l'espace mémoire est représenté dans la structure par un pointeur sur un char non initialisé au début.

                                Valgrind a écrit at makecontext by uthread_create donc je pense que les lignes correspondent à la fonction que j'ai envoyé

                                -
                                Edité par BelhouariSéhane 22 mai 2022 à 21:10:44

                                • Partager sur Facebook
                                • Partager sur Twitter
                                Le basheur
                                  22 mai 2022 à 21:17:48

                                  Oui mais quand tu copies sur sur openclassroom les numéros de lignes ne sont pas les mêmes d'où le a quelles lignes ca correspond exactement
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    22 mai 2022 à 21:29:36

                                    Dans uthread.c la ligne 35 c'est sur ton message la 22.

                                    La 24 c'est la 16.

                                    -
                                    Edité par BelhouariSéhane 22 mai 2022 à 21:31:20

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                    Le basheur
                                      22 mai 2022 à 21:32:51

                                      BelhouariSéhane a écrit:

                                      Non il n'y en a pas.

                                      Un autre problème est apparmement qu'un thread 2 utilise malloc, met le pointeur dans une variable globale, qu'un autre thread 3 utilise et génère un segfault. Comment rendre l'adresse comune ?

                                      -
                                      Edité par BelhouariSéhane il y a 33 minutes


                                      Il faut protéger l'accès aux variables que tu modifies et qui sont partagées (lock, condition variable, modifications atomiques, …).

                                      valgrind propose aussi un outil pour détecter dans une certaine mesure les race conditions, cf l'option --tool=helgrind

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        22 mai 2022 à 21:36:55

                                        Comment allouer un espace memoire que tout les threads peuvent utiliser ? Pourquoi aurais-je besoin de le protéger, de quoi ?

                                        -
                                        Edité par BelhouariSéhane 22 mai 2022 à 21:41:40

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                        Le basheur
                                          22 mai 2022 à 21:44:51

                                          d'un accès concurrent, une lecture effectuée par un thread alors que l'écriture n'est pas terminée par un autre thread par exemple. À moins qu'une donnée soit immutable (jamais modifiée, donc uniquement utilisée en lecture) il faut toujours en protéger l'accès en lecture et écriture. C'est la base en programmation multithread.

                                          Ensuite, quand tu as des messages genre «invalid write of size …» c'est que tu écris dans une zone mémoire qui ne t'appartient pas ⇒ c'est un gros souci.

                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            22 mai 2022 à 21:56:55

                                            C'est déjà très étrange, puisque je suis persuadé de ce que les allocations soient licites. Vargrind écriyt autre chose d'ailleurs:

                                            Thread 2:
                                            ==33776== Syscall param rt_sigaction(act->sa_mask) points to uninitialised byte(s)
                                            ==33776==    at 0x4870496: __libc_sigaction (sigaction.c:58)
                                            ==33776==    by 0x109894: idle_vcpu (vcpu.c:80)
                                            ==33776==    by 0x4864608: start_thread (pthread_create.c:477)
                                            ==33776==    by 0x499E162: clone (clone.S:95)
                                            ==33776==  Address 0x5673d98 is on thread 2's stack
                                            ==33776==  in frame #0, created by __libc_sigaction (sigaction.c:43)
                                            ==33776==  Uninitialised value was created by a heap allocation
                                            ==33776==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
                                            ==33776==    by 0x10985E: idle_vcpu (vcpu.c:76)
                                            ==33776==    by 0x4864608: start_thread (pthread_create.c:477)
                                            ==33776==    by 0x499E162: clone (clone.S:95)
                                            

                                            Je ne comprends pas comment interpréter ce message

                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                            Le basheur
                                              22 mai 2022 à 22:01:59

                                              BelhouariSéhane a écrit:

                                              C'est déjà très étrange, puisque je suis persuadé de ce que les allocations soient licites. Vargrind écriyt autre chose d'ailleurs:

                                              Thread 2:
                                              ==33776== Syscall param rt_sigaction(act->sa_mask) points to uninitialised byte(s)
                                              ==33776==    at 0x4870496: __libc_sigaction (sigaction.c:58)
                                              ==33776==    by 0x109894: idle_vcpu (vcpu.c:80)
                                              ==33776==    by 0x4864608: start_thread (pthread_create.c:477)
                                              ==33776==    by 0x499E162: clone (clone.S:95)
                                              ==33776==  Address 0x5673d98 is on thread 2's stack
                                              ==33776==  in frame #0, created by __libc_sigaction (sigaction.c:43)
                                              ==33776==  Uninitialised value was created by a heap allocation
                                              ==33776==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
                                              ==33776==    by 0x10985E: idle_vcpu (vcpu.c:76)
                                              ==33776==    by 0x4864608: start_thread (pthread_create.c:477)
                                              ==33776==    by 0x499E162: clone (clone.S:95)
                                              

                                              Je ne comprends pas comment interpréter ce message

                                              Chaque thread a sa propre pile, tu ne peux pas filer l'adresse d'un élément sur la pile d'un thread à un autre, entre autre à un signal handler qui ne va pas s'exécuter dans le contexte de ton thread.

                                              De plus, tu as un malloc dans la fonction idle_vcpu à la ligne 76 du fichier vcpu.c, tu alloues une zone mémoire que tu n'initialises pas mais que tu utilises à la ligne 80 comme si elle l'était …

                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                23 mai 2022 à 13:35:15

                                                D'accord. Un autre problème était le sizeof(stack) où il fallait mettre 126284.

                                                Le programme refonctionne merci. Il me reste un dernier problème. J'utilise makecontext :

                                                makecontext(&(idle_uthread_tab[nb_uth]),idle_uthread_func,1,nb_uth);

                                                avec la declaration

                                                void idle_uthread_func(int indice_uthread);

                                                mais gcc me dit

                                                uthread.c: In function ‘uthread_create’:
                                                uthread.c:62:42: warning: passing argument 2 of ‘makecontext’ from incompatible pointer type [-Wincompatible-pointer-types]
                                                   62 |  makecontext(&(idle_uthread_tab[nb_uth]),idle_uthread_func,1,nb_uth);
                                                      |                                          ^~~~~~~~~~~~~~~~~
                                                      |                                          |
                                                      |                                          void (*)(int)
                                                In file included from uthread.h:17,
                                                                 from Scheduler.h:2,
                                                                 from Scheduler.c:1,
                                                                 from main.c:6:
                                                /usr/include/ucontext.h:51:52: note: expected ‘void (*)(void)’ but argument is of type ‘void (*)(int)’
                                                   51 | extern void makecontext (ucontext_t *__ucp, void (*__func) (void)

                                                Pourtant je pense avoir bien mis les paramètres.



                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                Le basheur
                                                  23 mai 2022 à 14:41:39

                                                  Le message semble clair :

                                                  «/usr/include/ucontext.h:51:52: note: expected ‘void (*)(void)’ but argument is of type ‘void (*)(int)’»

                                                  il faut donner un void (*)(void) comme second d'après la déclaration de makecontext mais tu lui fournis un void (*)(int) ⇒ en effet les types ne sont pas compatibles.

                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    23 mai 2022 à 16:11:35

                                                    Oui mais si tu regarde la definition de makecontext, dans ce cas, comme j'ai donné les arguments (...,1, nb_uth), la fonction en paramètre 2 devrait avoir le type que j'ai donné et pas un type qui ne prends pas de paramètres.
                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                    Le basheur
                                                      23 mai 2022 à 16:30:38

                                                      BelhouariSéhane a écrit:

                                                      Oui il y a ça dans le .h

                                                      int nb_uth=0;
                                                      
                                                      uthread* uth_tab=NULL;




                                                      nb_uth est un int d'après ton message ici donc différent de void dans tous les cas.
                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        23 mai 2022 à 17:08:49

                                                        BelhouariSéhane a écrit:

                                                        Oui mais si tu regarde la definition de makecontext, dans ce cas, comme j'ai donné les arguments (...,1, nb_uth), la fonction en paramètre 2 devrait avoir le type que j'ai donné et pas un type qui ne prends pas de paramètres.


                                                        Alors un rtfm :

                                                        MAKECONTEXT(3)                                      Linux Programmer's Manual                                     MAKECONTEXT(3)
                                                        
                                                        NAME
                                                               makecontext, swapcontext - manipulate user context
                                                        
                                                        SYNOPSIS
                                                               #include <ucontext.h>
                                                        
                                                               void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...);
                                                        

                                                        cela signifie que le second paramètre makecontext est de type void (*)() et toi tu lui fournis un void (*)(int) … ce qui n'est pas compatible …

                                                        Le second paramètre est la fonction … ce qui est clairement indiqué par le message de ton compilo.

                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                          25 mai 2022 à 7:59:39

                                                          BelhouariSéhane a écrit:

                                                          Apparement il y aurait un problème l: un dépassement de mémoire de taille 8

                                                          char* stack = malloc(sizeof(char)*16284);
                                                          	
                                                          ucontext_t cont;
                                                          		
                                                          getcontext(&cont);
                                                          cont.uc_stack.ss_sp   = stack;
                                                          cont.uc_stack.ss_size = sizeof(stack);      // <--------
                                                          

                                                          Je vois un autre truc :

                                                          si ss_sp reçoit l'adresse de la pile allouée, alors ss_size devrait probablement contenir sa taille  (16284), pas la taille d'un pointeur.

                                                          EDIT : oups, j'avais pas vu que ça avait été remarqué avant.


                                                          Quoi qu'il en soit

                                                          • utiliser des constantes nommées (macros ou variables)
                                                          • multiplier par sizeof(char) vaut toujours 1, c'est du bruit qui perturbe la lecture
                                                          const int STACK_SIZE = 16284;                  // 1
                                                          
                                                          char* stack = malloc(STACK_SIZE);              // 2
                                                          	
                                                          ucontext_t cont;
                                                          getcontext(&cont);
                                                          
                                                          cont.uc_stack.ss_sp   = stack;
                                                          cont.uc_stack.ss_size = STACK_SIZE;            // 3
                                                          

                                                          -
                                                          Edité par michelbillaud 25 mai 2022 à 11:33:40

                                                          • Partager sur Facebook
                                                          • Partager sur Twitter

                                                          segmentation fault lors en réception d'un signal

                                                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                          • Editeur
                                                          • Markdown