Linux Modules Character drivers IO & Memory Linux Kernel Process Management Process Address space Linux Scheduler Memory Management Interrupts Signals System Calls Kernel Synchronization Linux Inter Process Communications Serial Ports Parallel Ports Introduction to Hardware Linux Timers DMA in Linux Linux Threads Linux Thread Synchronization Linux Multi Threading Debugging in Linux GDB GNU Debugger KDB Kernel Debugger KGDB Kernel GNU Debugger Example Ethernet Driver |
The kdb Kernel Debugger The kernel developers occasionally use interactive debugging tools. One such tool is the kdbbuilt-in kernel debugger, available as a nonofficial patch from oss.sgi.com. To use kdb, you must obtain the patch (be sure to get a version that matches your kernel version), apply it, and rebuild and reinstall the kernel. One you are running a kdb-enabled kernel, there are couple of ways to enter the debugger. Hitting the Pause (or Break) key on the console will start up the debugger. kdbalso starts up when a kernel oops happens, or when a breakpoint is hit. You will see a message that looks something like this: Entering kdb(0xc1278000) on processor 1 due to Keyboard Entry [1]kdb> Getting and Installing KDB KDB patches for Linux are available from ftp://oss.sgi.com/www/projects/kdb/download/ix86/ ü Download the kernel patch required for your kernel version. ü Copy unzipped patch file to Linux source code directory. ü Apply the patch -# patch -p1 < patch file name. ü Do kernel configuration -# make config / menuconfig / xconfig ü Enable CONFIG_KDB, CONFIG_FRAME_POINTER, Disable CONFIG_KDB_OFF in kernel hacking section ü Build the image with #make ü Install modules –#make modules_install ü Install kernel -#make install ü Press pause/break key to enter debug mode. md <VADDR> Display memory contents-> Addr HEX ASCII (8Lx4xDW) mdr <VADDR> <BYTES> Display Raw memory -> HEX only(no CR/CF) mds <VADDR> Display memory symbolically -> Addr HEX ASCII(8LxDW) mm <VADDR> <CONTENTS> modify Memory content -> modify 1 DW only. id <VADDR> Display instructions -> Interprets the contents as machine language and prints DIS ASM code (16 Instr) go [<VADRR>] Continue execution rd Display registers. ->Displays the contents of the registers EAX,EBX,ECX,EDX,ESI,EDI,ESP,EIP,EBP,XSS,XCS, EFCAGS,XDS,XES,ORIGEAX=oxFFFFFF01 rm <REG> <CONTENT> Modify registers. Ef display exception frame bt [<VADDR>] Stack traceback EBP, EIP, Functions (args) btp <pid> Display stack for process<pid> bta Display stack all process. env Show
environment variables (PROMPT,MORPROMPT,RADIX, LINES, COLUMNS, BYTESPERWORD,MDCOUNT, BTARGS, SSCOUNT,IDMODE, IDCOUNT) set Set environment variables help Display help message. ? Display help message cpu <CPUNUM> Switch to new CPU. Ps Display active task list. reboot Reboot the machine immediately (proper shutting down will not be done) lsmod List loaded kernel modules. rmmod <modname> Remove a kernel module. bp [<VADDR>] Set/Display breakpoints. bl [<VADDR>] Display breakpoints. bpa [<VADDR>] Set/Display global break points. bph [<VADDR>] Set hardware break points. bpha [<VADDR>] Set global hardware break points. bc <bpnum> clear break point. be <bpnum> Enable break point. bd <bpnum> Disable break point . ss [<#steps>] Single step. ssb Single step to branch/ call. Break points A break point makes your program stop whenever a certain point in the program is reached. bp [<VADDR>] Set/Display breakpoints. bl [<VADDR>] Display breakpoints. bpa [<VADDR>] Set/Display global break points. bph [<VADDR>] Set hardware break points. bpha [<VADDR>] Set global hardware break points. bc <bpnum> clear break point. be <bpnum> Enable break point. bd <bpnum> Disable break point . Continuing/Stepping go [<VADRR>] Continue execution ss [<#steps>] Single step Ssb Single step to branch/ call To execute instructions until it encounters a branch
condition (in this case, instruction jne): [0]kdb> ssb 0xc0105355 default_idle+0x25: cli 0xc0105356
default_idle+0x26: mov0x14(%edx),%eax 0xc0105359
default_idle+0x29: test %eax, %eax 0xc010535b default_idle+0x2b: jne0xc0105361
default_idle+0x31 Backtraces A backtrace is a summary of how your program got where it is. It shows one line per frame, for many frames, starting with the currently executing frame(frame 0), followed by its caller(frame 1), and on up the stack. ef Display exception frame bt [<VADDR>] Stack tracebackEBP, EIP, Functions (args) btp <pid> Display stack for process <pid> bta Display stack all process. Examining Memory md <VADDR> Display memory contents-> AddrHEX ASCII (8Lx4xDW) mdr <VADDR> <BYTES> Display Raw memory -> HEX only(no CR/CF) mds <VADDR> Display memory symbolically -> AddrHEX ASCII(8LxDW) mm <VADDR> <CONTENTS> modify Memory content -> modify 1 DW only. Examples To display 15 lines of memory starting at 0xc000000: [0]kdb>
md0xc000000 15 To change the contents of memory location 0xc000000 to 0x10: [0]kdb>
mm 0xc000000 0x10 Registers rd Display registers ->Displays the contents of the registers EAX,EBX,ECX,EDX,ESI,EDI,ESP,EIP,EBP,XSS,XCS, EFCAGS,XDS,XES,ORIGEAX=oxFFFFFF01 rm <REG> <CONTENT> Modify registers. Examples To display the general register set: [0]kdb>
rd To set the contents of register ebxto 0x25: [0]kdb>
rm%ebx0x25 Display instructions id <VADDR> Display instructions -> Interprets the contents as machine language and prints DIS ASM code (16 Instr) Examples To disassemble instructions starting from the routine schedule The number of lines displayed depends on the environment variable IDCOUNT: [0]kdb>
id schedule Tip #1 In KDB, typing an address at the prompt returns its nearest symbol match. This is extremely useful in stack analysis and in determining the addresses/values of global data and function addresses. Similarly, typing the name of a symbol returns its virtual address. Examples To indicate that the function sys_readstarts at address 0xc013db4c: [0]kdb>
0xc013db4c 0xc013db4c
= 0xc013db4c (sys_read) Similarly, to indicate that sys_writeis at address 0xc013dcc8: [0]kdb>
sys_write sys_write=
0xc013dcc8 (sys_write) Tip #2 The bph and bpha commands can be used (provided the architecture supports use of hardware registers) to apply read and write breakpoints. This means we can get control whenever data is read from or written into a particular address. This can be extremely handy when debugging data/memory corruption problems, where you can use it to identify the corrupting code/process. Examples To enter the kernel debugger whenever four bytes are written into address 0xc0204060: [0]kdb>
bph0xc0204060 dataw4 To enter the kernel debugger when at least two bytes of data starting at 0xc000000 are read: [0]kdb>
bph0xc000000 datar 2 |