如何使用GDB调试jonesforth? [英] How do I debug jonesforth with GDB?

查看:131
本文介绍了如何使用GDB调试jonesforth?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

jonesforth通常以如下方式启动:

jonesforth is typically started as follows:

cat jonesforth.f  - | ./jonesforth

什么是调试jonesforth的好方法?

推荐答案

在Ubuntu上?

如果您使用的是Ubuntu,请允许gdb附加到正在运行的进程:

On Ubuntu?

If you're on Ubuntu, allow gdb to attach to running processes:

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

如果您希望该设置在重新启动后保持不变:

If you'd like that setting to remain across reboots:

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

更新Makefile

在您的jonesforth Makefile配方中添加g标志:

Update Makefile

Add the g flag to your jonesforth Makefile recipe:

jonesforth: jonesforth.S
    gcc -g -m32 -nostdlib -static $(BUILD_ID_NONE) -o $@ $<

启动gdb

然后,像往常一样在终端中启动jonesforth:

Starting gdb

Then, start up jonesforth as usual in a terminal:

cat jonesforth.f - | ./jonesforth

在另一个终端中,启动gdb并将其附加到正在运行的jonesforth:

In another terminal, start gdb and attach it to the running jonesforth:

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

示例会话

这是我开始gdb时看到的内容:

Sample session

Here's what I see when I start 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例程:

Jonesforth is waiting for us to enter something. It's in the _KEY assembly routine. This is indicated by gdb above. It also shows that line 1290 is the next one to execute. Here's the _KEY routine:

_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功能来显示这些内容:

_KEY uses some variables in memory: buffer, currkey, and bufftop. It also uses a couple of registers. Let's use gdb's Auto Display feature to display these:

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

现在,如果我们在gdb中键入display,我们将一次看到所有这些内容:

Now if we type display in gdb, we'll see all of those at once:

(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的好时机:

This might also be a good time to enable gdb's TUI:

tui enable

gdb现在应如下所示:

gdb should now look like this:

好的,jonesforth仍在等待输入.因此,让我们给它一些东西:

OK, jonesforth is still waiting for input. So let's give it something:

JONESFORTH VERSION 47 
14499 CELLS REMAINING
OK 123

好吧,回到gdb中,我们终于可以要求它执行以下操作了:

Alright, back in gdb, we can finally ask it to step:

(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中的前三个字符是123.

Hey, look at that! The first 3 characters in buffer are 1, 2, and 3.

如果%eax <= 0,下一步将跳至2f标签.但是正如我们在上面看到的,%eax4.因此,应该继续进行下去.

If %eax <= 0 the next step will jump to the 2f label. But as we can see above, %eax is 4. So it should just continue on.

如果我们浏览接下来的三行,则bufftop将设置为buffer的地址,该地址递增4(三个字符"123"加换行符).与buffer地址有关的值检出:

If we step through the next three lines, the bufftop will be set to the address of buffer incremented by 4 (three characters of '123' plus a newline character). The value in relation to the address of buffer checks out:

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

现在,数据已被读入输入缓冲区,_KEY将完成其工作并返回给调用方.这是返回前的以下几条说明:

Now that data has been read into the input buffer, _KEY will do its job and return back to the caller. Here's the next few instructions before the return:

逐步浏览时,自动显示功能将显示变量并相应地更新寄存器.

As you step through those, the auto display feature will show the variables and registers updating accordingly.

这篇关于如何使用GDB调试jonesforth?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆