Les raisons courantes pour les bugs dans la version de sortie ne sont pas présents en mode débogage

StackOverflow https://stackoverflow.com/questions/1762088

  •  21-09-2019
  •  | 
  •  

Question

Quelles sont les raisons typiques pour les bugs et le comportement anormal du programme qui ne se manifestent que dans la version mode de compilation, mais qui ne se produisent pas en mode de débogage?

Était-ce utile?

La solution

Plusieurs fois, en mode débogage en C ++ toutes les variables sont nulles initialisées, alors que le même ne se produit pas en mode de libération sauf mention explicite.

Vérifier toutes les macros de débogage et variables non initialisées

Votre programme utilise le filetage, puis l'optimisation peut également causer des problèmes en mode de libération.

Vérifiez également toutes les exceptions, par exemple pas directement lié à la libération en mode, mais parfois nous ignorer quelques exceptions critiques, comme violation Mem d'accès en VC ++, mais la même chose peut être un problème au moins dans d'autres OS comme Linux, Solaris. Idéalement, votre programme ne devrait pas prendre de telles exceptions critiques comme l'accès à un pointeur NULL.

Autres conseils

Un piège courant utilise une expression d'effet secondaire à l'intérieur une assertion.

D'autres différences pourraient être:

  • Dans une langue ramasse-miettes, la collecteur est généralement plus agressif dans le mode de libération;
  • Mise en page de la mémoire peut souvent différent;
  • Mémoire peut être initialisé différemment (par exemple, pourrait être mis à zéro en mode débogage ou réutilisé plus agressivement dans la version);
  • Les sections locales peuvent être promu pour enregistrer des valeurs de libération, qui peut causer des problèmes avec virgule flottante valeurs.

J'ai été mordu par un certain nombre de bugs dans le passé qui ont été très bien dans debug mais crash construit Release. Il existe de nombreuses causes sous-jacentes (y compris bien sûr ceux qui ont déjà été résumées dans ce fil) et j'ai été pris par tous les éléments suivants:

  • Les variables membres ou fonctions membres dans un #ifdef _DEBUG, de sorte qu'une classe est une taille différente dans une version de débogage. Parfois, #ifndef NDEBUG est utilisé dans une version release
  • De même, il y a un autre #ifdef qui se trouve être présent que dans l'un des deux builds
  • La version de débogage utilise des versions de débogage des bibliothèques du système, en particulier les fonctions allocation tas et mémoire
  • Fonctions inline dans une version release
  • Ordre de l'inclusion des fichiers d'en-tête. Cela ne devrait pas causer des problèmes, mais si vous avez quelque chose comme un #pragma pack qui n'a pas été réarmé cela peut conduire à des problèmes désagréables. Des problèmes similaires peuvent également se produire en-têtes précompilés et forcé comprend
  • Caches: vous pouvez avoir un code tel que des caches qui ne se habitue dans la version construit, ou des limites de taille de cache qui sont différentes
  • Configurations de projet: les configurations de débogage et communication peut différents paramètres de construction (ce qui est susceptible de se produire lors de l'utilisation d'un IDE)
  • Les conditions de course, des problèmes de timing et effets secondaires se produisent miscellanous à la suite de débogage uniquement le code

Quelques conseils que j'ai accumulé au fil des années pour aller au fond des bogues de débogage / libération:

  • Essayez de reproduire un comportement anormal dans un débogage construire si vous le pouvez, et mieux encore, écrire un test unitaire pour le capturer
  • Pensez à ce qui diffère entre les deux: les paramètres du compilateur, des caches, le code de débogage uniquement. Essayez de minimiser ces différences temporairement
  • Créer une version release avec Optimisations éteint (si vous avez plus de chances d'obtenir des données utiles dans le débogueur), ou une version de débogage optimisé. En réduisant au minimum les changements entre le débogage et la libération, vous êtes plus susceptibles d'être en mesure d'isoler cette différence est à l'origine du bogue.

Oui !, si vous avez la compilation conditionnelle, il peut y avoir des bugs de synchronisation (optimisé vers la libération de code, le code de débogage non optimisé), la mémoire réutilisation par rapport tas de débogage.

Il peut, surtout si vous êtes dans le domaine C.

Une cause pourrait être que la version DEBUG peut ajouter du code pour vérifier les pointeurs errants et en quelque sorte à protéger votre code de tomber en panne (ou se comportent de manière incorrecte). Si tel est le cas, vous devriez vérifier soigneusement les avertissements et autres messages que vous obtenez de votre compilateur.

Une autre cause pourrait être l'optimisation (qui est normalement pour les versions et désactivé pour le débogage). Le code et la présentation des données peut avoir été optimisé et alors que votre programme de débogage était juste, par exemple, l'accès à la mémoire non utilisée, la version est maintenant essayer d'accéder à la mémoire réservée ou même en montrant code!

EDIT: Je vois d'autres mentionné: Bien sûr, vous pourriez avoir des sections entières de code qui sont conditionnellement exclus sinon la compilation en mode DEBUG. Si tel est le cas, je souhaite que le débogage est vraiment le code et non quelque chose de vital pour l'exactitude du programme lui-même!

Les fonctions de la bibliothèque CRT se comportent différemment dans debug vs libération (/ MD vs / MDd).

Par exemple, les versions de débogage souvent des tampons de pré-remplissage vous passez à la longueur indiquée pour vérifier votre demande. Les exemples incluent strcpy_s, StringCchCopy, etc. Même si les chaînes se terminent plus tôt, votre szDest mieux être n octets!

Bien sûr, par exemple, si vous utilisez des constructions comme

#if DEBUG

//some code

#endif

Dans .NET, même si vous ne l'utilisez pas la compilation conditionnelle comme #if DEBUG, le compilateur est encore beaucoup plus libéral avec Optimisations en mode de libération que dans le mode de débogage, qui peut conduire à ne libérer que des bugs aussi bien.

Vous auriez besoin de donner beaucoup plus d'informations, mais oui, il est possible. Cela dépend de ce que votre version de débogage fait. Vous pouvez bien avoir l'exploitation forestière ou des contrôles supplémentaires dans ce qui ne reçoivent pas compilés dans une version de version. Ces seuls chemins de code peuvent avoir des effets déboguer secondaires inattendus qui changent d'état ou influent sur les variables de façon étrange. Debug fonctionne généralement plus lent, donc cela peut affecter les conditions de course de filetage et se cacher. La même chose pour Optimisations avant droite d'une compilation de sortie, il est possible (bien que peu probable ces jours-ci) qu'une compilation de libération peut quelque chose de court-circuit comme une optimisation.

Sans plus de détails, je suppose que « pas OK » signifie qu'il soit ne compile pas ou jette une sorte d'erreur lors de l'exécution. Vérifiez si vous avez du code qui repose sur la version de compilation, soit par des déclarations de #if DEBUG ou via des méthodes marquées avec l'attribut Conditional.

Cela est possible, si vous avez la compilation conditionnelle afin que le code de débogage et le code de déverrouillage sont différents, et il y a un bogue dans le code qui utilise uniquement dans le mode de libération.

En dehors de cela, il est impossible. Il existe des différences dans la façon dont le code de débogage et le code de libération sont compilés, et les différences dans la façon dont le code est exécuté si elle est exécutée sous un débogueur ou non, mais si l'une de ces différences posent autre chose qu'une différence de performance, le problème a toujours été là.

Dans la version de débogage l'erreur pourrait ne pas être INTERVENUES (parce que l'allocation de synchronisation ou de la mémoire est différente), mais cela ne veut pas dire que l'erreur est pas là. Il peut aussi y avoir d'autres facteurs qui ne sont pas liés au mode de débogage qui change le calendrier du code, ce qui provoque l'erreur de se produire ou non, mais tout se résume au fait que si le code était correct, l'erreur ne se produirait pas dans l'une des situations.

Alors, non, la version de débogage n'est pas OK juste parce que vous pouvez l'exécuter sans avoir une erreur. Si une erreur se produit lorsque vous exécutez en mode de libération, ce n'est pas en raison du mode de sortie, il est parce que l'erreur était là depuis le début.

Il y a des optimisations du compilateur que peut casser le code valide parce qu'ils sont trop agressifs.

Essayez de compiler votre code avec moins d'optimisation est activée.

Dans une fonction non vide, tous les chemins d'exécution doivent se terminer par une déclaration de retour.

En mode débogage, si vous oubliez de mettre fin à un tel chemin avec une déclaration de retour alors la fonction renvoie généralement 0 par défaut.

Cependant, en mode de libération de votre fonction peut renvoyer des valeurs de déchets, ce qui peut affecter la façon dont votre programme fonctionne.

Il est possible. Si cela se produit et aucune compilation conditionnelle est impliquée, que vous pouvez être sûr que votre programme est erroné, et travaille en mode débogage seulement en raison de initialisations de mémoire fortuit ou même la mise en page en mémoire!

Je viens de vivre que lorsque j'appelle une fonction de montage qui n'a pas restauré les valeurs précédentes des registres.

Dans la configuration "Release", VS compilait avec / O2 qui optimise le code pour la vitesse. Ainsi certaines variables locales où cartographie simplement des registres CPU (pour l'optimisation) qui ont été partagées avec la fonction précitée conduisant à une corruption de mémoire grave.

voir si vous Quoiqu'il en soit pas déconner indirectement avec les registres CPU partout dans votre code.

Je me souviens il y a quelque temps quand nous étions en train de dll et pdb en c / c ++.

Je me souviens:

  • Ajout de données du journal serait parfois faire bouger bug ou disparaître ou faire une autre erreur apparaît totalement (il était donc pas vraiment une option).
  • Un grand nombre de ces erreurs lorsqu'elles sont dues à l'allocation CHAR dans strcpy et strcat et des tableaux de char [] etc ...
  • Nous désherbé certains par des bornes en cours d'exécution vérificateur et fixer simplement le mémoire problèmes alloc / de dealloc.
  • Plusieurs fois, nous sommes allés systématiquement le code et fixe une allocation de char (comme dans tous les fichiers).
  • Certainement, il est quelque chose lié à l'allocation de mémoire et de la gestion et les contraintes et les différences entre le mode de débogage et le mode de libération.

Et puis espérer le meilleur.

Je parfois, temporairement livré des versions de débogage de dll aux clients, afin de ne pas retarder la production, tout en travaillant sur ces bogues.

Une autre raison pourrait être des appels DB. Épargnez-vous et la mise à jour même enregistrement plusieurs fois dans la même fil, parfois pour la mise à jour. Il est possible la mise à jour a échoué ou travail na pas comme prévu parce que la précédente commande create était encore en cours de traitement et de mise à jour, l'appel db n'a pas réussi à trouver un enregistrement. cela ne se fera pas en tant que débogage débogueur veille à remplir toutes les tâches en attente avant l'atterrissage.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top