Guidance¶
首先介绍难度分层:
- Easy: <1h, These exercise are typically often warm-up exercises for subsequent exercises.
- Moderate: 1-2h
- Hard: >2h, Often these exercises don't require much code, but the code is tricky to get right.
Debugging Tips¶
Pointers¶
确保自己的C语言和pointers学得比较好.
#include <stdio.h>
#include <stdlib.h>
void
f(void)
{
int a[4];
int *b = malloc(16);
int *c;
int i;
printf("1: a = %p, b = %p, c = %p\n", a, b, c);
c = a;
for (i = 0; i < 4; i++)
a[i] = 100 + i;
c[0] = 200;
printf("2: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);
c[1] = 300;
*(c + 2) = 301;
3[c] = 302;
printf("3: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);
c = c + 1;
*c = 400;
printf("4: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);
c = (int *) ((char *) c + 1);
*c = 500;
printf("5: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);
b = (int *) a + 1;
c = (int *) ((char *) a + 1);
printf("6: a = %p, b = %p, c = %p\n", a, b, c);
}
int
main(int ac, char **av)
{
f();
return 0;
}
编译并运行:
guidance$ gcc -o p ptr_exer.c
guidance$ ./p
1: a = 0x7ffefa9e3980, b = 0x5f2e932c42a0, c = (nil)
2: a[0] = 200, a[1] = 101, a[2] = 102, a[3] = 103
3: a[0] = 200, a[1] = 300, a[2] = 301, a[3] = 302
4: a[0] = 200, a[1] = 400, a[2] = 301, a[3] = 302
5: a[0] = 200, a[1] = 128144, a[2] = 256, a[3] = 302
6: a = 0x7ffefa9e3980, b = 0x7ffefa9e3984, c = 0x7ffefa9e3981
Git¶
一部分完成之后,建议Git存个档,也方便后续回滚.
Make¶
在script内部运行make qemu指令观察输出.
gdb调试¶
打开一个窗口:
打开另一个窗口:
信息查看¶
- If you want to see what the assembly is that the compiler generates for the kernel or to find out what the instruction is at a particular kernel address, see the file
kernel.asm, which the Makefile produces when it compiles the kernel. (The Makefile also produces.asmfor all user programs.)- If the kernel panics, it will print an error message listing the value of the program counter when it crashed; you can search
kernel.asmto find out in which function the program counter was when it crashed, or you can run addr2line -e kernel/kernel pc-value (run man addr2line for details). If you want to get backtrace, restart using gdb: run 'make qemu-gdb' in one window, run gdb (or riscv64-linux-gnu-gdb) in another window, set breakpoint in panic ('b panic'), followed by followed by 'c' (continue). When the kernel hits the break point, type 'bt' to get a backtrace.- If your kernel hangs (e.g., due to a deadlock) or cannot execute further (e.g., due to a page fault when executing a kernel instruction), you can use gdb to find out where it is hanging. Run run
make qemu-gdbin one window, run gdb (riscv64-linux-gnu-gdb) in another window, followed by followed byc(continue). When the kernel appears to hang hitCtrl-Cin the qemu-gdb window and typebtto get a backtrace.qemuhas a "monitor" that lets you query the state of the emulated machine. You can get at it by typing control-a c (the "c" is for console). A particularly useful monitor command isinfo memto print the page table. You may need to use thecpucommand to select which coreinfo memlooks at, or you could start qemu withmake CPUS=1 qemuto cause there to be just one core.
kernel¶
查看kernel.asm可以得到内核崩溃信息,如在哪个函数崩溃.
monitor¶
获取每个monitor的状态: