日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

如何打开pr_debug调试信息

發(fā)布時間:2023/12/19 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何打开pr_debug调试信息 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

轉(zhuǎn)載:http://blog.csdn.net/helloanthea/article/details/25330809

以DMA的調(diào)試為例,先來看看一個pr_debug函數(shù)調(diào)用

pr_debug("%s: %s (%s)\n",__func__,chan ? "success" : "fail",chan ? dma_chan_name(chan) : NULL);

在include/linux/printk.h里找到pr_debug的定義

/* If you are writing a driver, please use dev_dbg instead */ #if defined(CONFIG_DYNAMIC_DEBUG) /* dynamic_pr_debug() uses pr_fmt() internally so we don't need it here */ #define pr_debug(fmt, ...) \dynamic_pr_debug(fmt, ##__VA_ARGS__) #elif defined(DEBUG) #define pr_debug(fmt, ...) \printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) #else #define pr_debug(fmt, ...) \no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) #endif


三個判斷條件決定pr_debug的用法
1.如果定義了CONFIG_DYNAMIC_DEBUG,就使用動態(tài)debug機(jī)制dynamic_pr_debug();
2.如果定義了DEBUG,就使用printk(KERN_DEBUG...)
3.默認(rèn)情況下,不打印。

那么要想讓kernel乖乖的打印調(diào)試信息,就只有兩條路可選了:要么動態(tài)debug,要么定義DEBUG宏。

先說一下如何定義DEBUG宏
其實在kernel中很多driver已經(jīng)定義好了這樣的選項
例如,我們經(jīng)常可以看到這樣的配置選項和宏定義:
(1)DMA Engine debugging(CONFIG_DMADEVICES_DEBUG )
(2)Power Management Debug Support(CONFIG_PM_DEBUG)
(3)Enable debug for the B2C2 FlexCop drivers(CONFIG_PCI_DEBUG)

以DMA為例,在drivers/dma/Makefile中定義了編譯選項
ccflags-$(CONFIG_DMADEVICES_DEBUG)? := -DDEBUG
其作用相當(dāng)于在drivers/dma/所有子文件定義了宏#define DEBUG

小伙伴們趕緊把CONFIG_DEBUG選項選上吧,然后重新編譯kernel。先別急,這樣還不夠,
默認(rèn)的console級別是7(在kernel/printk/printk.c中定義了#define DEFAULT_CONSOLE_LOGLEVEL 7)
只有那些級別“小于7”的調(diào)試信息才能打印出來,而printk(KERN_DEBUG...)的級別是7,那就還需要提高console打印級別
如果要查看dma初始化的debug信息,那就直接改代碼
#define DEFAULT_CONSOLE_LOGLEVEL 8
如果是runtime,可以直接通過printk的sys接口調(diào)整打印級別

$cat /proc/sys/kernel/printk 7 4 1 7 $echo 8 > /proc/sys/kernel/printk $cat /proc/sys/kernel/printk 8 4 1 7

?

ok,大功告成!

ps:如果一些driver沒有現(xiàn)成的宏可用,開發(fā)人員可以自己仿照上述方法,也可以直接在源文件中定義DEBUG宏

#define DEBUG(宏的作用范圍相信我就不用多說了吧,就是從宏定義開始到源文件的末尾結(jié)束)

?

下面再簡單說一下kernel的動態(tài)調(diào)試
打開Enable dynamic printk() support(DYNAMIC_DEBUG),那么所有的 pr_debug()/dev_debug() 之類的函數(shù)在runtime就可以動態(tài)地使用了。
kernel動態(tài)調(diào)試提供一個debugfs接口: <debugfs>/dynamic_debug/control
這個文件可以用來獲取已完成的調(diào)試信息列表
例如你要顯示文件'svcsock.c'的1603行內(nèi)容,你可以這樣做:

nullarbor:~ # echo 'file svcsock.c line 1603 +p' >
??????????????? <debugfs>/dynamic_debug/control ?

// 提供文件svcsock.c所有信息
nullarbor:~ # echo -n 'file svcsock.c +p' >
??????????????? <debugfs>/dynamic_debug/control

如果你想執(zhí)行多個命令,你需要為每個加入“echo”分割,像這樣:

nullarbor:~ # echo 'file svcsock.c line 1603 +p' > /proc/dprintk ;\
> echo 'file svcsock.c line 1563 +p' > /proc/dprintk

或者甚至是這樣:

nullarbor:~ # (
> echo 'file svcsock.c line 1603 +p' ;\
> echo 'file svcsock.c line 1563 +p' ;\
> ) > /proc/dprintk

file可以替換成module,format等匹配方式,具體用法請參考Documentation/dynamic-debug-howto.txt
好了,enjoy你的debug之旅吧!

下面是一個范例

Makefile:

ifneq ($(KERNELRELEASE),)ccflags-y += -DDEBUGobj-m := debug_driver.oobj-m += debug_device.o elseKERNELDIR ?= /root/work/latest_codes/linux-stablePWD := $(shell pwd) default:$(MAKE) -C $(KERNELDIR) M=$(PWD) modulesclean:@rm -rf *.o *.mod.c *.mod.o *.ko *.order *.symvers .*.cmd .tmp_versions endif

?

debug_device.c

#include <linux/init.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/mm.h>MODULE_LICENSE("GPL");static void demo_release (struct device *dev) {}static struct platform_device demo_dev = {.name = "demo_debug",.id = -1,.dev = {.release = demo_release,}, };static int demo_init(void) {platform_device_register(&demo_dev);return 0; }

?

debug_driver.c

#include <linux/init.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/mm.h> #include <linux/miscdevice.h> #include <linux/fs.h> #include <linux/types.h>static struct device *dev = NULL;static int debug_demo_open (struct inode *inode, struct file *file) {pr_debug("pr_debug: \n");dev_dbg(dev, "dev_dbg test.\n");return 0; }static int debug_demo_close (struct inode *inode, struct file *file) {printk("%s enter.\n", __func__);return 0; }static ssize_t debug_demo_write (struct file *file, const char __user *buf, size_t size, loff_t *offset) {printk("%s enter, size: %d\n", __func__, size);return size; }static struct file_operations debug_demo_fops = {.owner = THIS_MODULE,.open = debug_demo_open,.write = debug_demo_write,.release = debug_demo_close, };static struct miscdevice debug_demo_miscdev = {MISC_DYNAMIC_MINOR,"debug_demo",&debug_demo_fops };static int demo_probe(struct platform_device *device) {int ret;printk("%s enter.\n", __func__);dev = &device->dev;ret = misc_register(&debug_demo_miscdev);printk("ret: %d\n", ret);if (ret < 0)return ret;return 0; }static struct platform_driver demo_driver = {.probe = demo_probe,.driver = {.name = "demo_debug",.owner = THIS_MODULE,}, };static int demo_init(void) {platform_driver_register(&demo_driver);printk(KERN_ALERT "demo World.\n");return 0; }static void demo_exit(void) {platform_driver_unregister(&demo_driver);misc_deregister(&debug_demo_miscdev);printk(KERN_ALERT "GoodBye, cruel world.\n"); }MODULE_LICENSE("GPL"); module_init(demo_init); module_exit(demo_exit);

完。

總結(jié)

以上是生活随笔為你收集整理的如何打开pr_debug调试信息的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。