4.1. Debugging Support in the Kernel
In Chapter 2, we recommended
that
you build
and install your
own kernel, rather than running the stock kernel that comes with your
distribution. One of the strongest reasons for running your own
kernel is that the kernel developers have built several debugging
features into the kernel itself. These features can create extra
output and slow performance, so they tend not to be enabled in
production kernels from distributors. As a kernel developer, however,
you have different priorities and will gladly accept the (minimal)
overhead of the extra kernel debugging support.
Here, we list the configuration options that
should be
enabled for kernels used for development. Except where specified
otherwise, all of these options are found under the
"kernel hacking" menu in whatever
kernel configuration tool you prefer. Note that some of these options
are not supported by all architectures.
- CONFIG_DEBUG_KERNEL
-
This option just makes other debugging options available; it should
be turned on but does not, by itself, enable any features.
- CONFIG_DEBUG_SLAB
-
This crucial option turns on several types of checks in the kernel
memory allocation functions; with these checks enabled, it is
possible to detect a number of memory overrun and missing
initialization errors. Each byte of allocated memory is set to
0xa5 before being handed to the caller and then
set to 0x6b when it is freed. If you ever see
either of those "poison" patterns
repeating in output from your driver (or often in an oops listing),
you'll know exactly what sort of error to look for.
When debugging is enabled, the kernel also places special guard
values before and after every allocated memory object; if those
values ever get changed, the kernel knows that somebody has overrun a
memory allocation, and it complains loudly. Various checks for more
obscure errors are enabled as well.
- CONFIG_DEBUG_PAGEALLOC
-
Full pages are removed from the kernel address space when freed. This
option can slow things down significantly, but it can also quickly
point out certain kinds of memory corruption errors.
- CONFIG_DEBUG_SPINLOCK
-
With this option enabled, the kernel catches operations on
uninitialized spinlocks and various other errors (such as unlocking a
lock twice).
- CONFIG_DEBUG_SPINLOCK_SLEEP
-
This option enables a check for attempts to sleep while holding a
spinlock. In fact, it complains if you call a function that could
potentially sleep, even if the call in question would not sleep.
- CONFIG_INIT_DEBUG
-
Items marked with _ _init (or _
_initdata) are discarded after system initialization or
module load time. This option enables checks for code that attempts
to access initialization-time memory after initialization is
complete.
- CONFIG_DEBUG_INFO
-
This option causes the kernel to be built with full debugging
information included. You'll need that information
if you want to debug the kernel with gdb. You
may also want to enable CONFIG_FRAME_POINTER if
you plan to use gdb.
- CONFIG_MAGIC_SYSRQ
-
Enables the "magic SysRq" key. We
look at this key in Section 4.5.2 later in this chapter.
- CONFIG_DEBUG_STACKOVERFLOW
- CONFIG_DEBUG_STACK_USAGE
-
These options can help track down kernel stack overflows. A sure sign
of a stack overflow is an oops listing without any sort of reasonable
back trace. The first option adds explicit overflow checks to the
kernel; the second causes the kernel to monitor stack usage and make
some statistics available via the magic SysRq key.
- CONFIG_KALLSYMS
-
This option (under "General setup/Standard
features") causes kernel symbol information to be
built into the kernel; it is enabled by default. The symbol
information is used in debugging contexts; without it, an oops
listing can give you a kernel traceback only in hexadecimal, which is
not very useful.
- CONFIG_IKCONFIG
- CONFIG_IKCONFIG_PROC
-
These options (found in the "General
setup" menu) cause the full kernel configuration
state to be built into the kernel and to be made available via
/proc. Most kernel developers know which
configuration they used and do not need these options (which make the
kernel bigger). They can be useful, though, if you are trying to
debug a problem in a kernel built by somebody else.
- CONFIG_ACPI_DEBUG
-
Under "Power management/ACPI." This
option turns on verbose ACPI (Advanced Configuration and Power
Interface) debugging information, which can be useful if you suspect
a problem related to ACPI.
- CONFIG_DEBUG_DRIVER
-
Under "Device drivers." Turns on
debugging information in the driver core, which can be useful for
tracking down problems in the low-level support code.
We'll look at the driver core in Chapter 14.
- CONFIG_SCSI_CONSTANTS
-
This option, found under "Device drivers/SCSI device
support," builds in information for verbose SCSI
error messages. If you are working on a SCSI driver, you probably
want this option.
- CONFIG_INPUT_EVBUG
-
This option (under "Device drivers/Input device
support") turns on verbose logging of input events.
If you are working on a driver for an input device, this option may
be helpful. Be aware of the security implications of this option,
however: it logs everything you type, including your passwords.
- CONFIG_PROFILING
-
This option is found under "Profiling
support." Profiling is normally used for system
performance tuning, but it can also be useful for tracking down some
kernel hangs and related problems.
We will revisit some of the above options as we look at
various ways of tracking down kernel problems. But first, we will
look at the classic debugging technique: print statements.
|