Dynamic debugging is a powerful feature in the Linux kernel that allows developers to enable or disable debug messages at runtime. This can be particularly useful for diagnosing issues without the need to recompile the kernel. One of the most commonly used methods for dynamic debugging in the Linux kernel is through the pr_debug
macro.
What is pr_debug
?
pr_debug
is a macro in the Linux kernel that works similarly to printk
, which is used for logging messages. However, the key difference is that pr_debug
messages can be dynamically enabled or disabled without requiring a kernel rebuild. This makes it an excellent tool for selectively debugging certain parts of the kernel code.
Here’s a basic example of how pr_debug
works:
#include <linux/kernel.h>
#include <linux/module.h>
void example_function(void) {
pr_debug("This is a debug message from example_function\n");
}
In the code above, the pr_debug
macro logs a message that can be enabled or disabled dynamically.
How to Enable pr_debug
?
By default, pr_debug
messages are disabled. To enable them, you can use the dynamic_debug
control interface, which is typically located at /sys/kernel/debug/dynamic_debug/control
.
To enable all pr_debug
messages in a module, you can use the following command:
echo 'module <module_name> +p' > /sys/kernel/debug/dynamic_debug/control
Replace <module_name>
with the name of the kernel module you want to debug.
To enable pr_debug
messages for a specific file within a module, use:
echo 'file <file_name.c> +p' > /sys/kernel/debug/dynamic_debug/control
Disabling pr_debug
If you want to disable pr_debug
messages, you can do so by removing the +p
option:
echo 'module <module_name> -p' > /sys/kernel/debug/dynamic_debug/control
Similarly, you can disable debugging for a specific file:
echo 'file <file_name.c> -p' > /sys/kernel/debug/dynamic_debug/control
Practical Example
Let’s walk through a practical example. Suppose you have a kernel module that handles network packets, and you want to debug a function that processes these packets.
First, you add pr_debug
statements in your function:
void process_packet(struct packet *pkt) {
pr_debug("Processing packet with ID: %d\n", pkt->id);
// Other processing code...
}
Next, you enable dynamic debugging for your module:
echo 'module net_module +p' > /sys/kernel/debug/dynamic_debug/control
Now, every time process_packet
is called, the debug message will be logged, helping you trace how packets are processed.
Advantages of Using pr_debug
- Selective Debugging: You can enable or disable debug messages for specific modules or files, which is more efficient than logging everything.
- No Need for Recompilation: Dynamic debugging allows you to make changes on the fly, without needing to recompile the kernel.
- Better Performance: Since debug messages are disabled by default, there is no performance hit in the production environment.