在内核中经常见到一些调试打印信息。pr_debug,pr_err等。以前的理解是以为只有出错才会将pr_err中的内容打印出来,现在看来是错的。pr_err并不等同与perror。
关于pr_err,pr_debug的定义有两种:
第一种
(tools\perf\util\include\linux\Kernel.h)
int eprintf(int level,
const char *fmt, ...) __attribute__((format(printf, 2, 3)));
#define pr_err(fmt, ...) \
eprintf(0, pr_fmt(fmt), ##__VA_ARGS__)
#define pr_warning(fmt, ...) \
eprintf(0, pr_fmt(fmt), ##__VA_ARGS__)
#define pr_info(fmt, ...) \
eprintf(0, pr_fmt(fmt), ##__VA_ARGS__)
#define pr_debug(fmt, ...) \
eprintf(1, pr_fmt(fmt), ##__VA_ARGS__)
#define pr_debugN(n, fmt, ...) \
eprintf(n, pr_fmt(fmt), ##__VA_ARGS__)
第二种
(tools\virtio\linux\Virtio.h)
#define pr_err(format, ...) fprintf (stderr, format, ## __VA_ARGS__)
#ifdef DEBUG
#define pr_debug(format, ...) fprintf (stderr, format, ## __VA_ARGS__)
#else
#define pr_debug(format, ...) do {} while (0)
#endif
#define dev_err(dev, format, ...) fprintf (stderr, format, ## __VA_ARGS__)
#define dev_warn(dev, format, ...) fprintf (stderr, format, ## __VA_ARGS__)
第一种定义,可以看出pr_err,pr_debug,pr_warning,pr_info实质上都是一样的,eprintf就是printf函数。__attribute__((format(printf, 2, 3)));表示printf格式化字符串从printf的第2个参数开始,可变参数从printf的第3个参数开始。关于attribute的介绍可以参加这里
所以,对于内核代码中出现pr_err,pr_debug,pr_warning,pr_info都是打印信息到终端。
第二种定义,关键是对fprintf的理解了。
fprintf(stderr, "Can't open it!\n");
fprintf(stdout, "Can't open it!\n");
stdout -- 标准输出设备 (printf("..")) 同 stdout。
stderr -- 标准错误输出设备
两者默认向屏幕输出。
但如果用转向标准输出到磁盘文件,则可看出两者区别。stdout输出到磁盘文件,stderr在屏幕。
也就是说两者都是要向终端屏幕打印信息的。
【总结】:pr_err pr_debug等调用时,都会打印到终端屏幕的,不管之前的语句是否发生错误。之所以有几种定义,是为了代码清晰。