Je me demande comment fonctionne un débogueur? Particulièrement celui qui peut être «attaché» à un exécutable déjà en cours d'exécution. Je comprends que le compilateur traduit le code en langage machine, mais comment le débogueur "sait-il" à quoi il est attaché?
170
Réponses:
Les détails du fonctionnement d'un débogueur dépendent de ce que vous déboguez et du système d'exploitation. Pour le débogage natif sur Windows, vous pouvez trouver quelques détails sur MSDN: API de débogage Win32 .
L'utilisateur indique au débogueur à quel processus se connecter, soit par nom, soit par ID de processus. S'il s'agit d'un nom, le débogueur recherchera l'ID de processus et lancera la session de débogage via un appel système; sous Windows, ce serait DebugActiveProcess .
Une fois attaché, le débogueur entrera dans une boucle d'événements un peu comme pour n'importe quelle interface utilisateur, mais au lieu d'événements provenant du système de fenêtrage, le système d'exploitation générera des événements en fonction de ce qui se passe dans le processus en cours de débogage - par exemple une exception se produisant. Voir WaitForDebugEvent .
Le débogueur est capable de lire et d'écrire la mémoire virtuelle du processus cible, et même d'ajuster ses valeurs de registre via les API fournies par le système d'exploitation. Consultez la liste des fonctions de débogage pour Windows.
Le débogueur peut utiliser les informations des fichiers de symboles pour traduire des adresses en noms et emplacements de variables dans le code source. Les informations du fichier de symboles constituent un ensemble distinct d'API et ne font pas partie intégrante du système d'exploitation en tant que tel. Sur Windows, c'est via le SDK Debug Interface Access .
Si vous déboguez un environnement géré (.NET, Java, etc.), le processus sera généralement similaire, mais les détails sont différents, car l'environnement de la machine virtuelle fournit l'API de débogage plutôt que le système d'exploitation sous-jacent.
la source
Si je comprends bien:
Pour les points d'arrêt logiciels sur x86, le débogueur remplace le premier octet de l'instruction par
CC
(int3
). Ceci est fait avecWriteProcessMemory
sur Windows. Lorsque le CPU arrive à cette instruction et exécute leint3
, le processeur génère une exception de débogage. Le système d'exploitation reçoit cette interruption, réalise que le processus est en cours de débogage et informe le processus de débogage que le point d'arrêt a été atteint.Une fois le point d'arrêt atteint et le processus arrêté, le débogueur recherche dans sa liste de points d'arrêt et remplace le
CC
par l'octet qui s'y trouvait à l'origine. Le débogueur définitTF
, l'indicateur d'interruption dansEFLAGS
(en modifiant leCONTEXT
) et continue le processus. L'indicateur d'interruption amène le processeur à générer automatiquement une exception en une seule étape (INT 1
) sur l'instruction suivante.Lorsque le processus en cours de débogage s'arrête la prochaine fois, le débogueur remplace à nouveau le premier octet de l'instruction de point d'arrêt par
CC
et le processus se poursuit.Je ne sais pas si c'est exactement ainsi qu'il est implémenté par tous les débogueurs, mais j'ai écrit un programme Win32 qui parvient à se déboguer en utilisant ce mécanisme. Complètement inutile, mais éducatif.
la source
Sous Linux, le débogage d'un processus commence par l' appel système ptrace (2) . Cet article contient un excellent didacticiel sur la façon d'utiliser
ptrace
pour implémenter des constructions de débogage simples.la source
(2)
nous dit quelque chose de plus (ou moins) que "ptrace est un appel système"?(2)
est le numéro de section du manuel. Voir en.wikipedia.org/wiki/Man_page#Manual_sections pour une description des sections du manuel.ptrace
c'est un appel système.(2)
nous dit que nous pouvons taperman 2 ptrace
et obtenir la bonne page de manuel - pas important ici car il n'y en a pas d'autreptrace
pour lever l'ambiguïté, mais pour comparerman printf
avecman 3 printf
Linux.Si vous utilisez un système d'exploitation Windows, une excellente ressource pour cela serait «Débogage des applications pour Microsoft .NET et Microsoft Windows» par John Robbins:
(ou même l'ancienne édition: "Debugging Applications" )
Le livre contient un chapitre sur le fonctionnement d'un débogueur qui inclut du code pour quelques débogueurs simples (mais fonctionnels).
Comme je ne suis pas familier avec les détails du débogage Unix / Linux, cela peut ne pas s'appliquer du tout aux autres OS. Mais je suppose qu'en tant qu'introduction à un sujet très complexe, les concepts - sinon les détails et les API - devraient «porter» sur la plupart des systèmes d'exploitation.
la source
Le manuel des processeurs Intel (Intel® 64 et IA-32 Architectures Software Developer's Manual) est une autre source précieuse pour comprendre le débogage. Dans le volume 3A, chapitre 16, il a introduit le support matériel du débogage, comme les exceptions spéciales et les registres de débogage matériel. Ce qui suit est tiré de ce chapitre:
T (trap) flag, TSS - Génère une exception de débogage (#DB) lorsqu'une tentative est faite pour basculer vers une tâche avec l'indicateur T défini dans son TSS.
Je ne sais pas si Windows ou Linux utilisent ce drapeau ou non, mais il est très intéressant de lire ce chapitre.
J'espère que cela aide quelqu'un.
la source
Je pense qu'il y a deux questions principales auxquelles répondre ici:
1. Comment le débogueur sait-il qu'une exception s'est produite?
Lorsqu'une exception se produit dans un processus en cours de débogage, le débogueur est notifié par le système d'exploitation avant que les gestionnaires d'exceptions utilisateur définis dans le processus cible aient la possibilité de répondre à l'exception. Si le débogueur choisit de ne pas gérer cette notification d'exception (de première chance), la séquence de distribution d'exceptions continue et le thread cible a alors la possibilité de gérer l'exception s'il le souhaite. Si l'exception SEH n'est pas gérée par le processus cible, le débogueur reçoit alors un autre événement de débogage, appelé notification de seconde chance, pour l'informer qu'une exception non gérée s'est produite dans le processus cible.La source
2. Comment le débogueur sait-il s'arrêter sur un point d'arrêt?
La réponse simplifiée est: lorsque vous mettez un point d'arrêt dans le programme, le débogueur remplace votre code à ce stade par une instruction int3 qui est une interruption logicielle . En conséquence, le programme est suspendu et le débogueur est appelé.
la source
Je crois comprendre que lorsque vous compilez une application ou un fichier DLL, tout ce qu'il compile contient des symboles représentant les fonctions et les variables.
Lorsque vous avez une version de débogage, ces symboles sont beaucoup plus détaillés que lorsqu'il s'agit d'une version de version, permettant ainsi au débogueur de vous donner plus d'informations. Lorsque vous attachez le débogueur à un processus, il regarde quelles fonctions sont actuellement accédées et résout tous les symboles de débogage disponibles à partir d'ici (puisqu'il sait à quoi ressemblent les éléments internes du fichier compilé, il peut déterminer ce qui pourrait être en mémoire , avec le contenu des entiers, des flottants, des chaînes, etc.). Comme l'a dit la première affiche, ces informations et le fonctionnement de ces symboles dépendent grandement de l'environnement et de la langue.
la source