2016-09-22 88 views

回答

3

在Ubuntu上?

如果你在Ubuntu上,允許gdb附加到正在運行的進程:

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

如果您想的是設置在重新引導:

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

更新的Makefile

g加入您的jonesforthMakefile配方:

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

啓動GDB

然後,啓動jonesforth照常在終端:

cat jonesforth.f - | ./jonesforth 

在另一個終端,啓動gdb,並將它附加到正在運行的jonesforth:

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

示例會話

這是我看到的時候我開始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等待我們進入的東西。它在_KEY彙編程序中。這由上面的gdb表示。它還表明1290行是下一個要執行的行。這裏的_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使用了一些變量存儲:buffercurrkeybufftop。它也使用了一對寄存器。讓我們用gdbAuto Display功能來顯示這些:

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

現在,如果我們輸入gdbdisplay,我們將看到所有這些在一次:

(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 

這也可能是一個好時機使gdb的TUI:

tui enable 

GDB現在應該是這樣的:

enter image description here

好的,jonesforth仍在等待輸入。因此,讓我們給它的東西:

JONESFORTH VERSION 47 
14499 CELLS REMAINING 
OK 123 

好了,回來在gdb,我們終於可以問它步驟:

(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 

嘿,看那個! buffer中的前3個字符是1,23

如果%eax <= 0下一步將跳轉到2f標籤。但是,正如我們上面看到的,%eax4。所以它應該繼續。

如果我們接下來的三行,bufftop將被設置爲buffer的地址增加4('123'的三個字符加換行符)。有關的buffer地址值檢查出:

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

現在數據已經被讀入輸入緩衝區,_KEY將完成其工作,並返回給調用者。這裏的返回之前,未來數說明:

enter image description here

當你通過這些步驟,自動顯示功能會出現的變量和寄存器相應地更新。