How to Dynamically Enable dev_dbg in the Linux Kernel Without Reboot
This article explains the purpose of dev_info, dev_dbg, and dev_err in Linux kernel logging, shows how to view their output, and provides step‑by‑step methods—including dynamic debug, kernel configuration, and module parameters—to enable or disable dev_dbg at runtime without recompiling or rebooting.
1. dev_info function
dev_info is a kernel helper defined in <linux/device.h> that wraps printk with the KERN_INFO log level. It prints non‑error, informational messages such as device name, model, and resource usage, which can be viewed with dmesg. Typical use cases include driver probe initialization and system‑startup key‑device logging.
Device driver initialization: output MAC address, supported speeds, etc., in the probe function.
System boot key nodes: output storage device model, capacity, etc., to aid troubleshooting.
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/platform_device.h>
static struct platform_driver my_driver = {
.probe = my_probe,
.remove = my_remove,
.driver = {
.name = "my_device",
.owner = THIS_MODULE,
},
};
static int my_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
dev_info(dev, "My device is probed successfully!");
return 0;
}
static int my_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
dev_info(dev, "My device is removed.");
return 0;
}
static int __init my_module_init(void)
{
return platform_driver_register(&my_driver);
}
static void __exit my_module_exit(void)
{
platform_driver_unregister(&my_driver);
}
module_init(my_module_init);
module_exit(my_module_exit);
MODULE_LICENSE("GPL");Loading the module and running dmesg yields a line such as:
[ 3.452184] my_device: My device is probed successfully!2. dev_dbg function
dev_dbg prints debugging information but is disabled by default to avoid performance impact. It can be enabled either by defining the DEBUG macro at compile time or, more flexibly, by using the kernel's dynamic debug mechanism (CONFIG_DYNAMIC_DEBUG).
(1) Define DEBUG macro
#define DEBUG
#include <linux/device.h>
/* dev_dbg now prints */(2) Dynamic debug
When CONFIG_DYNAMIC_DEBUG is enabled, you can control output at runtime via /sys/kernel/debug/dynamic_debug/control. Example to enable all dev_dbg in a module:
echo 'module my_module +p' > /sys/kernel/debug/dynamic_debug/controlTo disable, replace +p with -p. You can also target a specific file or function:
echo 'file my_file.c +p' > /sys/kernel/debug/dynamic_debug/control
echo 'func my_function +p' > /sys/kernel/debug/dynamic_debug/controlDynamic debug works by recording all dev_dbg sites in a table during compilation; the control file toggles their emission without rebuilding.
Typical dev_dbg usage scenarios include tracing execution flow, printing variable values, and diagnosing non‑fatal errors in drivers.
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/usb.h>
static int my_usb_transfer(struct my_usb_device *dev, char *buf, int len)
{
int ret;
dev_dbg(&dev->udev->dev, "Enter my_usb_transfer, len = %d
", len);
ret = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 1), buf, len, NULL, 1000);
if (ret < 0)
dev_dbg(&dev->udev->dev, "USB transfer failed, error = %d
", ret);
else
dev_dbg(&dev->udev->dev, "USB transfer success
");
return ret;
}3. dev_err function
dev_err logs error‑level messages ( KERN_ERR) and is always enabled. It is used to record hardware failures, resource‑allocation errors, and other critical conditions. Example output format: my_driver 0000:01:00.0: Device read error: -EIO Developers can filter error messages with dmesg | grep -i err, dmesg --level=err, or by examining /var/log/kern.log and journalctl -k.
4. Why restart dev_dbg at runtime?
Recompiling the kernel or module each time you need more or fewer debug messages is time‑consuming. Runtime control lets you enable detailed logs only when needed, reducing overhead and speeding up the debugging cycle.
5. Methods to restart dev_dbg at runtime
5.1 Use dyndbg interface
echo 'module my_module +p' > /sys/kernel/debug/dynamic_debug/control5.2 Ensure CONFIG_DYNAMIC_DEBUG is set
CONFIG_DYNAMIC_DEBUG=y5.3 Enable via module parameters
modprobe my_module debug=1Driver code can expose a debug module parameter and conditionally call dev_dbg when it is non‑zero.
5.4 Use CONFIG_DEBUG_FS
mount -t debugfs none /sys/kernel/debug
echo 1 > /sys/kernel/debug/my_module/debug_enable6. Troubleshooting runtime dev_dbg activation
6.1 Permission issues
Modifying /sys/kernel/debug/dynamic_debug/control requires root. Use sudo or adjust permissions temporarily with chmod a+w, remembering to restore them afterwards.
6.2 Kernel configuration
If CONFIG_DYNAMIC_DEBUG or CONFIG_DEBUG_FS is not enabled, dynamic debug will not work. Recompile the kernel with these options enabled via make menuconfig under "Kernel hacking → Dynamic debug" and "Debug Filesystem".
6.3 dev_dbg produces no output
Possible causes: the DEBUG macro is not defined, the console log level is higher than KERN_DEBUG (check /proc/sys/kernel/printk), or the dynamic debug command was misspelled. Ensure debugfs is mounted and the module name matches.
7. Practical example: Ethernet driver debugging
Assuming the driver module is eth_driver:
Verify CONFIG_DYNAMIC_DEBUG is enabled.
Mount debugfs: mount -t debugfs none /sys/kernel/debug Enable dev_dbg for the module:
echo 'module eth_driver +p' > /sys/kernel/debug/dynamic_debug/controlReload the driver: rmmod eth_driver && modprobe eth_driver Inspect output: dmesg | grep eth_driver The resulting messages help pinpoint initialization failures, hardware detection problems, or other issues in the driver code.
Deepin Linux
Research areas: Windows & Linux platforms, C/C++ backend development, embedded systems and Linux kernel, etc.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
