dump_stack 和 trigger_all_cpu_backtrace

来源:互联网 发布:导出来的sql带双引号 编辑:程序博客网 时间:2024/04/19 17:12
182 /* 
183  * The architecture-independent dump_stack generator
184  */
185 void dump_stack(void)     
186 {  
187     unsigned long bp;     
188     unsigned long stack;  
189                           
190     bp = stack_frame(current, NULL); //在这边得到当前进程的 bp 值。
191     printk("Pid: %d, comm: %.20s %s %s %.*s\n",
192         current->pid, current->comm, print_tainted(),
193         init_utsname()->release,       
194         (int)strcspn(init_utsname()->version, " "),
195         init_utsname()->version);      
196     show_trace(NULL, NULL, &stack, bp);// 打印出函数调用栈,见下面
197 }  


171 void show_trace(struct task_struct *task, struct pt_regs *regs,
172         unsigned long *stack, unsigned long bp) 
173 {  
174     show_trace_log_lvl(task, regs, stack, bp, "");
175 }  


163 void 164 show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
165         unsigned long *stack, unsigned long bp, char *log_lvl)
166 {
167     printk("%sCall Trace:\n", log_lvl);
168     dump_trace(task, regs, stack, bp, &print_trace_ops, log_lvl);// 说明dump_trace 是跟踪单个 cpu的。

169 }

 20 void dump_trace(struct task_struct *task, struct pt_regs *regs,
 21         unsigned long *stack, unsigned long bp,
 22         const struct stacktrace_ops *ops, void *data)
 23 {
 24     int graph = 0;
 25 
 26     if (!task)
 27         task = current;
 28 
 29     if (!stack) {
 30         unsigned long dummy;
 31 
 32         stack = &dummy;
 33         if (task && task != current)
 34             stack = (unsigned long *)task->thread.sp;
 35     }
 36 
 37     if (!bp)
 38         bp = stack_frame(task, regs);

            for (;;) {
 41         struct thread_info *context;
 42 
 43         context = (struct thread_info *)
 44             ((unsigned long)stack & (~(THREAD_SIZE - 1)));
 45         bp = ops->walk_stack(context, stack, bp, ops, data, NULL, &graph);
 46 
 47         stack = (unsigned long *)context->previous_esp;
 48         if (!stack)
 49             break;
 50         if (ops->stack(data, "IRQ") < 0)
 51             break;
 52         touch_nmi_watchdog();
 53     }
 54 }





 88 unsigned long
 89 print_context_stack(struct thread_info *tinfo,
 90         unsigned long *stack, unsigned long bp,
 91         const struct stacktrace_ops *ops, void *data,
 92         unsigned long *end, int *graph)
 93 {
 94     struct stack_frame *frame = (struct stack_frame *)bp;
 95 
 96     while (valid_stack_ptr(tinfo, stack, sizeof(*stack), end)) {
 97         unsigned long addr;
 98 
 99         addr = *stack;
100         if (__kernel_text_address(addr)) {
101             if ((unsigned long) stack == bp + sizeof(long)) {
102                 ops->address(data, addr, 1);//在此打印,第三个参数为1代表可信,函数定义就是 print_trace_address,
103                 frame = frame->next_frame;
104                 bp = (unsigned long) frame;
105             } else {
106                 ops->address(data, addr, 0);
107             }
108             print_ftrace_graph_addr(addr, data, ops, tinfo, graph);
109         }
110         stack++;
111     }
112     return bp;
113 }


147 /*
148  * Print one address/symbol entries per line.
149  */
150 static void print_trace_address(void *data, unsigned long addr, int reliable)
151 {

/ * touch_nmi_watchdog - restart NMI watchdog timeout.

*
* If the architecture supports the NMI watchdog, touch_nmi_watchdog()
* may be used to reset the timeout - for code which intentionally
* disables interrupts for a long time. This call is stateless.
/

152     touch_nmi_watchdog();
153     printk(data);  //  data为空
154     printk_address(addr, reliable);
155 }


 59 static inline unsigned long
 60 stack_frame(struct task_struct *task, struct pt_regs *regs)
 61 {
 62     unsigned long bp;
 63 
 64     if (regs)
 65         return regs->bp;
 66 
 67     if (task == current) {
 68         /* Grab bp right from our regs */
 69         get_bp(bp);
 70         return bp;
 71     }
 72 
 73     /* bp is the last reg pushed by switch_to */
 74     return *(unsigned long *)task->thread.sp;
 75 }


#define get_bp(bp) asm("movl %%ebp, %0" : "=r" (bp) :)  //学了一招! 把ebp 放到变量  bp 中。




 35 void arch_trigger_all_cpu_backtrace(void)
 36 {
 37     int i;
 38 
 39     if (test_and_set_bit(0, &backtrace_flag))
 40         /*
 41          * If there is already a trigger_all_cpu_backtrace() in progress
 42          * (backtrace_flag == 1), don't output double cpu dump infos.
 43          */
 44         return;
 45 
 46     cpumask_copy(to_cpumask(backtrace_mask), cpu_online_mask);
 47 
 48     printk(KERN_INFO "sending NMI to all CPUs:\n");
 49     apic->send_IPI_all(NMI_VECTOR);
 50 
 51     /* Wait for up to 10 seconds for all CPUs to do the backtrace */
 52     for (i = 0; i < 10 * 1000; i++) {
 53         if (cpumask_empty(to_cpumask(backtrace_mask)))
 54             break;
 55         mdelay(1);
 56     }
 57 
 58     clear_bit(0, &backtrace_flag);
 59     smp_mb__after_clear_bit();
 60 }


0 0
原创粉丝点击