80 votes

L'utilisation de gdb pour le code d'assemblage en une seule étape en dehors de l'exécutable spécifié provoque l'erreur "impossible de trouver les limites de la fonction actuelle"

Je suis à l'extérieur gdb cible exécutable et je n'ai même pas une pile qui correspond à la cible. Je veux une seule étape, de toute façon, de sorte que je puisse vérifier ce qui se passe dans mon code assembleur, parce que je ne suis pas un expert en x86 assemblée. Malheureusement, gdb refuse de faire ce montage simple-niveau de débogage. Il me permet de définir et d'arrêter sur les points d'arrêt, mais dès que j'essaie d'en une seule étape à partir de, gdb signale l'erreur "Impossible de trouver les limites de la fonction en cours" et le PROGRAMME ne change pas.

Détails supplémentaires:

Le code machine généré par gcc asm états et je l'ai copié sur la mémoire du noyau emplacement où il est en cours d'exécution, à partir de la sortie de objdump -d. Je ne me dérangerait pas d'une façon simple d'utiliser un chargeur pour charger mon code objet d'un déménagé adresse, mais gardez à l'esprit le chargement doit être fait dans un module du noyau.

Je suppose que l'autre alternative serait de produire un faux module de noyau ou les informations de débogage du fichier à donner à gdb, pour l'obliger à croire que cette zone est dans le code du programme. gdb fonctionne très bien sur le noyau de l'exécutable lui-même.

(Pour ceux qui veulent vraiment savoir, je suis de l'insertion de code lors de l'exécution dans le noyau Linux de données de l'espace à l'intérieur d'un VMware VM et le débogage de gdb de débogage à distance au noyau via VMware Workstation est intégré dans gdb stub. Notez que je n'écris pas de noyau exploits; je suis une sécurité, un étudiant diplômé de l'écriture d'un prototype.)

(Je peux mettre un point d'arrêt sur chaque instruction à l'intérieur de mon assemblée. Cela fonctionne, mais serait assez laborieux après un certain temps, car la taille de x86 instructions de montage varie et l'emplacement de l'assemblée changera à chaque fois que je redémarre.)

146voto

ephemient Points 87003

Au lieu de gdb, exécutez gdbtui. Ou exécutez gdb avec l' -tui de l'interrupteur. Ou appuyez sur C-x C- après avoir entré gdb. Vous êtes maintenant en GDB TUI mode.

Entrez layout asm pour rendre le haut de la fenêtre d'affichage de l'assemblée -- cela va automatiquement suivre votre pointeur d'instruction, bien que vous pouvez également changer les cadres, ou faites défiler pendant le débogage. Appuyez sur C-x s pour entrer SingleKey mode, où run continue up down finish etc. sont abrégés à une touche unique, vous permettant de marcher à travers votre programme très rapidement.

+---------------------------------------------------------------------------+
B+>|0x402670 <main> push %r15 |
 |0x402672 <main+2> mov %edi,%r15d |
 |0x402675 <main+5> push %r14 |
 |0x402677 <main+7> push %r13 |
 |0x402679 <main+9> mov %rsi,%r13 |
 |0x40267c <main+12> push %r12 |
 |0x40267e <main+14> push %rbp |
 |0x40267f <main+15> push %rbx |
 |0x402680 <main+16> sub $0x438,%rsp |
 |0x402687 <main+23> mov (%rsi),%rdi |
 |0x40268a <main+26> movq $0x402a10,0x400(%rsp) |
 |0x402696 <main+38> movq $0x0,0x408(%rsp) |
 |0x4026a2 <main+50> movq $0x402510,0x410(%rsp) |
+---------------------------------------------------------------------------+
processus enfant 21518: Ligne principale: ?? PC: 0x402670
(gdb) fichier /opt/j64-602/bin/jconsole
La lecture de symboles de /opt/j64-602/bin/jconsole...fait.
(pas de symboles de débogage trouvé)...fait.
(gdb) mise en page de l'asm
(gdb) début
(gdb)

109voto

R Samuel Klatchko Points 44549

Vous pouvez utiliser stepi ou nexti (ce qui peut être abrégé en si ou ni ) pour parcourir votre code machine.

23voto

Matthew Slattery Points 21628

La chose la plus utile que vous pouvez faire ici est - display/i $pc, avant d'utiliser stepi comme l'a déjà suggéré dans la R Samuel Klatchko de réponse. Cela dit gdb pour démonter l'instruction en cours, juste avant l'impression de le demander à chaque fois; ensuite vous pouvez continuer à appuyer sur la touche Enter pour répéter l' stepi commande.

(Voir ma réponse à une autre question pour plus de détails - le contexte de cette question était différente, mais le principe est le même.)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X