2010-09-19 17 views
20

J'ai lu que INT 3 (0xCC) est utilisé pour les points d'arrêt logiciels.Comment les débogueurs garantissent-ils l'exactitude lors de l'utilisation du point d'arrêt logiciel INT 3 (0xCC) même si une instruction a été corrigée?

il est défini par (par exemple) un débogueur en écrasant le code réel du programme dans la mémoire.

J'ai aussi lu que INT 3 est une exception « piège » non « défaut » qui signifie l'adresse poussé sur la pile est l'adresse de l'instruction qui suit l'instruction INT3.

Comment le débogueur garantit-il l'exactitude si l'instruction corrigée n'est pas ré-exécutée?

+0

Quelqu'un peut-il citer le code source de GDB? :-) –

Répondre

26

Lorsque vous voulez continuer l'exécution après que les feux de point d'arrêt, vous avez deux possibilités: soit le point d'arrêt ne devait tirer une fois, ou il était censé être persistant. Si elle était supposée déclencher une fois, vous restaurez la valeur d'origine écrasée avec votre instruction breakpoint, ajustez manuellement l'adresse à l'adresse de cette instruction (souvenez-vous, quelle que soit l'instruction, exécuté était votre point d'arrêt à un octet, donc l'ajustement est toujours trivial). Ensuite, vous continuez l'exécution.

S'il était supposé être un point d'arrêt persistant, il y a une ride supplémentaire: avant de continuer l'exécution, vous définissez le bit à une seule étape (aka trap) dans les drapeaux de la pile. Cela signifie que seule l'instruction où le point d'arrêt a été défini sera exécutée, et vous recevrez à nouveau une interruption du point d'arrêt. Vous répondez à cela en restaurant l'int 3 octet que vous venez de patcher sur le premier octet de l'instruction d'origine, et (à nouveau) continuez l'exécution.

+0

mentionné également sur le [GDB wiki internals] (https://sourceware.org/gdb/wiki/Internals/Breakpoint%20Handling): « Lorsque l'utilisateur dit de continuer, gdb restaurez l'instruction d'origine, en une seule étape, réinsérez le piège et continuez. " –

2

La solution habituelle est pour le débogueur de modifier l'adresse sur la pile (et rétablir l'instruction qui a été écrasée par le piège), de sorte qu'il n'exécute l'instruction corrigée.

4

Cela fait longtemps que je ne me suis pas intéressé à ce genre de choses, mais en supposant que vous ayez raison de pousser l'adresse suivante sur la pile, le débogueur peut afficher l'adresse de retour et l'utiliser pour déterminer le point d'arrêt était (l'adresse de retour moins un, puisque l'instruction INT 3 est longue d'un octet) [édité]. En d'autres termes, le débogueur n'a pas nécessairement besoin de retourner à l'adresse sur la pile. Il peut restaurer l'instruction d'origine, puis l'exécuter à l'emplacement d'origine. Si le point d'arrêt doit rester positionné, il peut utiliser le "bit de piège" dans les drapeaux pour n'exécuter qu'une seule instruction - l'originale qui a été écrasée - avant qu'un autre trap ne soit généré (INT 3 encore je pense); alors l'instruction INT 3 peut être rétablie avant de poursuivre l'exécution correctement.

La plupart du temps, cependant, les débogueurs fonctionnent dans un système où ils ne sont pas directement manipuler le piège de toute façon; ils pourraient être délivrés un signal, par exemple, en leur disant où le piège s'est produit. Très probablement, ils doivent encore trouver l'adresse "réelle" (c'est-à-dire l'adresse de l'instruction INT3) à partir de l'adresse d'interruption, car le système d'exploitation n'a aucun moyen de le faire.

Les choses se compliquent aussi, s'il y a plusieurs threads impliqués; dans ce cas, la restauration de l'instruction d'origine "en place" peut entraîner l'absence du point d'arrêt s'il est frappé par un autre thread. Une solution pourrait être d'arrêter tous les autres threads avant de restaurer l'instruction (et de les redémarrer ensuite).

+1

INT est simple pas à pas 1 IIRC – ninjalj