summaryrefslogtreecommitdiff
path: root/kernel-devel/kernel-debugging
diff options
context:
space:
mode:
authorJan Altenberg <jan@linutronix.de>2011-02-10 11:37:06 +0100
committerJan Altenberg <jan@linutronix.de>2011-02-10 11:37:06 +0100
commitb1934fb29ed318cab4d9ed5aa5d18e84440d96f8 (patch)
treed6183ac5f35aa4abdda878457ccf9b3f686ee1cc /kernel-devel/kernel-debugging
parent5c90abcf73cccc9247e935c83807f2293ebb8fb7 (diff)
First version of a kernel debugging chapter.
Currently covers basic information about: - printk - Serial Console / Net Console - Oops / addr2line - ftrace / ftrace_dump_on_oops - Qemu gdbserver interface - KGDB - User Mode Linux
Diffstat (limited to 'kernel-devel/kernel-debugging')
-rw-r--r--kernel-devel/kernel-debugging/Makefile9
-rw-r--r--kernel-devel/kernel-debugging/pres_kernel-debugging_en.tex356
2 files changed, 365 insertions, 0 deletions
diff --git a/kernel-devel/kernel-debugging/Makefile b/kernel-devel/kernel-debugging/Makefile
new file mode 100644
index 0000000..d641258
--- /dev/null
+++ b/kernel-devel/kernel-debugging/Makefile
@@ -0,0 +1,9 @@
+all:
+ for pdf in `ls -1 *.tex` ; do \
+ TEXINPUTS=`pwd`/../..:.:..:$(TEXINPUTS) pdflatex $$pdf; \
+ TEXINPUTS=`pwd`/../..:.:..:$(TEXINPUTS) pdflatex $$pdf; \
+ done
+
+clean:
+ rm -f *.aux *.log *.pdf *.log *.snm *.toc *.vrb *.nav *.out
+
diff --git a/kernel-devel/kernel-debugging/pres_kernel-debugging_en.tex b/kernel-devel/kernel-debugging/pres_kernel-debugging_en.tex
new file mode 100644
index 0000000..f875368
--- /dev/null
+++ b/kernel-devel/kernel-debugging/pres_kernel-debugging_en.tex
@@ -0,0 +1,356 @@
+\input{configpres}
+
+\title{Kernel-Debugging}
+\maketitle
+\section{printk}
+\begin{frame}[fragile]
+\frametitle{printk is your friend!!}
+Usage is similar to printf() in userspace. Different loglevels:
+\small
+\begin{verbatim}
+KERN_EMERG "<0>" /* system is unusable */
+KERN_ALERT "<1>" /* action must be taken immediately */
+KERN_CRIT "<2>" /* critical conditions */
+KERN_ERR "<3>" /* error conditions */
+KERN_WARNING "<4>" /* warning conditions */
+KERN_NOTICE "<5>" /* normal but significant condition */
+KERN_INFO "<6>" /* informational */
+KERN_DEBUG "<7>" /* debug-level messages */
+\end{verbatim}
+\end{frame}
+
+\section{printk}
+\begin{frame}[fragile]
+\frametitle{Example}
+\begin{verbatim}
+printk(KERN_EMERG "Fatal error!\n");
+\end{verbatim}
+Setting the loglevel via kernel commandline:
+\begin{verbatim}
+loglevel=7
+\end{verbatim}
+Loglevel in procfs:
+\begin{verbatim}
+# console_loglevel, default_message_loglevel,
+# minimum_console_level and default_console_loglevel
+$ cat /proc/sys/kernel/printk
+4 4 1 7
+\end{verbatim}
+\end{frame}
+
+\section{Logging messages}
+\begin{frame}[fragile]
+\frametitle{Serial Console}
+Kernel configuration (example):
+\begin{verbatim}
+Device Drivers --->
+Character devices --->
+Serial drivers --->
+[*] Console on 8250/16550 and
+ compatible serial port
+\end{verbatim}
+Kernel commandline (examples)
+\begin{verbatim}
+console=ttyS0,115200
+\end{verbatim}
+\begin{verbatim}
+console=ttyS0,115200n8
+\end{verbatim}
+\begin{verbatim}
+console=ttyAM0,115200
+\end{verbatim}
+\end{frame}
+
+\begin{frame}[fragile]
+\frametitle{Netconsole}
+Kernel commandline:
+\begin{verbatim}
+netconsole=[src-port]@[src-ip]/[<dev>],
+ [tgt-port]@<tgt-ip>/[tgt-macaddr]
+\end{verbatim}
+src-port defaults to 6665. tgt-port defaults to 6666.
+\begin{verbatim}
+netconsole=@/,@10.10.0.2/
+\end{verbatim}
+On the host side:
+\begin{verbatim}
+$ nc -l -u -p 6666
+# or (depending on your netcat version)
+$ nc -l -u 6666
+\end{verbatim}
+\end{frame}
+
+\section{Analyzing Backtraces}
+\begin{frame}[fragile]
+\frametitle{Oops...Something went wrong ;-)}
+Note: PC is at c0009378
+\tiny
+\begin{verbatim}
+CPU: 0 Not tainted (2.6.37 #9)
+PC is at prepare_namespace+0x170/0x1d4
+LR is at do_unlinkat+0x10c/0x14c
+pc : [<c0009378>] lr : [<c00df338>] psr: 80000013
+sp : c783dfc8 ip : c783df20 fp : c783dfe0
+r10: 00000000 r9 : 00000000 r8 : 00000000
+r7 : 00000013 r6 : c0054a1c r5 : c0022995 r4 : c03969a4
+r3 : 00000000 r2 : 00000000 r1 : c78c7000 r0 : 00000000
+Flags: Nzcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel
+Control: 00093177 Table: 00004000 DAC: 00000017
+Process swapper (pid: 1, stack limit = 0xc783c260)
+Stack: (0xc783dfc8 to 0xc783e000)
+dfc0: c783dfd4 c0396940 c00084fc c783dff4 c783dfe4 c0008610
+dfe0: c0009214 00000000 00000000 c783dff8 c0054a1c c0008508 00000000 00000000
+Backtrace:
+[<c0009208>] (prepare_namespace+0x0/0x1d4) from [<c0008610>] (kernel_init+0x114/0x154)
+ r5:c00084fc r4:c0396940
+[<c00084fc>] (kernel_init+0x0/0x154) from [<c0054a1c>] (do_exit+0x0/0x660)
+ r4:00000000
+Code: e3500000 13a03601 15843000 e3a03000 (e5d31000)
+---[ end trace 4ed5c061b76895d8 ]---
+\end{verbatim}
+\end{frame}
+
+\begin{frame}[fragile]
+\frametitle{Analyzing Backtraces: addr2line}
+If you compiled your kernel with debug info, you can use addr2line to decode
+the address:
+\small
+\begin{verbatim}
+$ arm-none-linux-gnueabi-addr2line -e vmlinux c0009378
+linux-2.6.37/init/do_mounts.c:488
+\end{verbatim}
+\end{frame}
+
+\section{Debugging early crashes}
+\begin{frame}[fragile]
+\frametitle{Early printk}
+\begin{verbatim}
+Kernel hacking --->
+[*] Kernel low-level debugging functions
+[*] Early printk
+\end{verbatim}
+\begin{verbatim}
+earlyprintk=serial,ttyAMA0,115200,keep \
+console=ttyAMA0,115200
+\end{verbatim}
+\end{frame}
+
+\section{Magic SysRQ}
+\begin{frame}
+\frametitle{Magic Sysrequest Keys}
+Sysrequest (Alt-Print) or break signal (via serial console)
+followed by a specific key:
+\begin{itemize}
+\item t: Show task states
+\item p: Show registers
+\item q: Show all timers
+\item b: Force reboot
+\item e: Terminate all tasks
+\item l: Show backtrace of all active CPUs
+\item s: Sync
+\item h: Help
+\end{itemize}
+\end{frame}
+
+\section{ftrace}
+
+\begin{frame}[fragile]
+\frametitle{trace\_printk()}
+\begin{itemize}
+\item Writes to the tracing ring buffer
+\item Can be used in any context
+\item Useful for debugging ''high volume areas''
+\item Syntax similar to printk():
+\begin{verbatim}
+trace_printk("my_var -> %d\n", my_var);
+\end{verbatim}
+\end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]
+\frametitle{ftrace\_dump\_on\_oops}
+Example:
+\begin{verbatim}
+# Kernel Commandline:
+ftrace=sched_switch ftrace_dump_on_oops
+\end{verbatim}
+\tiny
+\begin{verbatim}
+Unable to handle kernel NULL pointer dereference at virtual address 00000000
+pgd = c0004000
+[00000000] *pgd=00000000
+Internal error: Oops: 35 [#1]
+last sysfs file:
+Dumping ftrace buffer:
+---------------------------------
+ swapper-1 0dN... 9034us : 1:120:R + [000] 2:120:S kthreadd
+ swapper-1 0..... 10044us : 1:120:D ==> [000] 2:120:R kthreadd
+kthreadd-2 0d.... 10529us : 2:120:R + [000] 15:120:R kswapd0
+kthreadd-2 0..... 10577us : 2:120:S ==> [000] 14:120:R kworker/0:1
+kworker/-14 0d.... 10623us : 14:120:D + [000] 4:120:D kworker/0:0
+kworker/-14 0..... 10656us : 14:120:D ==> [000] 4:120:R kworker/0:0
+kworker/-4 0d.... 10848us : 4:120:R + [000] 14:120:D kworker/0:1
+kworker/-4 0..... 11943us : 4:120:S ==> [000] 14:120:R kworker/0:1
+kworker/-14 0..... 12004us : 14:120:S ==> [000] 15:120:R kswapd0
+[...]
+\end{verbatim}
+\end{frame}
+
+\section{Qemu}
+\begin{frame}[fragile]
+\frametitle{Kerneldebugging with Qemu}
+\begin{verbatim}
+$ qemu-system-arm -M versatilepb -m 128 \
+-S -s -kernel zImage
+\end{verbatim}
+\begin{verbatim}
+$ arm-none-linux-gnueabi-gdb vmlinux
+(gdb) target remote localhost:1234
+Remote debugging using localhost:1234
+0x00000000 in ?? ()
+(gdb) break start_kernel
+(gdb) c
+Continuing.
+
+Breakpoint 1, start_kernel ()
+ at linux-2.6.37-rc4/init/main.c:539
+539 smp_setup_processor_id();
+\end{verbatim}
+\end{frame}
+
+\section{KGDB}
+\begin{frame}
+\frametitle{KGDB}
+\begin{itemize}
+\item KDB: Simplistic shell style interface: Inspect registers, process list, ...
+\item KGDB: Source-level debugging
+\end{itemize}
+\end{frame}
+
+\begin{frame}
+\frametitle{KDB}
+\begin{itemize}
+\item NOT a source level debugger!!
+\item Enter KDB with SysRQ-g: echo g $>$ /proc/sysrq-trigger
+\end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]
+\frametitle{KGDB}
+Kernel configuration:
+\begin{verbatim}
+Kernel hacking --->
+[*] KGDB: kernel debugging with remote gdb --->
+<*> KGDB: use kgdb over the serial console (NEW)
+\end{verbatim}
+Kernel Commandline:
+\begin{verbatim}
+kgdboc=ttyAMA0 kgdbwait
+\end{verbatim}
+\end{frame}
+
+\begin{frame}[fragile]
+\frametitle{KGDB}
+1)\\
+\begin{verbatim}
+qemu-system-arm -M versatilepb -m 128 \
+ -serial tcp:localhost:2345,server \
+ -kernel zImage -append "kgdboc=ttyAMA0 kgdbwait"
+\end{verbatim}
+2)\\
+telnet localhost 2345\\
+\begin{verbatim}
+kgdb: Wait for connection from remote gdb...
+\end{verbatim}
+CTRL-]
+quit
+\end{frame}
+
+\begin{frame}[fragile]
+\frametitle{KGDB}
+3)\\
+\begin{verbatim}
+arm-none-linux-gnueabi-gdb vmlinux
+(gdb) target remote localhost:2345
+Remote debugging using localhost:2345
+
+kgdb_breakpoint ()
+ at linux-2.6.37-rc4/kernel/debug/debug_core.c:959
+959 arch_kgdb_breakpoint();
+(gdb)
+\end{verbatim}
+\end{frame}
+
+\section{User Mode Linux}
+\begin{frame}
+\frametitle{UML: User Mode Linux}
+\begin{alertblock}{What is User Mode Linux?}
+User Mode Linux allows you to run the Linux kernel as a normal userspace
+process.
+\end{alertblock}
+\end{frame}
+
+\begin{frame}[fragile]
+\frametitle{UML: Build and boot a UML kernel}
+\begin{lstlisting}[language=bash]
+$ make ARCH=um defconfig
+$ make ARCH=um
+$ file linux
+ linux: ELF 32-bit LSB executable, Intel 80386,
+ version 1 (SYSV), dynamically linked (uses shared libs),
+ for GNU/Linux 2.6.8, not stripped
+$ ./linux
+\end{lstlisting}
+\end{frame}
+
+\begin{frame}[fragile]
+\frametitle{UML: Parameters}
+\begin{lstlisting}[language=bash]
+$ ./linux ubd0=my_disk.img \
+ eth0=slirp,,slirp \
+ hostfs=${HOME}
+\end{lstlisting}
+\begin{itemize}
+\item ubd0: The ubdX parameter maps a file in the underlying filesystem to a
+device. This is used to specify the filesystem(s)
+\item eth0=slirp,,slirp: This enables limited access to the network, without
+having root permissions
+\item hostfs: Tell UML which host directories can be mounted inside the UML
+environment. For example: ''mount none /mnt/myhost -t hostfs'' inside UML will
+mount your hosts / to /mnt/myhost
+\end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]
+\frametitle{Running UML in gdb}
+\begin{lstlisting}[language=bash]
+$ gdb ./linux
+(gdb) handle SIGSEGV pass nostop noprint
+Signal Stop Print Pass to program Description
+SIGSEGV No No Yes Segmentation fault
+(gdb) b start_kernel
+Breakpoint 1 at 0x80493ca: file /home/devel/images/linux-2.6.37/init/main.c,
+line 539.
+(gdb) r
+Starting program: /home/devel/images/build_um/linux
+Locating the bottom of the address space ... 0x1000
+Locating the top of the address space ... 0xc0000000
+Core dump limits :
+ soft - 0
+ hard - NONE
+[...]
+Adding 10047488 bytes to physical memory to account for exec-shield gap
+
+Breakpoint 1, start_kernel () at
+/home/devel/images/linux-2.6.37/init/main.c:539
+539 smp_setup_processor_id();
+(gdb) c
+Continuing.
+Linux version 2.6.37 (devel@ltx) (gcc version 4.3.2 (Debian 4.3.2-1.1) )
+Thu Feb 10 06:25:23 UTC 2011
+Built 1 zonelists in Zone order, mobility grouping on. Total pages: 10561
+[...]
+\end{lstlisting}
+\end{frame}
+
+\input{tailpres}