Quelles sont les raisons typiques des bugs et des comportements de programme anormaux qui ne se manifestent qu'en mode compilation, mais qui ne se produisent pas en mode débogage?
Plusieurs fois, en mode débogage en C++, toutes les variables sont initialisées à zéro, alors que la même chose ne se produit pas en mode édition, sauf indication explicite.
Recherchez des macros de débogage et des variables non initialisées.
Votre programme utilise-t-il le threading, alors l'optimisation peut aussi causer des problèmes en mode release.
Vérifiez également toutes les exceptions, par exemple non directement liées au mode de publication, mais nous ignorons parfois certaines exceptions critiques, telles que la violation d'accès de mem dans VC++, mais cela peut poser problème au moins sous un autre système d'exploitation comme Linux, Solaris. Idéalement, votre programme ne devrait pas intercepter des exceptions critiques telles que l’accès à un pointeur NULL.
Un piège courant consiste à utiliser une expression avec un effet secondaire dans un ASSERT.
D'autres différences pourraient être:
J'ai déjà été piqué par un certain nombre de bugs qui fonctionnaient bien dans les versions Debug mais qui plantaient dans les versions Release. Il y a beaucoup de causes sous-jacentes (y compris bien sûr celles qui ont déjà été résumées dans ce fil) et j'ai été attiré par tout ce qui suit:
#ifdef _DEBUG
, de sorte qu'une classe ait une taille différente dans une construction de débogage. Parfois, #ifndef NDEBUG
est utilisé dans une version release#ifdef
différent qui n'est présent que dans l'une des deux versions#pragma pack
qui n'a pas été réinitialisé, cela peut entraîner de vilains problèmes. Des problèmes similaires peuvent également se produire avec des en-têtes précompilés et des inclus forcés.Quelques conseils que j'ai accumulés au fil des ans pour aller au fond des bogues de débogage/libération:
Oui !, si vous avez une compilation conditionnelle, il peut y avoir des bogues de synchronisation (verset à code de version optimisé, code de débogage non optimisé), une réutilisation de la mémoire et un segment de débogage.
C'est possible, surtout si vous êtes dans le domaine C.
Une des raisons pourrait être que la version de DEBUG peut ajouter du code pour vérifier les pointeurs parasites et protéger votre code contre les plantages (ou se comporte de manière incorrecte). Si tel est le cas, vérifiez attentivement les avertissements et autres messages que vous recevez de votre compilateur.
Une autre cause pourrait être l'optimisation (normalement activée pour les versions et désactivée pour le débogage). La disposition du code et des données a peut-être été optimisée et, alors que votre programme de débogage venait, par exemple, d'accéder à de la mémoire inutilisée, la version en cours tente maintenant d'accéder à la mémoire réservée ou même de pointer du code!
EDIT: Je vois que d'autres l'ont mentionné: bien sûr, vous pourriez avoir des sections de code entières qui sont conditionnellement exclues si vous ne compilez pas en mode DEBUG. Si tel est le cas, j'espère que c'est vraiment du code de débogage et pas quelque chose de vital pour l'exactitude du programme lui-même!
Les fonctions de la bibliothèque CRT se comportent différemment dans les versions debug et release (/ MD vs/MDd).
Par exemple, les versions de débogage pré-remplissent souvent les tampons que vous passez à la longueur indiquée pour vérifier votre réclamation. Les exemples incluent strcpy_s
, StringCchCopy
, etc. Même si les chaînes se terminent plus tôt, votre szDest better soit n octets long!
Bien sûr, par exemple, si vous utilisez des constructions comme
#if DEBUG
//some code
#endif
En .NET, même si vous n'utilisez pas de compilation conditionnelle comme #if DEBUG
, le compilateur reste beaucoup plus libéral avec des optimisations en mode publication qu'en mode débogage, ce qui peut entraîner la publication de bogues uniquement.
Vous auriez besoin de donner beaucoup plus d'informations, mais oui, c'est possible. Cela dépend de ce que fait votre version de débogage. Il se peut que vous ayez des traces de connexion ou des vérifications supplémentaires qui ne soient pas compilées dans une version finale. Ces chemins de code de débogage uniquement peuvent avoir des effets secondaires non souhaités qui changent d'état ou affectent les variables de manière étrange. Les versions de débogage fonctionnent généralement plus lentement, ce qui peut affecter le threading et masquer les conditions de concurrence. De même pour les optimisations simples d'une compilation de version, il est possible (même si cela est peu probable de nos jours) qu'une compilation de version puisse court-circuiter quelque chose en tant qu'optimisation.
Sans plus de détails, je suppose que "pas OK" signifie qu’il ne compile pas ou ne génère pas une erreur au moment de l’exécution. Vérifiez si votre code s'appuie sur la version de compilation, via les instructions #if DEBUG
ou les méthodes marquées de l'attribut Conditional
.
Dans une fonction non vide, tous les chemins d'exécution doivent se terminer par une instruction return.
En mode débogage, si vous oubliez de terminer ce chemin avec une instruction return, la fonction renvoie généralement 0 par défaut.
Cependant, en mode de publication, votre fonction peut renvoyer des valeurs parasites, ce qui peut affecter le fonctionnement de votre programme.
Il existe des optimisations du compilateur qui peuvent casser un code valide car elles sont trop agressives.
Essayez de compiler votre code avec moins d'optimisation activée.
Cela est possible si vous avez une compilation conditionnelle de sorte que le code de débogage et le code de version soient différents, et qu'il existe un bogue dans le code utilisé uniquement en mode de publication.
Sinon, ce n'est pas possible. Il existe des différences dans la manière dont le code de débogage et le code de version sont compilées, et dans le mode d'exécution du code, qu'il soit exécuté sous un débogueur ou non, mais si l'une de ces différences entraîne autre chose qu'une différence de performances, le problème persiste.
Dans la version de débogage, l'erreur peut ne pas se produire (parce que le temps ou l'allocation de mémoire sont différents), mais cela ne signifie pas que l'erreur n'est pas là. Il peut également y avoir d'autres facteurs non liés au mode débogage qui modifient le minutage du code, causant ou non l'erreur, mais tout se résume au fait que si le code était correct, l'erreur ne se produirait pas dans l'une des situations.
Donc, non, la version de débogage n’est pas correcte simplement parce que vous pouvez l’exécuter sans erreur. Si une erreur se produit lorsque vous l'exécutez en mode de publication, ce n'est pas à cause du mode de publication, mais bien parce que l'erreur était présente depuis le début.
Je me souviens de la construction de dll et de pdb en c/c ++.
Je me rappelle de ça:
Et puis espéré pour le mieux.
Parfois, je livrais temporairement des versions de débogage de DLL aux clients, afin de ne pas retarder la production, tout en travaillant sur ces bugs.
Je venais de faire l'expérience de cela lorsque j'appelais une fonction d'assemblage qui ne restaurait pas les valeurs précédentes des registres.
Dans la configuration "Release", VS compilait avec/O2, ce qui optimise le code pour la vitesse. Ainsi, certaines variables locales étaient simplement mappées sur des registres de la CPU (pour l’optimisation) qui étaient partagés avec la fonction susmentionnée, entraînant une grave corruption de la mémoire.
Quoi qu'il en soit, voyez si vous ne jouez pas indirectement avec les registres de la CPU où que ce soit dans votre code.
C'est possible. Si cela se produit et qu'aucune compilation conditionnelle n'est impliquée, vous pouvez être à peu près sûr que votre programme est faux et qu'il fonctionne en mode débogage uniquement à cause d'initialisations mémoire fortuites ou même de la mise en page en mémoire!
Une autre raison pourrait être les appels à la base de données . Enregistrez-vous et mettez-vous à jour le même enregistrement plusieurs fois dans le même thread, Parfois pour la mise à jour . Lors du traitement et de la mise à jour, l’appel de la base de données n’a trouvé aucun enregistrement . Cela ne se produira pas dans le débogage car le débogueur s’assure de terminer toutes les tâches en attente avant l’atterrissage.