2 points par GN⁺ 2024-03-04 | 1 commentaires | Partager sur WhatsApp

Possible bug de std::shared_mutex sous Windows

  • Une équipe logicielle a découvert un comportement inattendu lié à std::shared_mutex sous Windows.
  • Ce problème ne se produit qu’avec MSVC, et n’apparaît ni avec MinGW ni sur d’autres plateformes.
  • Lorsque le thread principal acquiert un verrou exclusif puis que plusieurs threads enfants tentent d’acquérir un verrou partagé, un « deadlock » survient environ 1 fois sur 1000.
  • Quand ce deadlock se produit, exactement 1 thread enfant parvient à acquérir le verrou partagé, tandis que les autres restent bloqués indéfiniment dans lock_shared().
  • Le problème a été observé avec std::shared_mutex, std::shared_lock/std::unique_lock ainsi qu’en appelant directement les fonctions SRW.

Exemple de code et reproduction du bug

  • Un exemple de code simple permettant de reproduire le problème est fourni.
  • Le code répète le processus dans lequel le thread principal acquiert un verrou exclusif, plusieurs threads enfants acquièrent ensuite un verrou partagé avant de le relâcher.
  • Ce code ne montre le bug lié à std::shared_mutex que dans l’implémentation Windows de MSVC.

Avis des experts

  • Un développeur de la STL a indiqué que le problème ressemblait à un bug de l’API Windows.
  • Une discussion a eu lieu sur les étapes appropriées pour signaler le bug, et le développeur STL l’a remonté en interne.
  • D’autres utilisateurs ont étudié le problème en détail et ont contribué à isoler un bug spécifique dans l’implémentation de SRWLock.

Avis de GN⁺

  • Cet article fournit des informations particulièrement importantes pour les développeurs C++. Un bug potentiel dans std::shared_mutex peut en effet affecter les mécanismes de synchronisation des applications multithread.
  • Si le bug est confirmé, cela pourrait nuire à la confiance dans l’implémentation de la bibliothèque standard C++. Les développeurs devront être conscients de ce problème et pourraient avoir à envisager d’autres mécanismes de synchronisation.
  • Le problème peut être particulièrement critique dans les systèmes haute performance ou temps réel, où un deadlock peut avoir des conséquences fatales.
  • Avant d’adopter cette technologie, les développeurs devraient effectuer des tests approfondis sur la plateforme et le compilateur concernés afin de vérifier l’absence de ce type de bug.
  • Pour résoudre ce type de problème, les développeurs peuvent envisager des bibliothèques de synchronisation alternatives comme Boost. Boost étant largement testé et utilisé sur de nombreuses plateformes, il peut fournir une alternative fiable face à ce genre de problème.

1 commentaires

 
GN⁺ 2024-03-04
Avis Hacker News
  • Un utilisateur se demande pourquoi un problème aussi fondamental est resté inaperçu si longtemps et mentionne la réponse convaincante fournie par un autre utilisateur. Il souligne qu’un thread essayant de prendre le verrou en mode partagé peut, par erreur, obtenir le verrou en mode exclusif. Cela se produit à cause du chevauchement d’opérations atomiques de test et de mise à jour de bits lorsque le thread qui acquiert le mode partagé et le thread qui libère le mode exclusif s’exécutent en même temps.

    • Un utilisateur explique qu’il dispose d’un code de reproduction dans lequel tous les autres threads attendent de prendre un verrou partagé pendant qu’un utilisateur acquiert un verrou partagé, ce qui peut provoquer un interblocage si l’un des threads de travail obtient par erreur un verrou exclusif. Dans les cas d’usage habituels, les threads ne s’attendent pas les uns les autres, donc aucun interblocage ne se produit.
  • Un autre utilisateur dit ne pas être surpris par les bugs subtils qui surviennent dans les verrous Reader/Writer et partage son expérience d’implémentation interne basée sur Win32 avant C++11 et std::shared_mutex. En raison de mauvaises expériences avec les verrous partagés, il affirme essayer de les éviter sauf nécessité absolue.

    • Un utilisateur partage une expérience négative avec les verrous partagés et indique que les performances de std::shared_mutex sont nettement inférieures à celles de std::mutex, au point qu’un double buffering des données est plus rapide.
  • Un utilisateur fait remarquer que le titre est trompeur et explique que le véritable bug se situe dans le verrou slim reader/writer (SRW) de l’API Windows, et qu’il a été découvert parce que std::shared_mutex est implémenté à l’aide des verrous SRW. Un employé de Microsoft confirme que le bug a été remonté en interne à l’équipe de l’API Windows.

    • Un utilisateur souligne le caractère trompeur du titre et rappelle que le vrai problème se trouve dans le verrou SRW de l’API Windows, en mentionnant qu’un employé de Microsoft a confirmé que le bug avait été remonté.
  • Un utilisateur se demande si le même problème se produit aussi dans l’implémentation de WINE et dit vouloir le tester sur sa propre installation XP personnalisée. Il explique avoir ajouté plusieurs extensions, dont l’API SRW, sur cette installation, et avoir patché le noyau pour corriger une condition de concurrence provoquant un interblocage dans l’API keyed event, basée sur l’implémentation SRW.

    • Un utilisateur se demande si le même problème se produit aussi dans l’implémentation de WINE et dit vouloir le tester sur son installation XP personnalisée. Il indique avoir ajouté plusieurs extensions, dont l’API SRW, et patché le noyau pour corriger une condition de concurrence causant un interblocage dans l’API keyed event fondée sur l’implémentation SRW.
  • Il est signalé que le programme contient un bug. Il mélange des variables non atomiques et atomiques dans une boucle de vérification avec yield(), et les variables non atomiques ne garantissent pas la cohérence du cache entre threads. La boucle peut donc s’exécuter indéfiniment.

    • Un utilisateur signale un bug dans le programme et explique le problème causé par l’utilisation conjointe de variables non atomiques et atomiques. Il mentionne que les variables non atomiques ne garantissent pas la cohérence du cache, ce qui peut entraîner une boucle infinie.
  • Un utilisateur indique que ce bug remonte à la version Vista de 2008 et se dit surpris que personne ne l’ait découvert pendant aussi longtemps. Il note que, dans un usage classique des rwlock, on peut observer des cas aléatoires où un verrou partagé n’est pas acquis, sans pour autant provoquer d’interblocage.

    • Un utilisateur précise que ce bug remonte à Vista et se dit surpris qu’il soit passé inaperçu si longtemps. Il mentionne que, dans l’utilisation habituelle des rwlock, il n’y a pas d’interblocage, mais qu’il peut exister des cas où un verrou partagé n’est pas obtenu.
  • Un utilisateur affirme qu’il est très difficile de signaler un bug dans l’API Windows, expliquant qu’on lui demande de passer par Feedback Hub, ce qu’il juge presque inutile. Il dit avoir signalé un bug où SRWLOCK peut se retrouver en interblocage lorsque plusieurs threads de lecture tentent d’acquérir ensemble une propriété partagée après qu’un propriétaire exclusif a libéré cette propriété.

    • Un utilisateur affirme qu’il est très difficile de signaler des bugs dans l’API Windows et critique l’inefficacité des signalements via Feedback Hub. Il partage le fait qu’il a effectivement signalé un bug lié à SRWLOCK.
  • Un utilisateur se souvient qu’autrefois, l’achat de produits MS donnait droit à des incidents de support, et que l’incident était remboursé lorsqu’un vrai bug était découvert. Il estime que c’était un bon système, utile aux développeurs et à MS, car il permettait de remonter de vrais problèmes et d’améliorer la documentation. Il se demande si ce programme existe encore.

    • Un utilisateur se remémore les incidents de support inclus autrefois avec les produits MS et indique que ce système était bénéfique à la fois pour les développeurs et pour MS. Il se demande s’il existe encore aujourd’hui.
  • Enfin, un utilisateur exprime sa déception face à la difficulté de signaler des bugs dans l’API Windows.

    • Un utilisateur exprime sa déception quant à la difficulté de signaler des bugs dans l’API Windows.