2009-06-07 6 views

Répondre

5

Il peut être très utile dans les cas où vous ne pouvez pas (encore) reproduire de façon fiable un bug , comme en raison d'une corruption de tas/pile. Vous pourriez obtenir un ou deux core dumps, très probablement d'un client. Même en supposant que votre débogueur est fiable, en regardant l'assemblage peut vous dire exactement quelle instruction est plante (et donc quel morceau de mémoire est corrompu).

En outre, dans mon expérience (principalement dans le débogage du noyau) les débogueurs ont été relativement mauvais à traiter le code optimisé. Ils obtiennent des choses comme paramètres/etc faux, et à vraiment dire ce qui se passe, je dois regarder diassembly.

Si je peux reproduire un problème, il ne tend pas fiable/facilement être aussi utile pour traiter le démontage, parce que je vais obtenir plus d'informations de marcher juste par le programme. D'un autre côté, arriver au point où vous pouvez reproduire un problème est généralement plus de la moitié de la réparer.

+0

Battez-moi et je le dis mieux. – Dipstick

2

Sauf si vous soupçonnez le compilateur, je n'irais pas bas niveau pour le débogage. Mieux vaut déboguer au même niveau d'abstraction que vous exprimez votre intention dans l'algorithme.

Si vous écrivez le code en C/C++ alors utilisez un bon débogueur C/C++ pour l'accompagner.

+0

Parfois, vous devez examiner le problème sous un angle différent. Et vous pouvez apprendre beaucoup de code d'assemblage et d'octets. –

1

Cela peut aider avec certains des trucs avancés, et il est toujours utile de comprendre ce qui se passe "sous le capot". Mais à moins de faire du codage d'assemblage de toute façon (et si vous l'étiez, vous connaîtriez l'assemblage), déboguer avec l'assemblage est probablement exagéré. Les bogues seront probablement directement dans votre code, et non dans la traduction entre votre code et votre assembly.

2

Je présume que vous demandez quand utiliser un désassemblage lorsque vous voulez déboguer votre code écrit en C/C++.

Il y aura des cas où vous pensez que le compilateur n'a pas généré le code comme vous l'auriez voulu. En règle générale, lorsque la version optimisée de l'exécutable ne fonctionne pas correctement mais que la forme non optimisée fonctionne correctement. Vous voudriez vérifier le désassemblage puis voir quelle optimisation a changé le comportement.

Un autre cas serait lorsque vous voulez comprendre le comportement de l'exécutable, mais vous n'avez pas le code source pour commencer - c'est ce que l'on appelle le reverse engineering. Vous n'avez pas d'autre choix que de travailler avec le désassemblage de l'exécutable.

Une référence Wiki de dis-assembly and analysis tools pour comprendre les outils et commencer à apprendre celui qui convient le mieux à votre environnement.

3

Je ne peux pas vous dire "Quand" mais parfois vous pouvez avoir un comportement bizarre en C/C++ et vous ne comprenez vraiment pas ce qui se passe ... Regardez simplement le code asm, il ne vous trahira jamais.

Mais ici, je vérifie le code ASM de mes programmes C tout le temps ... pour l'optimisation, la curiosité et l'apprentissage.

Par tous les moyens apprendre le langage d'assemblage x86!

+0

+1 pour apprendre à partir de l'optimiseur et pour le plier selon vos besoins. – diapir

2

Je suis définitivement revenu à la lecture de l'assemblage à quelques reprises. GCC le rend plutôt pratique. Un bon exemple est le sujet one of my questions. GCC a changé le comportement entre 2,95 et 3,4,3, et aller à l'assemblage dans la fonction suspecte a expliqué pourquoi mon programme se bloquait.

Il est également utile lorsque vous vraiment besoin de savoir comment certains accès sont en cours. Si vous avez une mémoire mappée sur un bus, par exemple, vous voudrez peut-être savoir que vous faites un accès 16 bits au lieu d'un accès 32 bits.

Un autre cas que j'ai utilisé récemment pour l'assemblage est de vérifier que mes variables 'volatiles' sont vraiment traitées comme volatiles. Il s'avère que presque tous les compilateurs se trompent parfois, donc j'ai commencé à vérifier la sortie de cas spécifiques pour m'assurer que l'assembly référence réellement l'emplacement de la mémoire au lieu d'un registre.

1

La raison pour laquelle assembly peut aider à déboguer un programme est que gcc optimise souvent pour vous.Vous devez regarder à travers l'assemblée pour toutes les "améliorations" de gcc et assurez-vous qu'elles ne gâchent pas les choses.

Par exemple

/* global */ 
int x = 1; 

void *myFunc() { 
    /* do something productive */ 
    x = 0; 
    return NULL; 
} 

int main() { 
    thread_create(myFunc); 

    while(x) continue; 

    exit(1); 
} 

Dans certaines optimisations, while(x) continue; devient un jmp 0xDEADBEEF (où 0xDEADBEEF est l'instruction jmp). Vous pouvez le voir dans l'assemblage, et savoir changer x en volatile.

Sinon, l'assemblage risque de vous nuire en termes de compréhension de tout.

1

Dans certaines circonstances, vous n'avez pas d'autre choix que de revenir à l'assembleur. Si votre système tombe en panne et que tout ce que vous avez est un vidage du noyau ou une trace de pile avec peu de symboles, alors regarder le code source de haut niveau ne va pas vous aller très loin.

+0

Un coredump ou un stacktrace a des adresses qui pointent vers votre code, donc l'assemblage n'est pas vraiment nécessaire. – Gerhard

+0

Désolé Gerhard mais je ne comprends pas votre commentaire. Comment trouvez-vous exactement où dans votre code les adresses pointent si vous ne pouvez pas comprendre l'assembleur généré à partir du code c? – Dipstick

1

Je pense que les vidages de mémoire sont beaucoup plus utiles au débogage que d'apprendre à l'assembleur à le faire. Avec Visual Studio par exemple, vous pouvez vérifier quel emplacement mémoire change après une ligne de code particulière. La touche de raccourci est ALT-6 en mode débogage. Vous pouvez obtenir des emplacements variables en utilisant les montres standard.

0

J'ai un peu d'utilisation pour mes compétences d'assemblage à la recherche de bogues causés par une nouvelle version du compilateur que nous utilisions. Mais les bogues du compilateur sont très rares, donc ma réponse serait non pour le débogage.

Il est intéressant de voir comment le compilateur résout un problème d'assemblage à partir de votre source, mais ce n'est pas vraiment le débogage.

2

Je pense que vous aurez besoin d'apprendre l'assemblage à un moment ou l'autre. Connaître l'assemblage est la seule solution si un bogue est reproductible dans une version uniquement ou lors du débogage d'une bibliothèque tierce dans laquelle vous n'avez pas le code source. Il y a plus de raisons d'apprendre l'assemblage que de ne pas le faire.

Vous pouvez également jeter un oeil à mes articles récents sur le débogage dans l'assemblage mieux - http://mohit.io/blog/assembly-and-the-art-of-debugging/

Mise à jour -> Si vous souhaitez modifier le comportement de votre code à l'exécution sans recompilation, puis l'assemblage d'apprentissage est un indispensable.Jetez un oeil à http://mohit.io/blog/debugging-modifying-code-at-runtime/

1

Il est utile pour déboguer les versions optimisées; en particulier, lorsqu'un client vous envoie une minidump de votre application sur le terrain. Dans ces cas, de nombreux débogueurs sont assez faibles pour garder une trace des variables locales, et vous devez les sortir de la pile (ou des registres) à la main.

Questions connexes