2010-12-07 56 views
0

J'ai un projet utilisant pthreads; il y a le fil principal et un sous-fil et un tuyau entre eux. Tout fonctionne bien, sauf parfois cela ne fonctionne pas. Le sous-thread exécute un interpréteur de commandes et une entrée de GUI ncurses (en partie) sur le canal.pthread_exit (NULL) segfaults

je crée le fil normalement (thread est un pthread_t variable de fichier portée, interp_start est la fonction)

if (pthread_create(&thread, NULL, interp_start, NULL)) { perror("couldn't create thread"); return; } 

Ensuite, si le thread interprète reçoit une commande « exit » de l'utilisateur, il appelle interp_exit

fclose(output); 
pthread_exit(NULL); 

le thread principal a un select() qui examine, entre autres, FD de sortie et appelle une fonction qui a lu() s de la FD:

int num=read(interp_output[0], &ch, 1); 
if (num==0) shell_done(); 
if (num==-1) perror("read"); 

Le comportement prévu, qui fonctionne souvent, est de fermer le FICHIER * dans le thread, ce qui rend le rapport select() prêt, ce qui fait que read() arrive, qui renvoie 0, qui appelle shell_done(). Cela ne, après un nettoyage simple et sans rapport avec:

//fprintf(stderr, "joining thread\n"); 
pthread_join(thread, NULL); 
//fprintf(stderr, "joined\n"); 
exit(EXIT_SUCCESS); 

Tout cela parfois segfaults. Habituellement c'est bien. Si je ne commente pas ces deux printfs, si cela échoue, je ne reçois ni l'un ni l'autre (c'est-à-dire se sépare en pthread_exit) ou seulement le premier (c'est-à-dire segfaults dans pthread_join).

Je ne suis pas en train de jouer avec 'thread' à tout autre point, et je ne traite que des pointeurs NULL. Quel est le problème? Je regarderais ailleurs, sauf que j'ai régulièrement des problèmes à l'une de ces deux lignes - une fois même à restore_sem_to_pool. Je pense que ça doit être la façon dont je tue le fil, mais je fais à peu près la chose la plus simple possible.

Merci à l'avance ...

+0

Avez-vous un mimatch entre # d'arguments et la chaîne de format dans un de la famille d'appels printf (s) (f)? –

+0

D'où 'gdb' dit-il que la segfault se produit? – caf

+0

@jim - Je ne pense pas.Où aimeriez-vous que je regarde - dans le fil, dans le programme principal, ou dans toutes les variables partagées? – Robert

Répondre

0

Je suppose que c'est une combinaison de tous ces éléments, mais le problème est parti. Cela ne s'est produit que lorsque j'ai tapé 'stopper' trop tôt après le démarrage du programme, mais je n'ai pas le temps de le déboguer correctement et l'affectation est déjà due de toute façon. @John - Je mettais en place valgrind juste pour ce but. [EDIT] Je l'ai couru plus tôt et cela ne m'a pas aidé avec ce problème, mais j'ai vraiment trouvé de la mémoire Je ne libérais pas [/ EDIT] Tout le monde - Je pense que tu as raison, c'est probablement sorte de corruption de la mémoire. @caf - J'ai oublié de vérifier les autres threads ... mais je voyais le problème dans les deux threads. GDB me pointait sur celui qui était en train de segmenter. [EDIT] J'ai vérifié les autres fils et qu'il se trouve en attente sur le pt_join (si le segfault était avec le pt_exit) ou quelque part juste avant la pt_exit (si le segfault était dans le pt_join) [/ EDIT]

Votes à tous, mais je ne pense pas qu'il soit juste d'accepter une réponse ici.

6

Essayez d'utiliser valgrind (en particulier la partie "memcheck"). Il peut rapidement vous aider à localiser les accès mémoire invalides lors de l'exécution, parfois même en incluant les exécutions de votre programme qui ne tombent pas en panne.