📜 ⬆️ ⬇️

Making the code cleaner: Nuances of debugging output in Linux drivers

As is well known to many, debugging messages in Linux regarding drivers are carried out by several subsets of macros and functions. Not all analogues are interchangeable and work as it seems logical at first glance. That is what this brief article will be about.

First, let's look at what known message output functions are provided in the core internal API.

Basic function
printk(LEVEL "message\n"); 

From it there is a set of macros (the most frequently used):
 pr_err("message\n"); pr_warn("message\n"); pr_info("message\n"); pr_debug("message\n"); 

And so on.
')
For drivers, a set of functions with the prefix dev_* with the corresponding output levels is used, and separately for drivers of network cards with the prefix netdev_* . And in general, the general rule is that the kernel subsystem or driver uses its prefix with a message output level suffix.

All of them are full-fledged analogs of the pr_* record printk(LEVEL …) for pr_* and in the same way for dev_* and netdev_* except for pr_debug() , dev_dbg() and, as everyone has already guessed, netdev_dbg() .

So, under what conditions we will see the message displayed by different options?

With printk(KERN_DEBUG "message\n") :

and pr_debug("message\n") :

Same for dev_dbg() , and for netdev_dbg() .

In addition, special attention should be paid to the useful option CONFIG_DYNAMIC_DEBUG . With all its dynamism, it does not begin to load the kernel itself, so not all modules can rely on it.

Another dilemma about what to use in the product version: CONFIG_DYNAMIC_DEBUG or standard output, prefixed by a type condition:
 #define mydbg(dev, format, arg…) \ do { \ if (mycooldriver->debug > 0) \ dev_printk(KERN_DEBUG, dev, format, ##arg); \ } while (0) 

So the difference here is quite obvious, if you dig into the depths of the kernel source code, namely, in the first case, the output will be equal to no-op (empty operation), which is not so in the second case. Accordingly, modules that are critical in terms of execution time should not be filled with the code shown above. Moreover, the best option would be to use trace points in such places, but I will tell you about this sometime in the future.

Bonus add that function print_hex_dump_bytes() relatively recently acquired support from the Dynamic Debug.

Source: https://habr.com/ru/post/262791/


All Articles