2016-01-08 2 views
5

J'ai un exemple classique d'un Heisenbug qui est déclenché par une condition que je n'avais pas vue auparavant. Mon application héritée (environ 100 Ko de code ancien) ne fonctionne pas correctement dans une instance spécifique et le simple fait d'autoriser JPDA à déboguer à distance modifie le comportement, provoquant le bon fonctionnement de l'application: ne faisant rien d'autre que "-Xdebug -Xnoagent -Xrunjdwp: transport = dt_socket, serveur = y, suspend = n, adresse = 6666 "à la ligne de commande de vm cache le bogue (avec ou sans connexion réelle). Étant donné que j'ai un cas de test entièrement reproductible, je déteste le perturber beaucoup avec les changements de code au cas où il reviendrait dans la clandestinité. Et bien sûr, cela se produit uniquement en production.Causes probables et improbables de Heisenbugs en Java?

Habituellement, je suppose immédiatement un problème de threading, mais a) le comportement est 100% d'échec contre 100% de travail et b) il n'y a pas d'utilisation explicite de threads dans le chemin de code en question. Notre équipe essayait alors de trouver une liste d'autres raisons de ce comportement, alors j'ai pensé que l'esprit de groupe de Stack Overflow pourrait en rajouter.

en Java: bug logiciel inhabituel

  • Sujets: mauvaise synchronisation, les conditions de course, des hypothèses implicites de commande.
  • Code de débogage/consignation explicite: les modifications du chemin du code provoquent/empêchent le problème. Moins fréquemment, les modifications du niveau de journalisation peuvent entraîner des changements de synchronisation (enfilage à nouveau) et des différences dans l'utilisation des ressources d'E/S.
  • Les bibliothèques de code natives peuvent faire glisser des problèmes Heisenbug non-java.
  • Espérons que les finaliseurs fonctionneront de manière prévisible.
  • Hypothèses incorrectes sur les références faibles.
  • supposons qu'un cache de taille fixe ne se remplit jamais.
  • en attendant l'unicité des hashcodes.
  • l'hypothèse que == fonctionne sur les chaînes (ou ne fonctionne pas sur les chaînes pouvant être internées dans certains cas).
  • Bogue VM (nah, que jamais arrive;).
  • erreur (s) de la méthode d'essai. Surtout quand il y a des variables cachées qui dépendent du succès du test. (Cela semble être notre problème réel.Le succès d'un test a conduit le client à exécuter le prochain test, qui a échoué en raison de problèmes de politique.L'échec a conduit à fonctionner en mode débogage conformément à la politique, ce qui a abouti à succès.Sigh)

D'autres cas méritent d'être explorés?

Edits:

  • oui, le code d'activation JPDA utilise ancienne syntaxe. Je n'ai pas testé pour voir si l'utilisation de la syntaxe moderne change aussi le comportement.
  • Cette machine spécifique utilise 1.8.0_45-b14 pour le JRE et HotSpot 64 bits serveur VM (build-B02 25,45)
  • alors que la question est destinée à être générale, la question de dynamisante est réelle et actuelle. Puisque le problème se manifeste dans un système déployé, je suis déchiré entre vouloir le laisser fonctionner avec -Xdebug comme solution de contournement pour qu'il reste opérationnel et qu'il cherche à localiser le bogue sous-jacent et à le tuer.
  • le programme défectueux en question fait partie d'un pipeline de traitement de données en plusieurs étapes - les détails ne devraient pas importer, mais mieux se comprendre comme une application autonome qui obtient des informations d'une base de données, puis l'utilise pour modifier certains fichiers .La partie du système qui se casse semble être que les informations de la base de données ne sont pas interprétées correctement - tout ce qui provient d'un ORM ou d'un cache d'objet brisé. Quand elle est "cassée", la logique de l'application qui détermine si elle a du travail à faire (en fonction du contenu de la base de données) fait le mauvais choix pour toutes les itérations (milliers d'itérations incluant les invocations multiples du programme). Quand il "travaille" (la seule différence est que vm fonctionne avec -Xdebug ou pas), l'application fait les bons choix pour toutes les itérations. Il est complètement cohérent dans cette configuration. Le même code s'exécutant sur différentes bases de données n'échoue pas. Il existe des preuves (antérieures à mon implication dans ce code) qu'un comportement similaire a été vu dans le passé qui a mystérieusement commencé à fonctionner après des changements de code apparemment mineurs ... voir "Heisenbug"
+0

Je diviserais les drapeaux si possible. Le débogage en particulier me fait suspecter le JIT. – chrylis

+0

Cette question pourrait obtenir des informations intéressantes pour beaucoup d'entre nous. Pourquoi quelqu'un voudrait-il le fermer? – Andres

+0

@ m.thome, cela vous dérangerait-il d'expliquer un peu plus précisément ce que vous entendez par "le comportement est 100% d'échec contre 100% de travail"? Je veux dire par là quel est le comportement qui échoue 100% du temps ou passe 100% du temps? En outre, quelle est votre application (par exemple, bureau, service Web, application de ligne de commande monothread autonome, etc.)? Je ne suis pas à la recherche d'informations commerciales confidentielles, mais un peu plus de contexte m'aiderait à affiner certaines armes à feu dans une réponse. – entpnerd

Répondre

3

J'ai eu un cas où le l'échec a été provoqué par une fonction d'économie d'énergie sur le matériel qui n'a jamais été activé lorsque le bogue était à l'étude.

+0

C'est intéressant. Quel était le matériel et quelle était la fonction d'économie d'énergie? – entpnerd

+2

C'était il y a environ 15 ans. C'était le gros client d'un point de vente, fonctionnant sur un PC Compaq. Chaque fois que l'opérateur quitte le PC, la fonction d'économie d'énergie est activée (disques, moniteur et processeur) et le système raccroche. Nous ne l'avons pas réparé, nous avons simplement désactivé l'économie d'énergie. – Andres