我认为有一种方法可以调试未使用调试器标志编译的内核。我想用下面的例子来解释一下。
(gdb) disassemble
Dump of assembler code for function mystrcpy:
0x0804852a <+0>: push %ebp
0x0804852b <+1>: mov %esp,%ebp
0x0804852d <+3>: sub $0x10,%esp
0x08048530 <+6>: mov 0x8(%ebp),%eax
0x08048533 <+9>: mov %eax,-0x4(%ebp)
0x08048536 <+12>: jmp 0x8048540 <mystrcpy+22>
0x08048538 <+14>: addl $0x1,0xc(%ebp)
0x0804853c <+18>: addl $0x1,0x8(%ebp)
0x08048540 <+22>: mov 0xc(%ebp),%eax
0x08048543 <+25>: movzbl (%eax),%edx
0x08048546 <+28>: mov 0x8(%ebp),%eax
=> 0x08048549 <+31>: mov %dl,(%eax)
0x0804854b <+33>: mov 0x8(%ebp),%eax
0x0804854e <+36>: movzbl (%eax),%eax
0x08048551 <+39>: test %al,%al
0x08048553 <+41>: jne
0x8048538 <mystrcpy+14>
0x08048555 <+43>: mov -0x4(%ebp),%eax
0x08048558 <+46>: leave
0x08048559 <+47>:
ret End of assembler dump.
现在,实际显示“=>”符号的行是罪魁祸首。(=> 0x08048549 : mov %dl,(%eax))
我们可以使用 gdb 命令来找出显示问题的行发生了什么。
gdb) print $eax //print command
$1 = 0
(gdb) print $dl
$2 = 118
(gdb) print/c $dl
$3 = 118 'v‘
(gdb) info frame //info frame command
Stack level 0, frame at 0xffbf8b90: eip = 0x8048549 in mystrcpy; saved eip = 0x80485cd called by frame at 0xffbf8bc0 Arglist at 0xffbf8b88, args: Locals at 0xffbf8b88, Previous frame's sp is 0xffbf8b90 Saved registers: ebp at 0xffbf8b88, eip at 0xffbf8b8c
(gdb) x/x $ebp+4 //base pointer + 4
0xffbf8b8c: 0x080485cd
(gdb) info symbol 0x080485cd //info symbol command
connect + 115 in section .text of /home/vmahajan/a.out
(gdb) x/x $ebp+4
0xffbf8b8c: 0x080485cd
(gdb) x/x $ebp+8
0xffbf8b90: 0x00000000
(gdb) x/x $ebp+12
0xffbf8b94: 0xffbf91f3
(gdb) print/s (char *)0xffbf91f3
$5 = 0xffbf91f3 "vishal“