xv6 debug基本方法
Debug
调试kernel代码
Console
- .gdbinit
1
2
3
4
5
61 set confirm off
2 set architecture riscv:rv64
3 target remote 127.0.0.1:26000
4 symbol-file kernel/kernel
5 set disassemble-next-line auto
6 set riscv use-compressed-breakpoints yes - make qemu-gdb : 开启gdb server
- gdb-multiarch : 连接gdb server
VsCode
- .gdbinit
1
2
3
4
5
6
71 set confirm off
2 set architecture riscv:rv64
3
4 symbol-file kernel/kernel
5
6 set disassemble-next-line auto
7 set riscv use-compressed-breakpoints yes - terminal : make qemu-gdb CPUs=1
- debug console : attach to gdbServer
调试user代码
Console
- .gdbinit
1
2
3
4
5
6
71 set confirm off
2 set architecture riscv:rv64
3 target remote 127.0.0.1:26000
4
5 symbol-file user/_ls
6 set disassemble-next-line auto
7 set riscv use-compressed-breakpoints yes
VsCode
- Step1: terminal : make qemu-gdb。
- Step2: 点击左侧按钮运行与调试,并点击左上角绿色三角(Attach to gdb)
- Step3 : debug console : interrupt
- Step5 : debug console : b *0x27a,即将断点置于ls程序入口
- Step6 : debug console : file user/_ls。加载ls的调试符号 ; then continue
- Step7 : terminal : (运行应用程序)ls
- debug console
1
2
3
4
5
6
7
8
9
10
11
12
13
14Reading symbols from /home/shc/OSLab/xv6-labs-2020/kernel/kernel...
The target architecture is assumed to be riscv:rv64
0x0000000000001000 in ?? ()
=> 0x0000000000001000: 97 02 00 00 auipc t0,0x0
**interrupt**
Thread 1 received signal SIGINT, Interrupt. scheduler () at kernel/proc.c:465 \n 465 intr_on();
**b *0x27a**
Breakpoint 1 at 0x27a
**file user/_ls**
Reading symbols from user/_ls...
**c**
Continuing.
Thread 2 hit Breakpoint 1, main (argc=0, argv=0x6c <fmtname+108>) at user/ls.c:75
75 {通过readelf确认应用程序入口点
调试系统调用 kernel -> user -> kernel
step1 : gdb client 连接 gdb server,一开始是kenrel。
step2 : 加载user文件,打断点
- file user/_ls ; break [line at user program使用的system call]
step3 : break point at (你想要调试的系统调用)(这里时fstat syscall); and then breakpoint at ecall
- bug : 按理来说这时候page table应该是user的page table,不知道为什么这里时kernel的page table ?
- b 38 ; b [at ecall] (ecall的语义类似于x86-64的syscall)
step4 : 进入trampoline (进入kenrel前的最后阶段)
break at start of trampoline
break at end of trampoline
- 如何知道trampoline最后jr t0的addr是0x3ffffff08e?
- x/40i $pc显示当前PC后面的40条汇编
- 如何知道trampoline最后jr t0的addr是0x3ffffff08e?
si从trampoline中出来。进入kernel的usertrap
- 记得file kernel/kernel 因为现在要调试kernel
- 记得file kernel/kernel 因为现在要调试kernel
step5: 成功进入kernel,接下来就是正常的调试 kernel的C code