2010-10-19 8 views
2

Me référant à ma précédente question sur GDB not pinpointing the SIGSEGV point,Stack possible la corruption

Mon code de fil est la suivante:

void *runner(void *unused) 
{ 
do 
{ 
sem_wait(&x); 
    ... 

    if(/*condition 1 check*/) 
    { 
    sem_post(&x); 
    sleep(5); 
    sem_wait(&x); 
    if(/*repeat condition 1 check; after atleast 5 seconds*/) 
    { 
    printf("LEAVING...\n"); 
    sem_post(&x); 
    // putting exit(0); here resolves the dilemma 
    return(NULL); 
    } 
    } 
sem_post(&x); 
}while(1); 

} 

Code principal:

sem_t x;  

int main(void) 
{ 
    sem_init(&x,0,1); 
     ... 
    pthread_t thrId; 
    pthread_create(&thrId,NULL,runner,NULL); 
     ... 
    pthread_join(thrId,NULL); 
    return(0); 
} 

Edit: Avoir une sortie (0) dans le code du thread du coureur, fait disparaître le défaut.


Quelles pourraient être les raisons de la corruption de la pile?

GDB sortie: (0xb7fe2b70 est id de fil de canal de coulée)

LEAVING... 
Program received signal SIGSEGV, Segmentation fault. 
[Switching to Thread 0xb7fe2b70 (LWP 2604)] 
0x00000011 in ??() 

Valgrind sortie:

==3076== Thread 2: 
==3076== Jump to the invalid address stated on the next line 
==3076== at 0x11: ??? 
==3076== by 0xA26CCD: clone (clone.S:133) 
==3076== Address 0x11 is not stack'd, malloc'd or (recently) free'd 
==3076== 
==3076== 
==3076== Process terminating with default action of signal 11 (SIGSEGV) 
==3076== Bad permissions for mapped region at address 0x11 
==3076== at 0x11: ??? 
==3076== by 0xA26CCD: clone (clone.S:133) 
==3076== Address 0x11 is not stack'd, malloc'd or (recently) free'd 
+1

Vous devez poster plus de code. Toutes les parties juteuses sont manquantes. – EboMike

+0

Est-ce la seule et unique erreur de rapports de valgrind? Si cela rapporte d'autres, commencez par le premier. – nos

+0

Oui, c'est le seul. –

Répondre

6

Ecrire un nouveau fichier source avec une fonction main qui fait la même chose que le main vous avez publié ici que plutôt que d'utiliser pthread_create il suffit d'appeler la fonction. Voyez si vous pouvez recréer le problème indépendamment de l'utilisation des threads. De la façon dont les choses semblent vos sémaphores devraient encore fonctionner très bien dans un environnement unique.

Si cela échoue toujours, vous aurez plus de facilité à le déboguer. Puisque vous avez indiqué qu'appeler exit au lieu de renvoyer n'a pas généré l'erreur, cela suggère que vous avez corrompu l'adresse de retour qui est sur la pile lorsque runner est démarré. En appelant exit vous ne comptez pas sur cette zone de mémoire pour accéder à une fonction existante (si vous aviez retourné pthread_exit aurait été appelé par le code de la bibliothèque pthread qui avait appelé runner).Je pense que la sortie de valgrind n'est pas précise à 100% - pas à cause de la faute de valgrind, mais parce que l'endroit où vous déclenchez l'erreur et le type d'erreur que vous déclenchez rendent très difficile de savoir qui a appelé .

Certains gcc drapeaux vous pourriez être intéressé par:

-fstack-protector-all -Wstack-protector 

L'option d'alerte ne fonctionne pas sans l'option -f ici.

Vous pouvez également essayer:

-fno-omit-frame-pointer 
1

utilisation valgrind ou un outil de vérification de mémoire équivalente à comprendre. Cessez de deviner. Arrêtez également d'envoyer du code incomplet, surtout si vous ne savez pas s'il a un problème ou non. Le bug pourrait être en dehors de cette fonction. Par exemple, le sémaphore n'est peut-être pas initialisé. De la sortie de valgrind, je peux suggérer que votre ligne pthread_create() doit contenir un pointeur de fonction invalide. Donc pthread saute à cette fausse adresse, et se bloque. De toute évidence, il n'y a pas pile ...

+0

Le sémaphore a été initialisé, sortie Valgrind postée. –

+0

Je ne te ferais confiance que si valgrind ne s'en plaint pas. Sérieusement, arrêtez de deviner. – BatchyX

+0

J'ai mis le code principal. Je ne sais pas ce que je peux poster de plus, sans déverser tout le fichier source ici. –

2

Toutes les pièces importantes sont manquantes dans votre code, mais les raisons les plus courantes pour la corruption de la pile:

  • un pointeur vers Mémorisation un élément sur la pile et l'utiliser après l'objet est déjà hors de portée.
  • Buffer débordé, comme avoir un char buffer[20] sur la pile et écrire en dehors des limites (sprintf est un moyen fantastique d'accomplir cela).
  • Bad cast, c'est-à-dire ayant une classe de base A sur la pile, en la coulant dans une classe dérivée et en l'utilisant.
+0

sa pile ne semble pas être corrompue. – BatchyX