简体   繁体   English

如何使用GDB调试jonesforth?

[英]How do I debug jonesforth with GDB?

jonesforth is typically started as follows: jonesforth通常如下所示:

cat jonesforth.f  - | ./jonesforth

What's a good way to debug jonesforth ? 调试jonesforth的好方法是jonesforth

On Ubuntu? 在Ubuntu上?

If you're on Ubuntu, allow gdb to attach to running processes: 如果您使用的是Ubuntu,请允许gdb附加到正在运行的进程:

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

Update Makefile 更新Makefile

Add the g flag to your jonesforth Makefile recipe: g标志添加到jonesforth Makefile配方中:

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

Starting gdb 启动gdb

Then, start up jonesforth as usual in a terminal: 然后,像往常一样在终端中启动jonesforth:

cat jonesforth.f - | ./jonesforth

In another terminal, start gdb and attach it to the running jonesforth: 在另一个终端中,启动gdb并将其附加到正在运行的jonesforth:

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

Sample session 示例会话

Here's what I see when I start gdb : 这是我在启动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 is waiting for us to enter something. 琼斯福斯正在等我们输入一些东西。 It's in the _KEY assembly routine. 它在_KEY汇编程序中。 This is indicated by gdb above. 这由上面的gdb表示。 It also shows that line 1290 is the next one to execute. 它还显示第1290行是下一个要执行的行。 Here's the _KEY 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 uses some variables in memory: buffer , currkey , and bufftop . _KEY在内存中使用了一些变量: buffercurrkeybufftop It also uses a couple of registers. 它还使用了几个寄存器。 Let's use gdb 's Auto Display feature to display these: 让我们使用gdbAuto Display功能来显示这些:

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

Now if we type display in gdb , we'll see all of those at once: 现在如果我们在gdb输入display ,我们会立刻看到所有这些:

(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

This might also be a good time to enable gdb 's TUI: 这也许是启用gdb的TUI的好时机:

tui enable

gdb should now look like this: gdb现在应该如下所示:

在此输入图像描述

OK, jonesforth is still waiting for input. 好的,jonesforth还在等待输入。 So let's give it something: 所以让我们给它一些东西:

JONESFORTH VERSION 47 
14499 CELLS REMAINING
OK 123

Alright, back in gdb, we can finally ask it to step: 好吧,回到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

Hey, look at that! 嘿,看那个! The first 3 characters in buffer are 1 , 2 , and 3 . 在第一3个字符buffer12 ,和3

If %eax <= 0 the next step will jump to the 2f label. 如果%eax <= 0则下一步将跳转到2f标签。 But as we can see above, %eax is 4 . 但正如我们上面所看到的, %eax4 So it should just continue on. 所以它应该继续下去。

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). 如果我们单步执行接下来的三行,则bufftop将设置为buffer的地址递增4(三个字符'123'加上一个换行符)。 The value in relation to the address of buffer checks out: buffer地址相关的值检出:

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

Now that data has been read into the input buffer, _KEY will do its job and return back to the caller. 现在数据已被读入输入缓冲区, _KEY将完成其工作并返回给调用者。 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. 当您逐步执行这些操作时,自动显示功能将相应地显示变量和寄存器更新。

我(非常有限!)的经验是,当修改汇编语言程序时,LLVM调试器lldb更加友好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM