2016-09-22 3 views

Répondre

3

Sur Ubuntu?

Si vous êtes sur Ubuntu, permettent gdb d'attacher aux processus en cours d'exécution:

echo 0 > /proc/sys/kernel/yama/ptrace_scope 

Si vous souhaitez que l'établissement de rester entre les redémarrages:

vim /etc/sysctl.d/10-ptrace.conf 

Mise à jour Makefile

Ajouter le drapeau g à votre jonesforthMakefile recette:

jonesforth: jonesforth.S 
    gcc -g -m32 -nostdlib -static $(BUILD_ID_NONE) -o [email protected] $< 

gdb À partir

Ensuite, démarrez jonesforth comme d'habitude dans un terminal:

cat jonesforth.f - | ./jonesforth 

Dans un autre terminal, commencez gdb et l'attacher à la jonesforth en cours d'exécution:

gdb --quiet --pid=`pgrep jonesforth` ./jonesforth 

Exemple de session

Voici ce que je vois quand je commence gdb:

$ gdb --quiet --pid=`pgrep jonesforth` ./jonesforth 
Reading symbols from ./jonesforth...done. 
Attaching to program: /home/dharmatech/Dropbox/Documents/jonesforth-annexia/jonesforth, process 3406 
_KEY() at jonesforth.S:1290 
1290  test %eax,%eax  // If %eax <= 0, then exit. 
(gdb) 

Jonesforth nous attend d'entrer quelque chose. C'est dans la routine d'assemblage _KEY. Ceci est indiqué par gdb ci-dessus. Il montre également que la ligne 1290 est la suivante à exécuter. Voici la routine _KEY:

_KEY: 
    mov (currkey),%ebx 
    cmp (bufftop),%ebx 
    jge 1f   // exhausted the input buffer? 
    xor %eax,%eax 
    mov (%ebx),%al  // get next key from input buffer 
    inc %ebx 
    mov %ebx,(currkey) // increment currkey 
    ret 

1: // Out of input; use read(2) to fetch more input from stdin. 
    xor %ebx,%ebx  // 1st param: stdin 
    mov $buffer,%ecx // 2nd param: buffer 
    mov %ecx,currkey 
    mov $BUFFER_SIZE,%edx // 3rd param: max length 
    mov $__NR_read,%eax // syscall: read 
    int $0x80 
    test %eax,%eax  // If %eax <= 0, then exit. 
    jbe 2f 
    addl %eax,%ecx  // buffer+%eax = bufftop 
    mov %ecx,bufftop 
    jmp _KEY 

2: // Error or end of input: exit the program. 
    xor %ebx,%ebx 
    mov $__NR_exit,%eax // syscall: exit 
    int $0x80 

_KEY utilise des variables en mémoire: buffer, currkey et bufftop. Il utilise également quelques registres. Utilisons fonction de Auto Displaygdb pour afficher celles-ci:

display/8cb &buffer 
display/1xw &currkey 
display/1xw &bufftop 
display/x $eax 
display/x $ebx 

Maintenant, si nous tapons display à gdb, nous verrons tous ceux à la fois:

(gdb) display 
1: x/8cb &buffer 
0x804c000: 97 'a' 98 'b' 108 'l' 121 'y' 46 '.' 32 ' ' 32 ' ' 84 'T' 
2: x/xw &currkey 0x8049d54: 0x0804c000 
3: x/xw &bufftop 0x8049d58: 0x0804c7e3 
4: /x $eax = 0xfffffe00 
5: /x $ebx = 0x0 

Cela pourrait être aussi un bon moment pour permettre la TUI « gdb:

tui enable 

gdb devrait ressembler à ceci:

enter image description here

OK, jonesforth attend toujours l'entrée.Donc, nous allons lui donner quelque chose:

JONESFORTH VERSION 47 
14499 CELLS REMAINING 
OK 123 

Bon, retour à gdb, on peut enfin demander à l'étape:

(gdb) s 
1: x/8cb &buffer 
0x804c000:  49 '1' 50 '2' 51 '3' 10 '\n' 46 '.' 32 ' ' 32 ' ' 84 'T' 
2: x/xw &currkey 0x8049d54: 0x0804c000 
3: x/xw &bufftop 0x8049d58: 0x0804c7e3 
4: /x $eax = 0x4 
5: /x $ebx = 0x0 

Hé, regardez ça! Les 3 premiers caractères de buffer sont 1, 2 et 3.

Si %eax <= 0, l'étape suivante passera à l'étiquette 2f. Mais comme nous pouvons le voir ci-dessus, %eax est 4. Cela devrait donc continuer.

Si nous franchissons les trois lignes suivantes, le bufftop sera défini sur l'adresse buffer incrémentée de 4 (trois caractères de '123' plus un caractère de nouvelle ligne). La valeur par rapport à l'adresse de buffer vérifie:

3: x/xw &bufftop 0x8049d58: 0x0804c004 

Maintenant que les données ont été lues dans le tampon d'entrée, _KEY fera son travail et revenir à l'appelant. Voici les instructions PROCHAINS avant le retour:

enter image description here

Comme vous l'étape par ceux-ci, la fonction d'affichage automatique affiche les variables et la mise à jour des registres en conséquence.