亚洲综合图片区自拍_思思91精品国产综合在线观看_一区二区三区欧美_欧美黑人又粗又大_亚洲人成精品久久久久桥本

訊息:Linux內(nèi)核學(xué)習(xí)筆記:動(dòng)態(tài)輸出調(diào)試

2023-06-01 15:04:11 來源:嵌入式Linux充電站

上篇說到printk調(diào)試,但printk是 全局的,只能設(shè)置輸出等級(jí)。而動(dòng)態(tài)輸出可以動(dòng)態(tài)選擇打開某個(gè)內(nèi)核子系統(tǒng)的輸出,可以有選擇性地打開某些模塊的輸出。

配置內(nèi)核編譯選項(xiàng)

要使用動(dòng)態(tài)輸出,必須在配置內(nèi)核時(shí)打開CONFIG_DYNAMIC_DEBUG宏。內(nèi)核代碼里使用大量pr_debug()/dev_dbg()函數(shù)來輸出信息,這些就使用了動(dòng)態(tài)輸出。


(資料圖)

需要打開的內(nèi)核配置選項(xiàng):

CONFIG_DEBUG_FS=yCONFIG_DYNAMIC_DEBUG=y

CONFIG_DYNAMIC_DEBUG是配置動(dòng)態(tài)輸出,它依賴于CONFIG_DEBUG_FS,而CONFIG_DEBUG_FSdebugfs文件系統(tǒng)

打開內(nèi)核配置后,我們還需要掛載debugfs文件系統(tǒng)

debugfs文件系統(tǒng)掛載

動(dòng)態(tài)輸出在debugfs文件系統(tǒng)中有一個(gè)control文件節(jié)點(diǎn),這個(gè)文件節(jié)點(diǎn)記錄了系統(tǒng)中所有使用動(dòng)態(tài)輸出技術(shù)的 文件名路徑、輸出所在的行號(hào)、模塊名字和要輸出的語句

debugfs默認(rèn)會(huì)掛載到/sys/kernel/debug,如果沒有掛載,可以執(zhí)行以下命令掛載:

# mount -t debugfs none /sys/kernel/debug/

掛載debugfs文件系統(tǒng)后,可以查看control節(jié)點(diǎn)內(nèi)容:

# cat /sys/kernel/debug/dynamic_debug/control

動(dòng)態(tài)輸出使用

打開svcsock.c文件中所有的動(dòng)態(tài)輸出語句

# echo "file svcsock.c +p" > /sys/kernel/debug/dynamic_debug/control

打開usbcore模塊中所有的動(dòng)態(tài)輸出語句

# echo "module usbcore +p" > /sys/kernel/debug/dynamic_debug/control

打開svc_process()函數(shù)中所有的動(dòng)態(tài)輸出語句

# echo "func svc_process() +p" > /sys/kernel/debug/dynamic_debug/control

打開文件路徑包含usb的文件里所有的動(dòng)態(tài)輸出語句

# echo -n "*usb* +p" > /sys/kernel/debug/dynamic_debug/control

打開系統(tǒng)所有的動(dòng)態(tài)輸出語句

# echo -n "+p" > /sys/kernel/debug/dynamic_debug/control

上面是打開動(dòng)態(tài)輸出語句的例子,除了能輸出pr_debug()/dev_dbg()函數(shù)中定義的輸出信息外,還能輸出一些額外信息,如函數(shù)名、行號(hào)、模塊名字以及線程ID等

p:打開動(dòng)態(tài)輸出語句f:輸出函數(shù)名l:輸出行號(hào)m:輸出模塊名字t:輸出線程ID

另外,還可以在各個(gè)子系統(tǒng)的Makefile中添加ccflags來打開動(dòng)態(tài)輸出語句

< ../Makefile >ccflags-y += -DDEBUGccflags-y += -DVERBOSE_DEBUG

實(shí)際案例

例如在一個(gè)led驅(qū)動(dòng)中的open()、write()等函數(shù)開頭添加一句pr_debug("%s enter\\n", **func **** ** );

#include < linux/module.h >#include < linux/fs.h >#include < linux/errno.h >#include < linux/miscdevice.h >#include < linux/kernel.h >#include < linux/major.h >#include < linux/mutex.h >#include < linux/proc_fs.h >#include < linux/seq_file.h >#include < linux/stat.h >#include < linux/init.h >#include < linux/device.h >#include < linux/tty.h >#include < linux/kmod.h >#include < linux/gfp.h >static int major = 0;static char kernel_buf[1024];static struct class *hello_class;#define MIN(a, b) (a < b ? a : b)static ssize_t hello_drv_read(struct file *file, char __user *buf, size_t size, loff_t *offset){ int err; pr_debug("%s enter\\n", __func__); err = copy_to_user(buf, kernel_buf, MIN(1024, size)); return MIN(1024, size);}static ssize_t hello_drv_write (struct file *file, const char __user *buf, size_t size, loff_t *offset){ int err; pr_debug("%s enter\\n", __func__); err = copy_from_user(kernel_buf, buf, MIN(1024, size)); return MIN(1024, size);}static int hello_drv_open (struct inode *node, struct file *file){ pr_debug("%s enter\\n", __func__); return 0;}static int hello_drv_close (struct inode *node, struct file *file){ pr_debug("%s enter\\n", __func__); return 0;}/* 2. 定義自己的file_operations結(jié)構(gòu)體                                              */static struct file_operations hello_drv = { .owner  = THIS_MODULE, .open    = hello_drv_open, .read    = hello_drv_read, .write   = hello_drv_write, .release = hello_drv_close,};static int __init hello_init(void){ int err;  pr_debug("%s enter\\n", __func__); major = register_chrdev(0, "hello", &hello_drv);  /* /dev/hello */ hello_class = class_create(THIS_MODULE, "hello_class"); err = PTR_ERR(hello_class); if (IS_ERR(hello_class)) {  unregister_chrdev(major, "hello");  return -1; }  device_create(hello_class, NULL, MKDEV(major, 0), NULL, "hello"); /* /dev/hello */  return 0;}static void __exit hello_exit(void){ pr_debug("%s enter\\n", __func__); device_destroy(hello_class, MKDEV(major, 0)); class_destroy(hello_class); unregister_chrdev(major, "hello");}module_init(hello_init);module_exit(hello_exit);MODULE_LICENSE("GPL");

為了方面查看,先清除內(nèi)核輸出:

# dmesg -c

然后加載驅(qū)動(dòng),執(zhí)行dmesg查看是否有打印:

# insmod hello_drv.ko# dmesg

此時(shí)沒有pr_debug()的打印。這時(shí)再使用動(dòng)態(tài)輸出打開hello_drv模塊的動(dòng)態(tài)輸出:

# echo "module hello_drv +p" > /sys/kernel/debug/dynamic_debug/control

然后執(zhí)行該驅(qū)動(dòng)的應(yīng)用層程序,使其調(diào)用到驅(qū)動(dòng)的open、write、close函數(shù),從而執(zhí)行pr_debug():

# ./hello_drv_test -w 10

再查看demsg內(nèi)容:

可以看到,當(dāng)打開了hello_drv模塊的動(dòng)態(tài)輸出后,驅(qū)動(dòng)中的pr_debug()語句就可以正常打印了。

再看看debugfs的control節(jié)點(diǎn):

# cat /sys/kernel/debug/dynamic_debug/control

control節(jié)點(diǎn)記錄了剛剛執(zhí)行pr_debug()時(shí)的文件名、所在行號(hào)、模塊名、函數(shù)名和輸出語句(p表示動(dòng)態(tài)輸出的語句)。

標(biāo)簽:

上一篇:STM32CubeMx定時(shí)器基本使用方法 焦點(diǎn)速遞
下一篇:最后一頁