Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
4890 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  [MinGW/Boost.Thread] Segfault multi-threading

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[MinGW/Boost.Thread] Segfault multi-threading

n°897309
xterminhat​e
Si vis pacem, para bellum.
Posté le 12-11-2004 à 23:43:30  profilanswer
 

J'ai un leger soucis avec mon code. Lorsque je le fais tourner à fond (100%cpu), une exception (n°5 d'apres le rapport) se déclenche apres environ 10 minutes. Ce qui doit correspondre au segfault.
 
Mon code est compilé/linké en release avec le libs Boost en version release. Il n'y aucune IHM. J'ai l'impression que l'anomalie tourne autour de cet objet :

Code :
  1. template< typename X >
  2. struct bounded_fifo : private boost::noncopyable
  3. {
  4.     fifo( const int& n ) :
  5. begin( 0 ),
  6. end( 0 ),
  7. buffered( 0 ),
  8. circular_buf( n )
  9. {
  10. }
  11.     void write( const X& m )
  12. {
  13.         lock lk( monitor );
  14.         while ( buffered == circular_buf.size() )
  15.             buffer_not_full.wait( lk );
  16.         circular_buf[ end ] = m;
  17.         end = ( end + 1 ) % circular_buf.size();
  18.         ++buffered;
  19.         buffer_not_empty.notify_one();
  20.     }
  21.     X read()
  22. {
  23.         lock lk( monitor );
  24.         while ( buffered == 0 )
  25.             buffer_not_empty.wait( lk );
  26.         X i = circular_buf[ begin ];
  27.         begin = ( begin + 1 ) % circular_buf.size();
  28.         --buffered;
  29.         buffer_not_full.notify_one();
  30.         return i;
  31.     }
  32. private:
  33.     unsigned int begin, end, buffered;
  34.     vector< X > circular_buf;
  35.     condition buffer_not_full, buffer_not_empty;
  36. mutex monitor;
  37. };


Message édité par xterminhate le 14-11-2004 à 20:59:20

---------------
Cordialement, Xterm-in'Hate...
mood
Publicité
Posté le 12-11-2004 à 23:43:30  profilanswer
 

n°897320
Lam's
Profil: bas.
Posté le 13-11-2004 à 00:01:09  profilanswer
 

Je ne vois pas (pis j'ai mangé trop de gateau, ça ralentit le cerveau). Ceci dit, tu fais un notify alors même que tu as encore le lock, donc ça peut lui déplaire et te causer des trucs étranges.  
 
Peux-tu essayer comme ça:

Code :
  1. void write( const X& m )
  2. {
  3. {
  4.        lock lk( monitor );
  5.         while ( buffered == circular_buf.size() )
  6.             buffer_not_full.wait( lk );
  7.         circular_buf[ end ] = m;
  8.         end = ( end + 1 ) % circular_buf.size();
  9.         ++buffered;
  10. }
  11.         buffer_not_empty.notify_one();
  12.     }
  13.     X read()
  14. {
  15. {
  16.         lock lk( monitor );
  17.         while ( buffered == 0 )
  18.             buffer_not_empty.wait( lk );
  19.         X i = circular_buf[ begin ];
  20.         begin = ( begin + 1 ) % circular_buf.size();
  21.         --buffered;
  22. }
  23.         buffer_not_full.notify_one();
  24.         return i;
  25.     }


 
A défaut, quel est le type de X, et où le code plante-t-il ?

n°897326
xterminhat​e
Si vis pacem, para bellum.
Posté le 13-11-2004 à 00:12:31  profilanswer
 

Je realise la modification et je me reviens vers toi.
 
X est un vector<unsigned char>.
 
Je n'ai précisement aucune technique pour le debug de ce type de code à plusieurs threads. Je ne serais donc pas dire ou le code plante...


---------------
Cordialement, Xterm-in'Hate...
n°897328
Lam's
Profil: bas.
Posté le 13-11-2004 à 00:21:07  profilanswer
 

Tu es sous quel environnement ? (OS, compilo, etc.). Tu as déjà du le dire, mais j'ai une de ces flemmes de chercher... :)

n°897353
xterminhat​e
Si vis pacem, para bellum.
Posté le 13-11-2004 à 08:21:26  profilanswer
 

Je travaille sous windows Xp sp 2, et je compile avec MinGW 2.0 (gcc3.2).


---------------
Cordialement, Xterm-in'Hate...
n°897360
Lam's
Profil: bas.
Posté le 13-11-2004 à 09:28:30  profilanswer
 

Si tu as gdb, tu dois être capable d'avoir les frames de ton truc (il le fait sous cygwin, donc sous mingw, ça doit le faire aussi). Pense juste à compiler avec -g.  

n°897913
xterminhat​e
Si vis pacem, para bellum.
Posté le 14-11-2004 à 01:01:39  profilanswer
 

En effet, MinGW est fourni avec un outil de debug qui remplace DrWatson. Je constate donc que mon code plante systématique à l'appel des composants logiciels de Boost::Thread (mutex et condition). Comme Boost est fiable, j'en déduis que mon compilo a réellement un pb (configuration multi threading peut etre pas activée). JE vais recompiler avec Visual ou autre.
 
A tout hasard, sais tu comment compiler ce type de code sous GCC/MinGW (ligne de commande) ?


---------------
Cordialement, Xterm-in'Hate...
n°897922
Taz
bisounours-codeur
Posté le 14-11-2004 à 01:08:50  profilanswer
 

moi j'ai jamais compris ces trucs
 
end = ( end + 1 ) % circular_buf.size();
 
si la taille n'est pas un multiple de 2, mieux vaut faire un pauvre if :D, c'est plus rapide.
 
 
file du code compilable (classe + programme de test) tant qu'à faire si tu as des doutes

n°897927
Taz
bisounours-codeur
Posté le 14-11-2004 à 01:19:24  profilanswer
 

pour moi il n'y a pas besoin de scoper le lock plus que ça, la définition me semble correcte. je dirais même le contraire. une condition est associée à un lock, il faut demander le verrou dessus tant qu'on la manipule

n°897960
Lam's
Profil: bas.
Posté le 14-11-2004 à 08:54:30  profilanswer
 

C'est bien ce qui m'embête: le code est correct, et je dirais même canonique: c'est typiquement comme ça qu'il faut faire.  
 
Ceci dit, je ne fais pas 100% confiance au couple Boost/Mingw.
 
Donc le truc était de vérifier si ça marchait mieux en laissant le notify prévenir les classes sans que le lock ne soit actionné (pour qu'elles puissent sortir sans encombre du wait() ).
 
Xterm, sous Mingw, as-tu essayé "-pthread -mthreads" comme option de compil ?

mood
Publicité
Posté le 14-11-2004 à 08:54:30  profilanswer
 

n°897987
Taz
bisounours-codeur
Posté le 14-11-2004 à 10:36:20  profilanswer
 

Lam's a écrit :

C'est bien ce qui m'embête: le code est correct, et je dirais même canonique: c'est typiquement comme ça qu'il faut faire.  

pour moi aussi. c'est pour ça que j'aimerais bien avoir du code compilable + main de test qui montre la défaillance

n°898013
xterminhat​e
Si vis pacem, para bellum.
Posté le 14-11-2004 à 11:40:56  profilanswer
 

Sans modifier le code source, j'ai mis à jour le compilateur. J'ai aussi recompilé le code avec l'option "-mthreads" (btw, l'option "-pthread" n'est pas reconnue). Je n'ai pas recompilé les librairies Boost.Thread (les dll multithread en paritculier). J'ai relinké mon programme.
 
A prendre avec des pincettes (les bugs de ce type sont traitres), le code tourne depuis une heure sans plantage avec 2 ou 3 threads en plus du main.


Message édité par xterminhate le 14-11-2004 à 11:41:12

---------------
Cordialement, Xterm-in'Hate...
n°898014
Taz
bisounours-codeur
Posté le 14-11-2004 à 11:47:46  profilanswer
 

ça peut ne pas planter tout en violant l'exclusion mutuelle

n°898299
el muchach​o
Comfortably Numb
Posté le 14-11-2004 à 17:27:21  profilanswer
 

Fous des traces, je pense que ça peut aider.

n°898421
xterminhat​e
Si vis pacem, para bellum.
Posté le 14-11-2004 à 20:58:35  profilanswer
 

Apres une douzaine d'heure de test intensif, je n'ai pas eu un seul crash. Je respire enfin ! Tout semble fonctionner correctement.  :)  
 
Je conseille donc à ceux qui utilisent MinGW de mettre leur compilateur à jour en téléchargeant les packages individuels. La version de MinGW en une seule archive et celle fournie avec MinGW Studio ne sont pas fiable pour la programmation multithreads.
 
Merci de votre aide.  :jap:


---------------
Cordialement, Xterm-in'Hate...
n°898437
el muchach​o
Comfortably Numb
Posté le 14-11-2004 à 21:19:17  profilanswer
 

Je viens de voir que tu compilais avec gcc 3.2 ? Tu es tjrs sous gcc 3.2 ? Il me semble avoir lu qq part que cette version était assez moisie (de façon générale les versions entre la 2.96 et la 3.3.1, il me semble que c'est pas génial, qq peut confirmer ? Taz ?).


Message édité par el muchacho le 14-11-2004 à 21:19:38
n°898448
xterminhat​e
Si vis pacem, para bellum.
Posté le 14-11-2004 à 21:39:44  profilanswer
 

Clair. Je me demande comment j'ai pu coder autant (dont quelques services winNT multithreads) avec cette version antérieure qui semble peu recommandable !


---------------
Cordialement, Xterm-in'Hate...
n°898451
Taz
bisounours-codeur
Posté le 14-11-2004 à 21:41:33  profilanswer
 

elle l'est pas mais elle a pas vécu très longtemps. t'as qu'à filer ton code, que je teste avec g++-3.3, g++-3.4 et g++-3.5

n°898453
Lam's
Profil: bas.
Posté le 14-11-2004 à 21:43:30  profilanswer
 

el muchacho a écrit :

Je viens de voir que tu compilais avec gcc 3.2 ? Tu es tjrs sous gcc 3.2 ? Il me semble avoir lu qq part que cette version était assez moisie (de façon générale les versions entre la 2.96 et la 3.3.1, il me semble que c'est pas génial, qq peut confirmer ? Taz ?).


3.0 et 3.1 pas digne de faire du code "commercial", c'est mon avis. C'est surtout les optimisateurs qui étaient vraiment moisis. Et du code fortement STL sans optimisation du compilo, c'est de la bouse. Bref le compilo était presque inutile.
 
Là, je suis sous la 3.3.3 sous cygwin, et ça a l'air correct, à part les messages d'erreur qui sont à se pisser dessus, mais bon on a ce qu'on paye.
 

n°898456
Taz
bisounours-codeur
Posté le 14-11-2004 à 21:48:41  profilanswer
 

il faut utiliser stlfilt et ça roule. Les messages sont long et verbeux, certes, mais nécessaires à une analyse fine. Même si tu payais, le message ne pourrait pas être meilleur : y a des échecs d'instantiation, il faut affiche le tout déroulé. Je sais pas comment fait VC, mais je vois mal comment on peut simplifier le message sans perdre d'information.

n°898462
Taz
bisounours-codeur
Posté le 14-11-2004 à 21:53:17  profilanswer
 

Code :
  1. #include <map>
  2. int main()
  3. {
  4.   std::map<int, int&> a;
  5. }


 

Citation :

g++-3.4 map.cpp  
/usr/include/c++/3.4/bits/stl_map.h: In instantiation of `std::map<int, int&, std::less<int>, std::allocator<std::pair<const int, int&> > >':
map.cpp:5:   instantiated from here
/usr/include/c++/3.4/bits/stl_map.h:332: error: forming reference to reference type `int&'
/usr/include/c++/3.4/bits/stl_pair.h: In instantiation of `std::pair<const int, int&>':
/usr/include/c++/3.4/bits/stl_tree.h:135:   instantiated from `std::_Rb_tree_node<std::pair<const int, int&> >'
/usr/include/c++/3.4/bits/stl_tree.h:1064:   instantiated from `void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_erase(std::_Rb_tree_node<_Val>*) [with _Key = int, _Val = std::pair<const int, int&>, _KeyOfValue = std::_Select1st<std::pair<const int, int&> >, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, int&> >]'
/usr/include/c++/3.4/bits/stl_tree.h:565:   instantiated from `std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::~_Rb_tree() [with _Key = int, _Val = std::pair<const int, int&>, _KeyOfValue = std::_Select1st<std::pair<const int, int&> >, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, int&> >]'
map.cpp:5:   instantiated from here
/usr/include/c++/3.4/bits/stl_pair.h:85: error: forming reference to reference type `int&'


 

Citation :

Comeau C/C++ 4.3.3 (Aug  6 2003 15:13:37) for ONLINE_EVALUATION_BETA1
Copyright 1988-2003 Comeau Computing.  All rights reserved.
MODE:strict errors C++
 
"stl_map.h", line 165: error: reference to reference is not allowed
    _Tp& operator[](const key_type& __k) {
       ^
          detected during instantiation of class "std::map<_Key, _Tp,
                    _Compare, _Alloc> [with _Key=int, _Tp=int &,
                    _Compare=std::less<int>, _Alloc=std::allocator<int &>]" at
                    line 5 of "ComeauTest.c"
 
"stl_pair.h", line 44: error: reference to reference is not allowed
    pair(const _T1& __a, const _T2& __b) : first(__a), second(__b) {}
                                  ^
          detected during:
            instantiation of class
                      "std::pair<_T1, _T2> [with _T1=const int, _T2=int &]" at
                      line 98 of "stl_tree.h"
            instantiation of class "std::_Rb_tree_node<_Value> [with
                      _Value=std::map<int, int &, std::less<int>,
                      std::allocator<int &>>::value_type]" at line 195 of
                      "stl_alloc.h"
            instantiation of "_Tp *std::simple_alloc<_Tp,
                      _Alloc>::allocate(size_t) [with
                      _Tp=std::_Rb_tree_node<std::map<int, int &,
                      std::less<int>, std::allocator<int &>>::value_type>,
                      _Alloc=std::alloc]" at line 475 of "stl_tree.h"
            instantiation of "std::_Rb_tree_node<_Value>
                      *std::_Rb_tree_alloc_base<_Tp, _Alloc,
                      true>::_M_get_node() [with _Tp=std::map<int, int &,
                      std::less<int>, std::allocator<int &>>::value_type,
                      _Alloc=std::allocator<int &>]" at line 497 of
                      "stl_tree.h"
            instantiation of "std::_Rb_tree_base<_Tp,
                      _Alloc>::_Rb_tree_base(const std::_Rb_tree_base<_Tp,
                      _Alloc>::allocator_type & ) [with _Tp=std::map<int, int
                      &, std::less<int>, std::allocator<int &>>::value_type,
                      _Alloc=std::allocator<int &>]" at line 659 of
                      "stl_tree.h"
            instantiation of "std::_Rb_tree<_Key, _Value, _KeyOfValue,
                      _Compare, _Alloc>::_Rb_tree(const _Compare &, const
                      std::_Rb_tree<_Key, _Value, _KeyOfValue, _Compare,
                      _Alloc>::allocator_type & ) [with _Key=std::map<int, int
                      &, std::less<int>, std::allocator<int &>>::key_type,
                      _Value=std::map<int, int &, std::less<int>,
                      std::allocator<int &>>::value_type,
                      _KeyOfValue=std::_Select1st<std::map<int, int &,
                      std::less<int>, std::allocator<int &>>::value_type>,
                      _Compare=std::map<int, int &, std::less<int>,
                      std::allocator<int &>>::key_compare,
                      _Alloc=std::allocator<int &>]" at line 105 of
                      "stl_map.h"
            instantiation of "std::map<_Key, _Tp, _Compare, _Alloc>::map()
                      [with _Key=int, _Tp=int &, _Compare=std::less<int>,
                      _Alloc=std::allocator<int &>]" at line 5 of "ComeauTest.c"
 
2 errors detected in the compilation of "ComeauTest.c".

est mieux formaté, mais ne change pas en substance


Message édité par Taz le 14-11-2004 à 21:53:33
n°898471
Lam's
Profil: bas.
Posté le 14-11-2004 à 22:11:58  profilanswer
 

Taz a écrit :

il faut utiliser stlfilt et ça roule. Les messages sont long et verbeux, certes, mais nécessaires à une analyse fine. Même si tu payais, le message ne pourrait pas être meilleur : y a des échecs d'instantiation, il faut affiche le tout déroulé. Je sais pas comment fait VC, mais je vois mal comment on peut simplifier le message sans perdre d'information.


Y des scripts sympas pour VC++ qui "remplacent" le compilo et qui font l'équivalent d'un stlfilt.  
 
Mais je ne pensais pas à ça, je pensais à la qualité des messages d'erreur sous Forte (facile à parser, clairs, précis à la colonne près), et les espèces de truc que sort g++, plus proche du "syntax error somewhere".
 
Genre, j'ai eu le malheur d'installer wxWidgets qui m'a françisé le truc à moitié:

Citation :

bidule.cpp: Dans function << int main() >>:
bidule.cpp:5: error: erreur d'analyse syntaxique before string constant

n°898472
Taz
bisounours-codeur
Posté le 14-11-2004 à 22:13:46  profilanswer
 

ouais alors forte, moins je bosse avec, mieux je me porte. c'est antédéluvien.

n°898481
Lam's
Profil: bas.
Posté le 14-11-2004 à 22:23:36  profilanswer
 

Taz a écrit :

ouais alors forte, moins je bosse avec, mieux je me porte. c'est antédéluvien.


Le front-end est pas mauvais, et l'optimiseur est carrément solide. Par contre, la gestion des templates est catastrophique, c'est clair.  
 
Le template-repository, il ressemble à un truc codé par un stagiaire. :lol:

n°898488
Taz
bisounours-codeur
Posté le 14-11-2004 à 22:27:23  profilanswer
 

même au niveau du C, c'est la marne. Je sais pas ce que c'est la politique de licence de Forte, mais sur les Solaris surlesquels je bosse, y a tous les gcc récents contre la version de base fournie ...

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  [MinGW/Boost.Thread] Segfault multi-threading

 

Sujets relatifs
[C] thread sur SUN et sur linux[php/mysql]Creation multi table
[C++] boost & semaphore [ solution boost::condition ]Winsock et Threads (Boost) : Problème
[C++] conteneur stl & éléments-objets "thread-safe"OpenGL : opaque derriere multi blending...ca part en sucette
multi-compilation avec gcc sous VisualC++ 6Problème Thread en java
arreter un select bloquant depuis un autre thread[C++/SDL] pb de threading
Plus de sujets relatifs à : [MinGW/Boost.Thread] Segfault multi-threading


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)