This page contains information regarding the debugging process: how to get more information from the compilation system, how to change the way your kernel display debug information, etc.
If the environment is too quiet for you, turn on the verbose in your user profile as follows such that the operations related to the compilation and linking process are displayed in detail.
_OUTPUT_ = ${_OUTPUT_VERBOSE_}
Sometimes, kaneton needs to display so much information that the 80x25 screen is not enough to contain. This often happens in critical times when you need debug information for instance.
An easy way to get more output is to forward the kaneton console output to another machine over a serial line. Although this might sound complicated for real machines, this techniques becomes very easy and efficient with emulatorss such as QEMU.
In order to activate the forward module, you will need to add the forward
module by adding the following to your user profile configuration file:
_MODULES_ += forward
Once your kaneton has been recompiled, you can use QEMU to redirect the data received on serial line to the standard console, as shown below:
$> qemu-system-i386 -serial stdio -fda [path-to-your-kaneton-image]
That way, QEMU will be launched as usual but every displayed text will be forwarded by kaneton to the serial line, hence displayed on the console output by QEMU.
Interrupts can be used for debugging as well. For instance, whenever a page fault occurs, the default page fault interrupt handler displays information on the context such as registers etc.
However, depending on the specificity of the situation, one might want to display additional debug information such as the state of the page directory and page tables involved in the error.
Students should make the best of the interrupt handlers in order to speed up the debugging process.
The glue component sets up a default page fault handler which can be modified for example.
Qemu implements gdb stubs to debug the software it runs.
$> qemu-system-i386 -fda kaneton.img -s -S
-s
: shortcut option (for -gdb tcp::1234) to make qemu's gdbserver wait for a connection on port 1234 of the local machine.-S
: freeze the CPU at startup so that it can be started from the debugger (or by typing c
on qemu's console).When facing tough kernel crashes, it is possible to ask qemu to log in /tmp/qemu.log details about the kernel execution on the emulated machine. -d item{,item}*
option turns on the logging of the given items. Use -d ?
to list every logging options of qemu. The most useful are :
in_asm
: log every block of your kernel assembly code being executed by qemu.int
: log interrupts/exceptions in short format.$> qemu-system-i386 -fda kaneton.img -s -S -d in_asm,cpu
Note that the file grows fastly (several MB/s).
Having logs for each executed block of assembly code can be not granular enough to understand a kernel crash. Turn on the single stepping mode (option -singlestep
) to make qemu execute your kernel instruction per instruction. So that you obtain the logs for each single instruction. E.g.: to log the registers for each instruction executed, use:
$> qemu-system-i386 -fda kaneton.img -s -S -d in_asm,cpu -singlestep
It is advised to ask qemu to use linux's KVM module to make it execute most of your kernel code directly on your host machine. Therefore avoiding as much as possible qemu's emulation mistakes.
$> qemu-system-i386 -enable-kvm -fda kaneton.img -s -S
or
$> qemu-kvm -fda kaneton.img -s -S
You can still get more information from the console. Type Alt-2
in graphical mode or C-q c
otherwise to get the console.
Type info
to get the list of informations qemu can give you. E.g.:
Type help
to get the list of commands. E.g.:
The list of possible arguments of a qemu's option is returned when providing it ?
argument.
$> qemu-system-i386 -enable-kvm -fda kaneton.img -s -S -d ?
Log items (comma separated):
out_asm show generated host assembly code for each compiled TB
in_asm show target assembly code for each compiled TB
...
Once qemu is waiting for your gdb connection, simply launch gdb, read the symbols from the ELF file (having compiled with the debug options), connect to the target, and start debugging as usual. E.g.:
$> qemu-system-i386 -enable-kvm -fda kaneton.img -s -S &
$> gdb kaneton -tui
(gdb) target remote :1234
(gdb) b architecture_pt_map
(gdb) c
watch
, rwatch
, awatch
).-x
option (gdb -x test
).break if $eax == 0x33
).break myfunction
command
set myvar = myvalue
p "Hello"
end