1. 程式人生 > >列印除錯資訊的總結 pr_dbug pr_err pr_info

列印除錯資訊的總結 pr_dbug pr_err pr_info

在核心中經常見到一些除錯列印資訊。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等呼叫時,都會列印到終端螢幕的,不管之前的語句是否發生錯誤。之所以有幾種定義,是為了程式碼清晰。