ARM 架构 dump_stack 实现分析(3.0 printk %pS选项实现)
2013-11-15 22:43
274 查看
上篇提到了函数:
实际打印的却类似下面的语句:
symbol<bf00c0c4>] (handler_pre+0x0/0x19c [kk]) from [<c063d174>] (kprobe_handler+0x194/0x234)
明明只是传入了一个PC指针而已,却可以打印出函数名字及偏移量。
查看了源码,发现是printk的功劳。
参考: kernel/lib/vsprintf
kernel/kernel/printk
回顾下printk实现:
printk
-->vprintk
-->vsnprintf (格式话,及做更多功能)
* This function follows C99 vsnprintf, but has some extensions:
* %pS output the name of a text symbol with offset 关键在这两个格式化选项
* %ps output the name of a text symbol without offset
* %pF output the name of a function pointer with its offset
* %pf output the name of a function pointer without its offset
* %pB output the name of a backtrace symbol with its offset
* %pR output the address range in a struct resource with decoded flags
* %pr output the address range in a struct resource with raw flags
* %pM output a 6-byte MAC address with colons
* %pm output a 6-byte MAC address without colons
* %pI4 print an IPv4 address without leading zeros
* %pi4 print an IPv4 address with leading zeros
* %pI6 print an IPv6 address with colons
* %pi6 print an IPv6 address without colons
* %pI6c print an IPv6 address as specified by RFC 5952
* %pU[bBlL] print a UUID/GUID in big or little endian using lower or upper
* case.
* %n is ignored
参考: kernel/kernel/kallsyms.c
呵呵,有时间好好看看kallsyms_lookup的实现
void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame) { #ifdef CONFIG_KALLSYMS //记住%pS是关键 printk 与 普通printf最大的不同 //惭愧啊,现在才知道此选项 printk("symbol<%08lx>] (%pS) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from); #else printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from); #endif if (in_exception_text(where)) dump_mem("", "Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs)); }
实际打印的却类似下面的语句:
symbol<bf00c0c4>] (handler_pre+0x0/0x19c [kk]) from [<c063d174>] (kprobe_handler+0x194/0x234)
明明只是传入了一个PC指针而已,却可以打印出函数名字及偏移量。
查看了源码,发现是printk的功劳。
参考: kernel/lib/vsprintf
kernel/kernel/printk
回顾下printk实现:
printk
-->vprintk
-->vsnprintf (格式话,及做更多功能)
* This function follows C99 vsnprintf, but has some extensions:
* %pS output the name of a text symbol with offset 关键在这两个格式化选项
* %ps output the name of a text symbol without offset
* %pF output the name of a function pointer with its offset
* %pf output the name of a function pointer without its offset
* %pB output the name of a backtrace symbol with its offset
* %pR output the address range in a struct resource with decoded flags
* %pr output the address range in a struct resource with raw flags
* %pM output a 6-byte MAC address with colons
* %pm output a 6-byte MAC address without colons
* %pI4 print an IPv4 address without leading zeros
* %pi4 print an IPv4 address with leading zeros
* %pI6 print an IPv6 address with colons
* %pi6 print an IPv6 address without colons
* %pI6c print an IPv6 address as specified by RFC 5952
* %pU[bBlL] print a UUID/GUID in big or little endian using lower or upper
* case.
* %n is ignored
int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) { ... case FORMAT_TYPE_PTR: //格式化为函数名+偏移量 str = pointer(fmt+1, str, end, va_arg(args, void *), spec); //传入的必须是函数指针或地址 (text段) while (isalnum(*fmt)) fmt++; break; }
char *pointer(const char *fmt, char *buf, char *end, void *ptr, struct printf_spec spec) { ...... switch (*fmt) { case 'S': case 's': case 'B': return symbol_string(buf, end, ptr, spec, *fmt); }
char *symbol_string(char *buf, char *end, void *ptr, struct printf_spec spec, char ext) { unsigned long value = (unsigned long) ptr; // 函数名不能超过此长度,否则可能数组越界,导致奇怪问题的产生 char sym[KSYM_SYMBOL_LEN]; //真正去查找函数名的实现 kallsyms_lookup(value, NULL, NULL, NULL, sym); return string(buf, end, sym, spec); }
参考: kernel/kernel/kallsyms.c
呵呵,有时间好好看看kallsyms_lookup的实现
相关文章推荐
- ARM 架构 dump_stack 实现分析(2.0 调用时序)
- ARM 架构 dump_stack 实现分析(1.0 具体实例)
- dump_stack 实现分析【转】
- 从架构上分析,为什么X86架构比ARM更难实现低功耗?
- 云计算的技术架构与实现分析
- ARM架构内核启动分析-head.S(1.3、stext分析之内存临时页表建立)
- tiny4412 串口驱动分析二 --- printk的实现
- arm-linux-androideabi-gcc 4.8的选项分析
- .NET三层经典架构PetShop3.0分析之表现层---3
- 一个App架构例子分析--UI层使用MVP模式;各层之间使用Otto实现通信
- dump 分析模式之 INCORRECT STACK TRACE - djm2005dy的专栏 - 博客频道 - CSDN.NET
- 分布式架构学习之:032--使用Redis3.0集群实现Tomcat集群的Session共享
- ucOS-II基于ARM920T的OSCtxSw实现分析
- OpenStack建立实例完整过程源码详细分析(12)----依据AMQP通信架构实现消息发送机制解析之一
- OpenStack建立实例完整过程源码详细分析(15)----依据AMQP通信架构实现消息接收机制解析之二
- TI Z-Stack协议栈架构分析
- 关于ARM架构下ucos2任务切换函数OSCtxSw源码分析
- 【前端】Popush前端架构分析&注册后自动登录的实现
- .NET三层经典架构PetShop3.0分析连载一
- linux内核中打印栈回溯信息 - dump_stack()函数分析