在內核中經常見到一些調試打印信息。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等調用時,都會打印到終端屏幕的,不管之前的語句是否發生錯誤。之所以有幾種定義,是爲了代碼清晰。