Debugging Techniques Ted Baker  Andy Wang COP 5641 / CIS 4930.

Slides:



Advertisements
Similar presentations
Device Drivers. Linux Device Drivers Linux supports three types of hardware device: character, block and network –character devices: R/W without buffering.
Advertisements

RT_FIFO, Device driver.
Computer System Laboratory
R4 Dynamically loading processes. Overview R4 is closely related to R3, much of what you have written for R3 applies to R4 In R3, we executed procedures.
Module R2 CS450. Next Week R1 is due next Friday ▫Bring manuals in a binder - make sure to have a cover page with group number, module, and date. You.
Building and Running Modules Sarah Diesburg COP 5641.
Using VMX within Linux We explore the feasibility of executing ROM-BIOS code within the Linux x86_64 kernel.
Debugging What can debuggers do? Run programs Make the program stops on specified places or on specified conditions Give information about current variables’
1 CHAPTER 8 BUFFER OVERFLOW. 2 Introduction One of the more advanced attack techniques is the buffer overflow attack Buffer Overflows occurs when software.
Processes CSCI 444/544 Operating Systems Fall 2008.
Home: Phones OFF Please Unix Kernel Parminder Singh Kang Home:
Kernel module programming and debugging Advanced Operating Systems.
Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8 th Edition Chapter 2: Operating-System Structures Modified from the text book.
Chapter 13: I/O Systems I/O Hardware Application I/O Interface
Loadable Kernel Modules Dzintars Lepešs The University of Latvia.
Server Design Discuss Design issues for Servers Review Server Creation in Linux.
Spring 2014 SILICON VALLEY UNIVERSITY CONFIDENTIAL 1 Introduction to Embedded Systems Dr. Jerry Shiao, Silicon Valley University.
Debugging techniques in Linux Debugging Techniques in Linux Chetan Kumar S Wipro Technologies.
Game Scripting By: Nicholas Haines. Aurora Neverwinter Toolset.
Operating System Program 5 I/O System DMA Device Driver.
1 CS503: Operating Systems Part 1: OS Interface Dongyan Xu Department of Computer Science Purdue University.
6.828: PC hardware and x86 Frans Kaashoek
Debugging Techniques Sarah Diesburg COP Overview Several tools are available Some are more difficult to set up and learn Will go over basic tools,
CS591 (Spring 2001) The Linux Kernel: Debugging. CS591 (Spring 2001) Accessing the “Black Box” n Kernel code: n Not always executed in context of a process.
1 Computing Software. Programming Style Programs that are not documented internally, while they may do what is requested, can be difficult to understand.
The UNIX Shell. The Shell Program that constantly runs at terminal after a user has logged in. Prompts the user and waits for user input. Interprets command.
FINAL MPX DELIVERABLE Due when you schedule your interview and presentation.
Today’s Topics Introducing process: the basic mechanism for concurrent programming –Process management related system calls Process creation Process termination.
C questions A great programmer codes excellent code in C and Java. The code does video decoding. Java code works faster then C on my computer. how come?
Game Scripting by: Nicholas Haines. What is Scripting? Interpreted Language Interpreted Language –As the game runs.
Guide to Linux Installation and Administration, 2e1 Chapter 10 Managing System Resources.
Lecture 3 Process Concepts. What is a Process? A process is the dynamic execution context of an executing program. Several processes may run concurrently,
Agenda Link of the week Use of Virtual Machine Review week one lab assignment This week’s expected outcomes Review next lab assignments Break Out Problems.
Kernel Modules. Kernel Module Pieces of code that can be loaded and unloaded into the kernel upon demand. Compiled as an independent program With appropriate.
Kyu Ho Park Sept. 22, Lecture 4 proc file system(procfs) (Project 2 included) Sept.19,4pm.
Module 6: Debugging a Windows CE Image.  Overview Debug Zones IDE Debug Setup IDE Debug Commands Platform Builder Integrated Kernel Debugger Other Debugging.
UNIX Files File organization and a few primitives.
Using the /proc File System with “scull” Sarah Diesburg COP 5641.
NT Kernel CS Spring Overview Interrupts and Exceptions: Trap Handler Interrupt Request Levels and IRT DPC’s, and APC’s System Service Dispatching.
A Tutorial on Introduction to gdb By Sasanka Madiraju Graduate Assistant Center for Computation and Technology.
CSNB374: Microprocessor Systems Chapter 5: Procedures and Interrupts.
CSE 332: C++ debugging Why Debug a Program? When your program crashes –Finding out where it crashed –Examining program memory at that point When a bug.
CNIT 127: Exploit Development Ch 3: Shellcode. Topics Protection rings Syscalls Shellcode nasm Assembler ld GNU Linker objdump to see contents of object.
Operating Systems Process Creation
Debugging Techniques Ted Baker  Andy Wang COP 5641 / CIS 4930.
Interfacing Device Drivers with the Kernel
Processes and Virtual Memory
CSC414 “Introduction to UNIX/ Linux” Lecture 2. Schedule 1. Introduction to Unix/ Linux 2. Kernel Structure and Device Drivers. 3. System and Storage.
© Janice Regan, CMPT 300, May CMPT 300 Introduction to Operating Systems Operating Systems Processes and Threads.
Lab 12 Department of Computer Science and Information Engineering National Taiwan University Lab12 – Driver 2014/12/16 1 /21.
GAME203 – C Files stdio.h C standard Input/Output “getchar()”
Debugging Techniques Linux Kernel Programming CIS 4930/COP 5641.
Lecture 5 Rootkits Hoglund/Butler (Chapters 1-3).
I/O Software CS 537 – Introduction to Operating Systems.
1 Hardware Overview Dave Eckhardt
CSE 332: C++ expressions Expressions: Operators and Operands Operators obey arity, associativity, and precedence int result = 2 * 3 + 5; // assigns 11.
C Programming Day 2. 2 Copyright © 2005, Infosys Technologies Ltd ER/CORP/CRS/LA07/003 Version No. 1.0 Union –mechanism to create user defined data types.
C++ Functions A bit of review (things we’ve covered so far)
Introduction to Operating Systems Concepts
Chapter 13: I/O Systems Modified by Dr. Neerja Mhaskar for CS 3SH3.
Kernel Tracing David Ferry, Chris Gill
Linux Kernel Driver.
Want to play a game? – Linux Kernel Modules
Introduction to Operating Systems
Discussions on HW2 Objectives
When your program crashes
Discussions on HW2 Objectives
Kernel Tracing David Ferry, Chris Gill, Brian Kocoloski
CSE 153 Design of Operating Systems Winter 2019
Chapter 13: I/O Systems “The two main jobs of a computer are I/O and [CPU] processing. In many cases, the main job is I/O, and the [CPU] processing is.
Presentation transcript:

Debugging Techniques Ted Baker  Andy Wang COP 5641 / CIS 4930

Overview Several tools are available Some are difficult to set up and learn All of them have inherent limitations Intrusive, may change the kernel behavior Kernel might crash the tool

Kernel Debugging Support Under the “kernel hacking” menu Not supported by all architectures CONFIG_DEBUG_KERNEL Enables other debugging features CONFIG_DEBUG_MEMORY_INIT Checks kernel memory allocation functions Memory overrun Missing initialization

Kernel Debugging Support CONFIG_DEBUG_PAGEALLOC Pages are removed from the kernel address space when freed CONFIG_DEBUG_SPINLOCK Catches operations on uninitialized spinlocks and double unlocking

Kernel Debugging Support CONFIG_DEBUG_SPINLOCK_SLEEP Checks for attempts to sleep while holding a spinlock CONFIG_DEBUG_MEMORY_INIT Checks for attempts to access initialization- time memory CONFIG_DEBUG_INFO Enables gdb debugging

Kernel Debugging Support CONFIG_MAGIC_SYSRQ For debugging system hangs CONFIG_DEBUG_STACKOVERFLOW Helps track down kernel stack overflows CONFIG_DEBUG_STACK_USAGE Monitors stack usage and makes statistics available via magic SysRq key

Kernel Debugging Support CONFIG_KALLSYMS Causes kernel symbol information to be built into the kernel CONFIG_IKCONFIG CONFIG_IKCONFIG_PROC Causes kernel configurations to be made available via /proc

Kernel Debugging Support CONFIG_ACPI_DEBUG Enables debugging for power management CONFIG_PROFILING For performance tuning To confirm grep CONFIG_.config

printk (vs. printf ) Classifies messages according to their priority/loglevels printk(KERN_DEBUG “Here I am: %s:%i\n”, __FILE__, __LINE__); Eight possible loglevels (0 - 7), defined in

printk (vs. printf ) KERN_EMERG For emergency messages KERN_ALERT For a situation requiring immediate action KERN_CRIT Critical conditions, related to serious hardware or software failures

printk (vs. printf ) KERN_ERR Used to report error conditions; device drivers often use it to report hardware difficulties KERN_WARNING Warnings for less serious problems

printk (vs. printf ) KERN_NOTICE Normal situations worthy of note (e.g., security-related) KERN_INFO Informational messages KERN_DEBUG Used for debugging messages

printk (vs. printf ) Without specified priority DEFAULT_MESSAGE_LOGLEVEL = KERNEL_WARNING If current priority < console_loglevel console_loglevel initialized to DEFAULT_CONSOLE_LOGLEVEL Message is printed to the console one line at a time

printk (vs. printf ) If both klogd and syslogd are running Messages are appended to /var/log/messages klog daemon doesn’t save consecutive identical lines, only the first line + the number of repetitions

printk (vs. printf ) console_loglevel can be modified using /proc/sys/kernel/printk Contains 4 values Current loglevel Default log level Minimum allowed loglevel Boot-timed default loglevel echo 6 > /proc/sys/kernel/printk

How Messages Get Logged printk writes messages into a circular buffer that is __LOG_BUF_LEN bytes Wakes any process that is waiting for messages If the buffer fills up, printk wraps around and overwrite the beginning of the buffer Can specify the –f option to klogd to save messages to a specific file

How Messages Get Logged Reading from /proc/kmsg consumes data syslog system call can leave data for other processes (try dmesg command)

Turning the Messages On and Off at Compile Time Need to recompile to turn messages on and off Faster than using C conditionals In a header file (e.g., scull.h ) #undef PDEBUG /* undef it, just in case */ #ifdef SCULL_DEBUG # ifdef __KERNEL__ # define PDEBUG(fmt, args...) \ printk(KERN_DEBUG “scull: “ fmt, ## args) # endif Concatenation operator

Turning the Messages On and Off In the Makefile file DEBUG = y ifeq ($(DEBUG),y) DEBFLAGS = -O –g –DSCULL_DEBUG # “-O” is needed to expand inlines else DEBFLAGS = -O2 endif CFLAGS += $(DEBFLAGS)

Rate Limiting Too many messages may overwhelm the console To reduce repeated messages, use int printk_ratelimit(void); Example if (printk_ratelimit()) { printk(KERN_NOTICE “The printer is still on fire\n”); }

Rate Limiting To modify the behavior of printk_ratelimit /proc/sys/kernel/printk_ratelimit Number of seconds before re-enabling messages /proc/sys/kernel/printk_ratelimit_burst Number of messages accepted before rate limiting

Printing Device Numbers Utility functions (defined as macros) int print_dev_t(char *buffer, dev_t dev); Returns the number of characters printed char *format_dev_t(char *buffer, dev_t dev); Returns buffer buffer should be at least 20 bytes

Debugging by Querying Disadvantages of printk Every line causes a disk operation Can be solved by prefixing the log file specified in /etc/syslogd.conf with “-” Example (in /etc/syslogd.conf ) mail.*-/var/log/maillog One alternative: query the system ps, netstat, vmstat, /proc, ioctl, sysfs

Using the /proc Filesystem Exports kernel information Each file under /proc tied to a kernel function

Implementing Files in /proc #include For a read-only file, your driver must implement the following function int (*read_proc) (char *page, char **start, off_t offset, int count, int *eof, void *data); page points to a buffer with PAGE_SIZE bytes

Implementing Files in /proc start points to where to store the read data start == NULL indicates the offset is 0 eof points to an integer, which signals that it has no more data to return data is device-specific, for internal bookkeeping

Implementing Files in /proc int scull_read_procmem(char *buf, char **start, off_t offset, int count, int *eof, void *data) { int i, j, len = 0; int limit = count - 80; /* Don't print more than this */ for (i = 0; i < scull_nr_devs && len <= limit; i++) { struct scull_dev *d = &scull_devices[i]; struct scull_qset *qs = d->data; if (down_interruptible(&d->sem)) { return -ERESTARTSYS; } len += sprintf(buf+len,"\nDevice %i: qset %i, q %i, sz %li\n", i, d->qset, d->quantum, d->size);

Implementing Files in /proc int scull_read_procmem(char *buf, char **start, off_t offset, int count, int *eof, void *data) { int i, j, len = 0; int limit = count - 80; /* Don't print more than this */ for (i = 0; i < scull_nr_devs && len <= limit; i++) { struct scull_dev *d = &scull_devices[i]; struct scull_qset *qs = d->data; if (down_interruptible(&d->sem)) { return -ERESTARTSYS; } len += sprintf(buf+len,"\nDevice %i: qset %i, q %i, sz %li\n", i, d->qset, d->quantum, d->size); start and offset not used

Implementing Files in /proc /* scan the list */ for (; qs && len next) { len += sprintf(buf + len, " item at %p, qset at %p\n", qs, qs->data); if (qs->data && !qs->next) /* dump only the last item */ for (j = 0; j qset; j++) { if (qs->data[j]) { len += sprintf(buf + len, " % 4i: %8p\n", j, qs->data[j]); } up(&scull_devices[i].sem); } *eof = 1; return len; }

Creating Your /proc File To connect the read_proc function to /proc, call the following struct proc_dir_entry *create_proc_read_entry( const char *name, mode_t mode, struct proc_dir_entry *base, read_proc_t *read_proc, void *data); name : name of the /proc file Note: kernel does not check duplicate names mode : protection mask (0 for default)

Creating Your /proc File base : directory ( NULL for /proc root) read_proc : read function defined to access a kernel data structure data : ignored by the kernel, but passed to read_proc To make scull_read_procmem available, call the following create_proc_read_entry(“scullmem”, 0, NULL, scull_read_procmem, NULL);

Creating Your /proc File To remove scull_read_procmem, call the following remove_proc_entry(“scullmem”, NULL /* parent directory */); Note: /proc has no reference count Make sure that no one is reading the file

The seq_file Interface Provides an iterator for a /proc file #include You need to create four methods start, next, stop, show void *start(struct seq_file *sfile, loff_t *pos); sfile : almost always ignored pos : not necessarily in bytes

The seq_file Interface In the scull example static void *scull_seq_start(struct seq_file *s, loff_t *pos) { if (*pos >= scull_nr_devs) { return NULL; /* no more to read */ } return scull_devices + *pos; }

The seq_file Interface void *next(struct seq_file *sfile, void *v, loff_t *pos); v : returned from previous call to start or next pos : current position in the file, not necessarily in bytes

The seq_file Interface In the scull example static void *scull_seq_next(struct seq_file *s, void *v, loff_t *pos) { (*pos)++; if (*pos >= scull_nr_devs) { return NULL; /* no more to read */ } return scull_devices + *pos; }

The seq_file Interface void *stop(struct seq_file *sfile, void *v); Cleans up An empty function for the scull example

The seq_file Interface void *show(struct seq_file *sfile, void *v); Creates output for data structure traversed by the iterator Should not use printk ; instead, use seq_printf(struct seq_file *sfile, const char *fmt, …); seq_putc(struct seq_file *sfile, char c); seq_puts(struct seq_file *sfile, const char *s); Similar to printf, putc, puts

The seq_file Interface In the scull example static int scull_seq_show(struct seq_file *s, void *v) { struct scull_dev *dev = (struct scull_dev *) v; struct scull_qset *d; int i; if (down_interruptible(&dev->sem)) { return -ERESTARTSYS; } seq_printf(s, "\nDevice %i: qset %i, q %i, sz %li\n", (int) (dev - scull_devices), dev->qset, dev->quantum, dev->size);

The seq_file Interface for (d = dev->data; d; d = d->next) { /* scan the list */ seq_printf(s, " item at %p, qset at %p\n", d, d->data); if (d->data && !d->next) { /* dump only the last item */ for (i = 0; i qset; i++) { if (d->data[i]) { seq_printf(s, " % 4i: %8p\n", i, d->data[i]); } up(&dev->sem); return 0; }

The seq_file Interface To package the four iterator operations, declare the following structure static struct seq_operations scull_seq_ops = {.start = scull_seq_start,.next = scull_seq_next,.stop = scull_seq_stop,.show = scull_seq_show };

The seq_file Interface To associate seq_operations to a /proc file at file open time, create an open method static int scull_proc_open(struct inode *inode, struct file *file) { return seq_open(file, &scull_seq_ops); }

The seq_file Interface Then, package scull_proc_open to a file_operations data structure static struct file_operations scull_proc_ops = {.owner = THIS_MODULE,.open = scull_proc_open,.read = seq_read,.llseek = seq_lseek,.release = seq_release }; Default methods

The seq_file Interface Finally, create the file in /proc entry = create_proc_entry(“scullseq”, 0, NULL); if (entry) entry->proc_fops = &scull_proc_ops; Prototype for create_proc_entry struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode, struct proc_dir_entry *parent); vs. proc_read More general, easier to maintain

debugfs Similar to /proc Easier to use in some cases To use Compile kernel with CONFIG_DEBUG_FS=y mount –t debugfs none /sys/kernel/debug

debugfs Call the following in your kernel code struct dentry debugfs_create_u32(const char *name, mode_t mode, struct dentry *parent, u32 *val);

Read/write val via /sys/kernel/debugfs/foo #include static struct dentry *de; static u32 val = (u32) 777; static int debugfs_init { de = debugfs_create_u32(“foo”, S_IRUGO|S_IWUSR, NULL, &val); } static void debugfs_exit { if (de) { debugfs_remove(de); } } module_init(debugfs_init); module_exit(debugfs_exit); Defined in linux/stat.h

The ioctl Method Implement additional commands to return debugging information Advantages More efficient Does not need to split data into pages Can be left in the driver unnoticed

The ioctl Method Implement additional commands to return debugging information Disadvantages Needs to implement a user-level debugging program that is in sync with the kernel module Slightly bigger module

Debugging by Watching strace command Shows system calls, arguments, and return values No need to compile a program with the –g option -t to display when each call is executed -T to display the time spent in the call -e to limit the types of calls -o to redirect the output to a file

Debugging by Watching strace example 1 > strace ls /dev > /dev/scull0 [...] open("/dev", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY) = 3 fstat64(3, {st_mode=S_IFDIR|0755, st_size=24576,...}) = 0 fcntl64(3, F_SETFD, FD_CLOEXEC) = 0 getdents64(3, /* 141 entries */, 4096) = 4088 [...] getdents64(3, /* 0 entries */, 4096) = 0 close(3) = 0 [...]

Debugging by Watching strace example 1 [...] fstat64(1, {st_mode=S_IFCHR|0664, st_rdev=makedev(254, 0),...}) = 0 write(1, "MAKEDEV\nadmmidi0\nadmmidi1\nadmmid"..., 4096) = 4000 write(1, "b\nptywc\nptywd\nptywe\nptywf\nptyx0\n"..., 96) = 96 write(1, "b\nptyxc\nptyxd\nptyxe\nptyxf\nptyy0\n"..., 4096) = 3904 write(1, "s17\nvcs18\nvcs19\nvcs2\nvcs20\nvcs21"..., 192) = 192 write(1, "\nvcs47\nvcs48\nvcs49\nvcs5\nvcs50\nvc"..., 673) = 673 close(1) = 0 exit_group(0) = ? The size of a scull quantum is 4,000 bytes

Debugging by Watching strace example 2 strace wc /dev/scull0 [...] open("/dev/scull0", O_RDONLY|O_LARGEFILE) = 3 fstat64(3, {st_mode=S_IFCHR|0664, st_rdev=makedev(254, 0),...}) = 0 read(3, "MAKEDEV\nadmmidi0\nadmmidi1\nadmmid"..., 16384) = 4000 read(3, "b\nptywc\nptywd\nptywe\nptywf\nptyx0\n"..., 16384) = 4000 read(3, "s17\nvcs18\nvcs19\nvcs2\nvcs20\nvcs21"..., 16384) = 865 read(3, "", 16384) = 0 fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1),...}) = 0 write(1, "8865 /dev/scull0\n", 17) = 17 close(3) = 0 exit_group(0) = ? wc bypasses the standard library and reads 16KB at a time

Debugging System Faults A fault usually ends the current process, while the system continues to work Potential side effects Hardware left in an unusable state Kernel resources in an inconsistent state Corrupted memory Common remedy Reboot

Oops Messages Dereferencing invalid pointers often results in oops messages ssize_t faulty_write(struct file *filp, const char __user *buf, size_t count, loff_t *pos) { /* make a simple fault by dereferencing a NULL pointer */ *(int *)0 = 0; return 0; }

Oops Messages Unable to handle kernel NULL pointer dereference at virtual address printing eip: d083a064 Oops: 0002 [#1] SMP CPU: 0 EIP: 0060:[ ] Not tainted EFLAGS: (2.6.6) EIP is at faulty_write+0x4/0x10 [faulty] eax: ebx: ecx: edx: esi: cf8b2460 edi: cf8b2480 ebp: esp: c31c5f74 ds: 007b es: 007b ss: 0068 Process bash (pid: 2086, threadinfo=c31c4000 task=cfa0a6c0) Stack: c cf8b e cf8b cf8b2460 cf8b2460 fffffff7 080e9408 c31c4000 c cf8b e cf8b c0103f8f e Call Trace: [ ] vfs_write+0xb8/0x130 [ ] sys_write+0x42/0x70 [ ] syscall_call+0x7/0xb Code: c3 90 8d ec 0c b8 00 a6 83 d0 Function name, 4 bytes into the function, kernel module name Error message Call stack Kernel address space if >= 0xc000000

Oops Messages Buffer overflow ssize_t faulty_read(struct file *filp, char __user *buf, size_t count, loff_t *pos) { int ret; char stack_buf[4]; memset(stack_buf, 0xff, 20); /* buffer overflow */ if (count > 4) { count = 4; /* copy 4 bytes to the user */ } ret = copy_to_user(buf, stack_buf, count); if (!ret) { return count; } return ret; }

Oops Messages EIP: 0010:[ ] Unable to handle kernel paging request at virtual address ffffffff printing eip: ffffffff Oops: 0000 [#5] SMP CPU: 0 EIP: 0060:[ ] Not tainted EFLAGS: (2.6.6) EIP is at 0xffffffff eax: c ebx: ffffffff ecx: edx: bfffda7c esi: cf434f00 edi: ffffffff ebp: esp: c27fff78 ds: 007b es: 007b ss: 0068 Process head (pid: 2331, threadinfo=c27fe000 task=c ) Stack: ffffffff bfffda cf434f cf434f00 fffffff7 bfffda70 c27fe000 c cf434f00 bfffda cf434f c0103f8f bfffda bfffda70 Call Trace: [ ] sys_read+0x42/0x70 [ ] syscall_call+0x7/0xb Code: Bad EIP value. Error message 0xffffffff points to nowhere User-space address space if < 0xc Call stack Bad address

Oops Messages Require CONFIG_KALLSYMS option turned on to see meaningful messages Other tricks 0xa5a5a5a5 on stack  memory not initialized

System Hangs If Ctrl-Alt-Del does not work Two choices Prevent hangs Debug after the fact

System Hangs Insert schedule() calls at strategic points Hand the CPU back to the scheduler Do not call if your driver holds a spinlock

System Hangs Keyboard lockups, but other things are still working Use the “magic SysRq key” To enable magic SysRq Compile kernel with CONFIG_MAGIC_SYSRQ on echo 1 > /proc/sys/kernel/sysrq To trigger magic SysRq Alt-SysRq- echo > /proc/sysrq- trigger

System Hangs Key k : kills all processes running on the current console s : synchronize all disks u : umount and remount all disks in read- only mode b : reboot, make sure to synchronize and remount the disks first

System Hangs p : prints processor registers information t : prints the current task list m : prints memory information See sysrq.txt for more Precaution for chasing system hangs Mount all disks as read-only

Using gdb Compile kernel with the CONFIG_DEBUG_INFO option set Need an uncompressed ELF kernel image (not zImage or bzImage ) Cannot modify kernel data Not possible to set breakpoints or watchpoints, or single-step through functions

Using gdb > gdb /usr/src/linux/vmlinux /proc/kcore … (gdb) p jiffies $1 = (gdb) p jiffies $2 = (gdb) core-file /proc/kcore … (gdb) p jiffies $3 = Number of clock ticks from system boot to the current time gdb caches data Need to flush the gdb cache

Using gdb vmlinux does not know about kernel modules Need to tell gdb where to load symbols from ELF-format kernel modules. text : executable code for the module.bss : uninitialized variables.data : initialized variables

Using gdb With scull.ko loaded > grep scull /proc/kallsyms | sort … f2ab5000 t scull_read_procmem [scull] f2ab5125 t scull_seq_start [scull] … f2ab69e0 d scull_nr_devs [scull] f2ab69e4 d scull_nr_devs [scull] … f2ab6d00 b scull_major [scull] f2ab6d04 b scull_minor [scull] …

Using gdb > gdb /usr/src/linux/vmlinux /proc/kcore … (gdb) add-symbol-file scull.ko 0xf2ab5000 –s.bss 0xf2ab69e0 \ –s.data 0xf2ab6d00 … (gdb) p scull_devices[0] $1 = {data = 0x0xcfd66c50, quantum = 4000, …}

The User-Mode Linux Port Advantages Allows the Linux kernel to run as a separate user-level process Limits the damage to the real system Use regular gdb Disadvantages Has no access to hardware

The Linux Trace Toolkit Can trace various events in the kernel Can track down performance problems

The kgdb Kernel Support Separate the machine running the test kernel from the machine running the debugger Connected via a serial cable

The kdb Kernel Debugger An interactive debugger Can set breakpoints Can modify data as well Download two patches from oss.sgi.com (with matching kernel version) Obsolete

Others kprobes Can insert breakpoints Can be used to examine as well as modify processor registers, data structures, etc. jprobes Can instrument any function Examples See lab book