dynamic debug log输出机制
2012-06-05 15:17
393 查看
dynamic debug log输出机制
0. 注意该机制只对 dev_dbg -> dynamic_dev_dbg
定义的debug log输出加以控制
1. 如何使用:(kernel/Documentation/dynamic-debug-howto.txt)
mkdir /data/debugfs
mount -t debugfs none /data/debugfs
echo -n 'file ab8500_fg.c +p' > /data/debugfs/dynamic_debug/control //增加该文件dynamic debug的输出
echo -n 'file ab8500_fg.c -p' > /data/debugfs/dynamic_debug/control //去掉该文件dynamic debug的输出
2. 如果想使用debugfs
必须,在kernel的config文件(kernel/arch/arm/configs/semc_lotus_deconfig)中有CONFIG_DEBUG_FS=y
3. 如果需要使用Dynamic debug机制,需要在kernel的config文件(kernel/arch/arm/configs/semc_lotus_deconfig)中有CONFIG_DYNAMIC_DEBUG=y
4. dev_dbg@kernel/include/linux/device.h
->dynamic_dev_dbg@kernel/include/linux/dynamic_debug.h
#define dynamic_dev_dbg(dev, fmt, ...) do { \
static struct _ddebug descriptor \
__used \
__attribute__((section("__verbose"), aligned(8))) = \
{ KBUILD_MODNAME, __func__, __FILE__, fmt, DEBUG_HASH, \
DEBUG_HASH2, __LINE__, _DPRINTK_FLAGS_DEFAULT }; \
if (__dynamic_dbg_enabled(descriptor)) \
dev_printk(KERN_DEBUG, dev, fmt, ##__VA_ARGS__); \
} while (0)
a. 该define
最终会展开在被调用dev_dbg函数的c文件中,也就是KBUILD_MODNAME, __func__, __FILE__, __LINE__
会有对应的字符串
b. _DPRINTK_FLAGS_DEFAULT=0;
c. DEBUG_HASH和DEBUG_HASH2的定义在kernel/scripts/makefile.lib中
DEBUG_HASH=$(shell ./scripts/basic/hash djb2 $(@D)$(modname)) //利用djb2 hash算法,计算modname的DEBUG_HASH
value;
DEBUG_HASH2=$(shell ./scripts/basic/hash r5 $(@D)$(modname)) //利用r5 hash算法,计算modname的DEBUG_HASH2
value;
d. 分析 kernel/scripts/basic/hash.c,会生成out/target/product/lotus/obj/kernel/scripts/basic/hash,
shell可执行文件
e. 在编译连接完成后,该 descriptor
值会被保存到 data section的 __verbose区
5. dynamic_debug_init@kernel/lib/dynamic_debug.c
a. dir = debugfs_create_dir("dynamic_debug", NULL);
b. file = debugfs_create_file("control", 0644, dir, NULL, &ddebug_proc_fops); //在debugfs文件系统中创建dynamic_debug/control
文件
c. 通过__start___verbose和__stop___verbose@kernel/include/asm-generic/vmlinux.lds.h中,实际上是获取保存在__verbose区的
struct _ddebug 数据(就是前面编译后添加到data section的__verbose)
d. 如果是不同的modname,就添加到ddebug_tables
中,也就是所有dynamic_dev_dbg的模块(modname),文件(__FILE__),行(__LINE__),函数(__func__),是否输出的flag,对应的hash
value都会逐条保存到ddebug_tables中
6. 分析 echo -n 'file ab8500_charger.c +p' > /data/debugfs/dynamic_debug/control
的实际操作
a. 通过system call,debugfs文件系统会调用到ddebug_proc_write,ddebug_parse_query和ddebug_parse_flags@kernel/lib/dynamic_debug.c分析传入的参数字符串
b. 在ddebug_change@kernel/lib/dynamic_debug.c中,会根据modname, __FILE__, __LINE__,
__func__信息在ddebug_tables找到对应的item.
c. 然后根据输入的是 +p或-p ,来标志struct _ddebug中flag字段,还有根据struct
_ddebug中的primary_hash和secondary_hash,来标志global value dynamic_debug_enabled和dynamic_debug_enabled2
对应的位,会在__dynamic_dbg_enabled@kernel/include/linux/dynamic_debug.h用到
7. 分析 #cat /data/debugfs/dynamic_debug/control的实际操作
a. 先ddebug_proc_open中有err = seq_open(file, &ddebug_proc_seqops);应用了seq
file的读写机制
b. 然后seq_read,利用seq file机制逐个读出和显示ddebug_tables中的内容
8. long long dynamic_debug_enabled和dynamic_debug_enabled2@kernel/lib/dynamic_debugc,用于标志某个mod(可包含一个或多个文件,比如ab8500_fg
mod,目前只包含ab8500_fg.c file)是否可以输出debug log的模块.
最多可以标志64*64=4096个dev_debug/dynamic_dev_dbg.
9. 是否输出dev_log/dynamic_dev_dbg的log,
关键是如下判断,@kernel/include/linux/dynamic_debug.h
#define __dynamic_dbg_enabled(dd) ({ \
int __ret = 0; \
if (unlikely((dynamic_debug_enabled & (1LL << DEBUG_HASH)) && \
(dynamic_debug_enabled2 & (1LL << DEBUG_HASH2)))) \
if (unlikely(dd.flags)) \
__ret = 1; \
__ret; })
a.
dynamic_debug_enabled和dynamic_debug_enabled2就是前面分析的是否输出该modname的两个long long的组合标志位
b. DEBUG_HASH和DEBUG_HASH2
如前面所解释
c. dd.flag
默认为_DPRINTK_FLAGS_DEFAULT,但通过debugfs文件系统,最终操作ddebug_proc_write函数,会设置为_DPRINTK_FLAGS_PRIN或_DPRINTK_FLAGS_DEFAULT
10. debugfs 文件系统中的内容保存在那?????内存中,类似proc
11. 小结:如果你需要用到dynamic debug info,
你需要在你的 .c
文件中查看是否用到了dev_log
输出log。
0. 注意该机制只对 dev_dbg -> dynamic_dev_dbg
定义的debug log输出加以控制
1. 如何使用:(kernel/Documentation/dynamic-debug-howto.txt)
mkdir /data/debugfs
mount -t debugfs none /data/debugfs
echo -n 'file ab8500_fg.c +p' > /data/debugfs/dynamic_debug/control //增加该文件dynamic debug的输出
echo -n 'file ab8500_fg.c -p' > /data/debugfs/dynamic_debug/control //去掉该文件dynamic debug的输出
2. 如果想使用debugfs
必须,在kernel的config文件(kernel/arch/arm/configs/semc_lotus_deconfig)中有CONFIG_DEBUG_FS=y
3. 如果需要使用Dynamic debug机制,需要在kernel的config文件(kernel/arch/arm/configs/semc_lotus_deconfig)中有CONFIG_DYNAMIC_DEBUG=y
4. dev_dbg@kernel/include/linux/device.h
->dynamic_dev_dbg@kernel/include/linux/dynamic_debug.h
#define dynamic_dev_dbg(dev, fmt, ...) do { \
static struct _ddebug descriptor \
__used \
__attribute__((section("__verbose"), aligned(8))) = \
{ KBUILD_MODNAME, __func__, __FILE__, fmt, DEBUG_HASH, \
DEBUG_HASH2, __LINE__, _DPRINTK_FLAGS_DEFAULT }; \
if (__dynamic_dbg_enabled(descriptor)) \
dev_printk(KERN_DEBUG, dev, fmt, ##__VA_ARGS__); \
} while (0)
a. 该define
最终会展开在被调用dev_dbg函数的c文件中,也就是KBUILD_MODNAME, __func__, __FILE__, __LINE__
会有对应的字符串
b. _DPRINTK_FLAGS_DEFAULT=0;
c. DEBUG_HASH和DEBUG_HASH2的定义在kernel/scripts/makefile.lib中
DEBUG_HASH=$(shell ./scripts/basic/hash djb2 $(@D)$(modname)) //利用djb2 hash算法,计算modname的DEBUG_HASH
value;
DEBUG_HASH2=$(shell ./scripts/basic/hash r5 $(@D)$(modname)) //利用r5 hash算法,计算modname的DEBUG_HASH2
value;
d. 分析 kernel/scripts/basic/hash.c,会生成out/target/product/lotus/obj/kernel/scripts/basic/hash,
shell可执行文件
e. 在编译连接完成后,该 descriptor
值会被保存到 data section的 __verbose区
5. dynamic_debug_init@kernel/lib/dynamic_debug.c
a. dir = debugfs_create_dir("dynamic_debug", NULL);
b. file = debugfs_create_file("control", 0644, dir, NULL, &ddebug_proc_fops); //在debugfs文件系统中创建dynamic_debug/control
文件
c. 通过__start___verbose和__stop___verbose@kernel/include/asm-generic/vmlinux.lds.h中,实际上是获取保存在__verbose区的
struct _ddebug 数据(就是前面编译后添加到data section的__verbose)
d. 如果是不同的modname,就添加到ddebug_tables
中,也就是所有dynamic_dev_dbg的模块(modname),文件(__FILE__),行(__LINE__),函数(__func__),是否输出的flag,对应的hash
value都会逐条保存到ddebug_tables中
6. 分析 echo -n 'file ab8500_charger.c +p' > /data/debugfs/dynamic_debug/control
的实际操作
a. 通过system call,debugfs文件系统会调用到ddebug_proc_write,ddebug_parse_query和ddebug_parse_flags@kernel/lib/dynamic_debug.c分析传入的参数字符串
b. 在ddebug_change@kernel/lib/dynamic_debug.c中,会根据modname, __FILE__, __LINE__,
__func__信息在ddebug_tables找到对应的item.
c. 然后根据输入的是 +p或-p ,来标志struct _ddebug中flag字段,还有根据struct
_ddebug中的primary_hash和secondary_hash,来标志global value dynamic_debug_enabled和dynamic_debug_enabled2
对应的位,会在__dynamic_dbg_enabled@kernel/include/linux/dynamic_debug.h用到
7. 分析 #cat /data/debugfs/dynamic_debug/control的实际操作
a. 先ddebug_proc_open中有err = seq_open(file, &ddebug_proc_seqops);应用了seq
file的读写机制
b. 然后seq_read,利用seq file机制逐个读出和显示ddebug_tables中的内容
8. long long dynamic_debug_enabled和dynamic_debug_enabled2@kernel/lib/dynamic_debugc,用于标志某个mod(可包含一个或多个文件,比如ab8500_fg
mod,目前只包含ab8500_fg.c file)是否可以输出debug log的模块.
最多可以标志64*64=4096个dev_debug/dynamic_dev_dbg.
9. 是否输出dev_log/dynamic_dev_dbg的log,
关键是如下判断,@kernel/include/linux/dynamic_debug.h
#define __dynamic_dbg_enabled(dd) ({ \
int __ret = 0; \
if (unlikely((dynamic_debug_enabled & (1LL << DEBUG_HASH)) && \
(dynamic_debug_enabled2 & (1LL << DEBUG_HASH2)))) \
if (unlikely(dd.flags)) \
__ret = 1; \
__ret; })
a.
dynamic_debug_enabled和dynamic_debug_enabled2就是前面分析的是否输出该modname的两个long long的组合标志位
b. DEBUG_HASH和DEBUG_HASH2
如前面所解释
c. dd.flag
默认为_DPRINTK_FLAGS_DEFAULT,但通过debugfs文件系统,最终操作ddebug_proc_write函数,会设置为_DPRINTK_FLAGS_PRIN或_DPRINTK_FLAGS_DEFAULT
10. debugfs 文件系统中的内容保存在那?????内存中,类似proc
11. 小结:如果你需要用到dynamic debug info,
你需要在你的 .c
文件中查看是否用到了dev_log
输出log。
相关文章推荐
- dynamic debug log输出机制
- Android_Log输出的优先级: Verbose,Debug,Info,Warn,Error
- 解读Android LOG机制的实现:(2)JAVA域输出LOG
- 安卓Studio学习笔记---gradle自定义BuildConfig.DEBUG实现在调试输出Log,正式的时候不输出Log
- 【Unity基础知识②】创建C#脚本、Debug.log输出语句
- unity, 对于Debug.Log输出的log,可以双击定位到代码
- android log机制——输出log
- vs输出框用OutputDebugString输出不了log了
- 解决华为手机无法输出Debug级别log的问题
- unity debug.log()富文本输出
- android log机制——输出log【转】
- Cocos2d-x之Log输出机制
- debug 输出log控制
- Unity3D研究院之在发布版本屏蔽Debug.log输出的Log
- 使用 Spring 的 AOP 机制来输出 Log
- 解决华为手机无法输出Debug级别log的问题
- iOS 在Debug下显示log,在Release下屏蔽log输出
- android-基础知识:android调试总结(Log日志输出, Debug, 单元测试)
- DEBUG下输出Log
- 在swift中debug的环境下使用log输出