2010-07-14 5 views
4

J'ai un programme client-serveur dans lequel il y a plusieurs threads dans le serveur et le client. Il y a un nombre variable de clients et de serveurs (comme 3 serveurs (réplicas), 10 clients). Je débogue un fichier source dans ce programme. Je pense qu'il existe une sorte de blocage, éventuellement le suivant:Aide requise pour le débogage de pthreads

Un verrouillage de mutex est déjà détenu par une méthode de serveur et une requête du client appelle une méthode de serveur qui veut acquérir à nouveau le mutex.

Le programme est lancé par un script de test qui génère les serveurs et les clients et envoie le client envoyer des requêtes spécifiques aux serveurs. Je l'ai utilisé le code suivant dans la zone suspecte du code pour voir s'il y a une impasse, mais il ne semble pas fonctionner, à savoir le code entre ni bloc:

if (pthread_mutex_lock(&a_mutex) == EDEADLK) { 
    cout<<"couldnt acquire lock."<<endl; 
} 
else cout<<"acquired lock"<<endl; 

J'ai essayé de débogage (en attachant une course processus serveur) avec gdb. J'ai ajouté "display" et "watch" (dans différentes exécutions de gdb) pour a_mutex. Je reçois un résultat de la forme suivante:

1: a_mutex = {__data = {__lock = 2, __count = 0, __owner = 4193, __kind = 0, __nusers = 2, 
{__spins = 0, __list = {__next = 0x0}}}, 
    __size = "\002\000\000\000\000\000\000\000a\020\000\000\000\000\000\000\002\000\000 \000\000\000\000", __align = 2} 

Je ne sais pas le sens de toutes les choses dans la sortie ci-dessus, mais je pouvais voir qu'un fil (4193) tient le mutex. J'ai vu le backtrace de ce fil (snipped):

#0 0xb8082430 in __kernel_vsyscall() 
#1 0xb7e347a6 in nanosleep() from /lib/tls/i686/cmov/libc.so.6 
#2 0xb7e345be in sleep() from /lib/tls/i686/cmov/libc.so.6 
#3 0x0804cb59 in class1::method1 (this=0xbfa9fe6c, clt=1, id= 
    {static npos = 4294967295, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0xb7c9c11c "l/%\b"}}) 
at file1.cc:33 

Je ne sais pas comment et où le bogue est.

Je vous serais très reconnaissant de toute aide aux questions suivantes:

  1. Qu'est-ce qu'une bonne méthode de mise au point des conditions/programmes?
  2. Comment puis-je détecter la condition d'interblocage (c'est-à-dire où un verrou est maintenu et non libéré)?
  3. Dans un tel programme multiprocessus, existe-t-il une meilleure façon d'utiliser gdb? (ie inspecter les états dans tous les processus? configurer gdb pour regarder/afficher une variable avant le début du processus?)
  4. Parce que, quand j'attache gdb au serveur après qu'il a démarré (par le script du testeur), le serveur pourrait Avons déjà devancé le code que je veux inspecter. J'ai essayé d'ajouter un sommeil (20) avant la zone suspecte pour m'aider avec gdb, mais je pense que ce n'est pas un bon moyen. Je pense aussi que l'ouverture de plusieurs terminaux, le démarrage manuel des serveurs et des clients et la vérification des états de chacun d'entre eux n'est pas non plus une très bonne idée (veuillez me corriger si je me trompe).

PS: J'ai déjà lu ceci question.

Merci beaucoup.

+1

J'ai personnellement utilisé l'Intel Thread Checker. Je l'ai trouvé très utile pour attraper les blocages – onof

+2

J'ai aussi utilisé Intel Thread Checker.L'outil hellgrind (qui fait partie de Valgrind) est excellent aussi. –

+0

Cela ne ressemble pas à une impasse, mais simplement une contention. Avez-vous un deuxième mutex qui est acquis quelque part là-bas? Si c'est le cas, assurez-vous qu'ils sont verrouillés * dans le même ordre *. –

Répondre

4

Utilisez GDB et attachez-le au programme bloqué. Ensuite, utilisez "thread apply all bt" (je pense mais je n'ai pas de système à portée de main).

Cela vous donnera un backtrace de tous les threads et vous devriez être capable de voir quel thread fait quoi.

Si ce problème est facilement reproductible aussi, vous pouvez utiliser une ligne pour donner quelques informations sur lesquelles des verrouillages sont effectués.