如何使用GDB调试jonesforth? [英] How do I debug jonesforth with GDB?
问题描述
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
在内存中使用一些变量:buffer
,currkey
和bufftop
.它还使用了两个寄存器.让我们使用gdb
的Auto 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
中的前三个字符是1
,2
和3
.
Hey, look at that! The first 3 characters in buffer
are 1
, 2
, and 3
.
如果%eax <= 0
,下一步将跳至2f
标签.但是正如我们在上面看到的,%eax
是4
.因此,应该继续进行下去.
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屋!