Step 1: dump_stack_print_info 第一部分主要实现 print info ,函数比较简单,我们直接看代码: void dump_stack_print_info(const char *log_lvl) { printk("%sCPU: %d PID: %d Comm: %.20s %s %s %.*s\n", log_lvl, raw_smp_processor_id(), current->pid, current->comm, print_tainted(), ...
关于内核符号表kallsyms_names可参考我的另一篇文章点击打开链接。 实现应用程序中的dump_stack() 按照如上所述,实现一个用户态程序的dump_stack好像不是什么难事,因为上面说的步骤在用户态都可以完成,程序运行的方式也基本上是相同的。 那我们实现一个dump_stack需要做的事情只有两点: 1. 获得程序当前运行时间点...
dump_stack 的核心功能分为两部分:打印 info 信息和打印调用栈信息。实现主要通过 dump_stack_print_info 和 show_stack 函数完成。dump_stack_print_info 主要负责打印 info 信息,实现逻辑简单,关键在于打印出清晰的调试信息,帮助开发者快速定位问题。show_stack 则是实现调用栈打印的关键。它通过 un...
内核中dump_stack的实现原理(1) —— 栈回溯 环境 Aarch64 Qemu aarch64-linux-gnu-gcc linux-4.14 概述 栈回溯的目的是将函数的调用栈打印出来,对于分析函数调用和debug系统异常会很有帮助。对于Aarch64,x29用于用来当做帧指针,x30用来存放函数返回地址。 正文 原理 首先通过一个简单的程序分析一下栈回溯的原...
内核中dump_stack的实现原理(2) —— symbol 环境 Linux-4.14 Aarch64 正文 在前面的分析中调用print_symbol("PC is at %s\n", instruction_pointer(regs))输出当前PC地址的时候,输出的的内容却是:PC is at demo_init+0xc/0x1000 [demo] 下面分析一下这个函数print_symbol。
通过grep,发现 dump_stack 函数原型存在于 kernel/lib/dump_stack.c 文件中。它的实现流程如下图所示: static void __dump_stack(void){dump_stack_print_info(KERN_DEFAULT);show_stack(NULL, NULL);} 可以看到关键的两个函数分别是dump_stack_print_info和show_stack。其中第一个函数是用来打印 info 信息的...
通过grep,发现 dump_stack 函数原型存在于 kernel/lib/dump_stack.c 文件中(注:笔者使用的是 4.4 版本的代码)。它的实现流程如下图所示: dump_stack 可以看到关键的两个函数分别是 dump_stack_print_info 和 show_stack 。其中第一个函数是用来打印 info 信息的,而第二个函数是用来打印 Call...
Step 1: dump_stack_print_info 第一部分主要实现 print info ,函数比较简单,我们直接看代码: voiddump_stack_print_info(constchar *log_lvl) { printk("%sCPU: %d PID: %d Comm: %.20s %s %s %.*s\n", log_lvl, raw_smp_processor_id(), current->pid, current->comm, ...
在内核中使用dump_stack的时候可以看到如下用法: staticinlinevoidprint_ip_sym(unsignedlongip) { printk("[<%px>] %pS\n", (void*) ip, (void*) ip); } 然后我们就可以看到类似如下的内核log: 可以看到,上面不光输出了运行地址,还把对应的函数名以及偏移地址都列了出来,内核是如何做到的呢?
内核中dump_stack的实现原理(1) —— 栈回溯 环境 Aarch64 Qemu aarch64-linux-gnu-gcc linux-4.14 概述 栈回溯的目的是将函数的调用栈打印出来,对于分析函数调用和debug系统异常会很有帮助。对于Aarch64,x29用于用来当做帧指针,x30用来存放函数返回地址。