2016-09-22 59 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

当你通过这些步骤,自动显示功能会出现的变量和寄存器相应地更新。