dump_stack调用过程【原创】

简介: dump_stack调用: void dump_stack(void){    dump_backtrace(NULL, NULL);} 继续看: static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)...

dump_stack调用:

void dump_stack(void)
{
    dump_backtrace(NULL, NULL);
}

继续看:

static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
{
    unsigned int fp, mode;
    int ok = 1;

    printk("Backtrace: ");

    if (!tsk)
        tsk = current;

    if (regs) {
        fp = regs->ARM_fp;
        mode = processor_mode(regs);
    } else if (tsk != current) {
        fp = thread_saved_fp(tsk);
        mode = 0x10;
    } else {
        asm("mov %0, fp" : "=r" (fp) : : "cc");
        mode = 0x10;
    }

    if (!fp) {
        printk("no frame pointer");
        ok = 0;
    } else if (verify_stack(fp)) {
        printk("invalid frame pointer 0x%08x", fp);
        ok = 0;
    } else if (fp < (unsigned long)end_of_stack(tsk))
        printk("frame pointer underflow");
    printk("\n");

    if (ok)
        c_backtrace(fp, mode);
}
#endif

我们搜索这个 c_backtrace 函数

在arch\arm\lib中 backtrace.S中

#include <linux/linkage.h>
#include <asm/assembler.h>
        .text

@ fp is 0 or stack frame

#define frame    r4
#define sv_fp    r5
#define sv_pc    r6
#define mask    r7
#define offset    r8

ENTRY(c_backtrace)

。。。。

1003:        ldr    r2, [sv_pc, #-4]    @ if stmfd sp!, {args} exists,
        ldr    r3, .Ldsi+4        @ adjust saved 'pc' back one
        teq    r3, r2, lsr #10        @ instruction
        subne    r0, sv_pc, #4        @ allow for mov
        subeq    r0, sv_pc, #8        @ allow for mov + stmia

        ldr    r1, [frame, #-4]    @ get saved lr
        mov    r2, frame
        bic    r1, r1, mask        @ mask PC/LR for the mode
        bl    dump_backtrace_entry

        ldr    r1, [sv_pc, #-4]    @ if stmfd sp!, {args} exists,
        ldr    r3, .Ldsi+4
        teq    r3, r1, lsr #10
        ldreq    r0, [frame, #-8]    @ get sp
        subeq    r0, r0, #4        @ point at the last arg
        bleq    .Ldumpstm        @ dump saved registers

1004:        ldr    r1, [sv_pc, #0]        @ if stmfd sp!, {..., fp, ip, lr, pc}

 

再看这个函数 dump_backtrace_entry

void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
{
#ifdef CONFIG_KALLSYMS
    printk("[<%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));
}

 

【作者】 张昺华
【新浪微博】 张昺华--sky
【twitter】 @sky2030_
【facebook】 张昺华 zhangbinghua
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
目录
相关文章
|
Linux Go SoC
关于S3学习所涉及到的知识(二):Linux设备驱动suspend/resume的顺序
关于S3学习所涉及到的知识(二):Linux设备驱动suspend/resume的顺序
773 0
|
存储 缓存 前端开发
【硬件知识】了解服务器基础硬件组成
【硬件知识】了解服务器基础硬件组成
1202 1
|
Linux C++
【代码片段】Linux C++打印当前函数调用堆栈
【代码片段】Linux C++打印当前函数调用堆栈
497 0
|
数据可视化 Linux 调度
DolphinScheduler【部署 01】分布式可视化工作流任务调度工具DolphinScheduler部署使用实例分享(一篇入门学会使用DolphinScheduler)
DolphinScheduler【部署 01】分布式可视化工作流任务调度工具DolphinScheduler部署使用实例分享(一篇入门学会使用DolphinScheduler)
1547 0
【Linux C 几种锁的性能对比】 1.读写锁 2.互斥锁 3.自旋锁 4.信号量 5.rcu
【Linux C 几种锁的性能对比】 1.读写锁 2.互斥锁 3.自旋锁 4.信号量 5.rcu
|
运维 前端开发 调度
|
关系型数据库 MySQL 程序员
程序员性能之道,从使用perf开始!
程序员性能之道,从使用perf开始!
|
Linux 测试技术
insmod module_param 模块参数
模块参数 引导模块时,可以向它传递参数。要使用模块参数加载模块,这样写: insmod module.ko [param1=value param2=value ...] 为了使用这些参数的值,要在模块中声明变量来保存它们,并在所有函数之外的某个地方使用宏MODULE_PARM(variable, type) 和 MODULE_PARM_DESC(variable, description) 来接收它们。
1919 0
|
NoSQL 安全 Linux
ARM深入理解-hypervisor调试方法一(异常寄存器分析)
ARM深入理解-hypervisor调试方法一(异常寄存器分析)
|
SQL 缓存 分布式计算
HBase查询一张表的数据条数的方法
HBase查询一张表的数据条数的方法
1274 0
HBase查询一张表的数据条数的方法