-DDEBUGging the kernel

You won’t believe this one small trick!

Seriously though, as someone who is often extremely dense when it comes to figuring out things that should be obvious, it took me wayyyy too long to discover that this was a thing that could be done.

If you’ve ever wondered how to get those pesky dev_dbg() logs to work when poking around the kernel, but not wanted to go through the hassle of enabling and configuring dynamic debugging, just open up the Makefile (preferably for the driver or subsystem you’re working on… Otherwise you’ll have to rebuild everything!) and add this to the top:

ccflags-y += -DDEBUG

If you only want to enable debugging for one C file, just add this before all the #include statements:

#define DEBUG

Boot your new kernel with ignore_loglevel on the kernel cmdline, or if you don’t need debugging output during boot, wait until you get a shell and run:

sudo dmesg -n 8

How does it work?

I guess I should at least pretend this is more of a blog post, but then again why bury the lead.

In include/linux/printk.h you can find the following (and several other blocks like it).

542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
/**
 * pr_devel - Print a debug-level message conditionally
 * @fmt: format string
 * @...: arguments for the format string
 *
 * This macro expands to a printk with KERN_DEBUG loglevel if DEBUG is
 * defined. Otherwise it does nothing.
 *
 * It uses pr_fmt() to generate the format string.
 */
#ifdef DEBUG
#define pr_devel(fmt, ...) \
	printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
#else
#define pr_devel(fmt, ...) \
	no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
#endif

Yep, it’s really just that simple.