代码网站怎么做的,wordpress 资讯模板,计算机网站建设论文.,手机排行榜结合上面的知识#xff0c;看下当内核打印堆栈信息时#xff0c;都打印了上面信息。下面的打印信息是工作中遇到的一种情况#xff0c;打印了内核的堆栈信息#xff0c;PC指针在dev_get_by_flags中#xff0c;不能访问的内核虚地址为45685516#xff0c;内核中一般可访问…结合上面的知识看下当内核打印堆栈信息时都打印了上面信息。下面的打印信息是工作中遇到的一种情况打印了内核的堆栈信息PC指针在dev_get_by_flags中不能访问的内核虚地址为45685516内核中一般可访问的地址都是以0xCXXXXXXX开头的地址。Unableto handle kernel paging request atvirtualaddress45685516pgdc65a4000[45685516]*pgd00000000Internalerror:Oops:1[#1]lastsysfs file:/sys/devices/form/tpm/cfg_l3/l3_rule_addModuleslinkedin:splic mmp(P)CPU:0Tainted:P(2.6.32.11#42)PCisat dev_get_by_flags0xfc/0x140LRisat dev_get_by_flags0xe8/0x140pc:[]lr:[]psr:20000013sp:c07e9c28 ip:00000000fp:c07e9c64r10:c6bcc560 r9:c646a220 r8:c66a0000r7:c6a00000 r6:c0204e56 r5:30687461r4:45685516r3:00000000r2:00000010r1:c0204e56 r0:ffffffffFlags:nzCvIRQsonFIQsonModeSVC_32 ISA ARMSegmentkernelControl:0005397fTable:065a4000DAC:00000017Processswapper(pid:0,stack limit0xc07e8270)Stack:(0xc07e9c28to0xc07ea000)9c20:c0204e56 c6a0000045685516c69ffff0 c69ffff0 c69ffff09c40:c6a0000030687461c66a0000 c6a0000000000007c64b210c c07e9d24 c07e9c689c60:c071f764 c06bed38 c66a0000 c66a0000 c6a00000 c6a00000 c66a0000 c6a000009c80:c07e9cfc c07e9c90 c03350d4 c0334b2c000000340000000600000100c64b21049ca0:0000c4fbc0243ece c66a0000 c0beed04 c033436c c646a220 c07e9cf4000000009cc0:c66a000000000003c0bee8e8 c0beed04 c07e9d24 c07e9ce0 c06e4f5c00004c689ce0:00000000faa9fea9 faa9fea90000000000000000c6bcc560 c0335138 c646a2209d00:c66a0000 c64b2104 c085ffbc c66a0000 c0bee8e800000000c07e9d54 c07e9d289d20:c071f9a0 c071ebc000000000c071ebb08000000000000007c67fb460 c646a2209d40:c0bee8c800000608c07e9d94 c07e9d58 c002a100 c071f84c c0029bb8800000009d60:c07e9d84 c0beee0c c0335138 c66a0000 c646a22000000000c4959800 c49598009d80:c67fb46000000000c07e9dc4 c07e9d98 c078f0f4 c0029bc800000000c0029bb89da0:80000000c07e9dbc c6b8d340 c66a052000000000c646a220 c07e9dec c07e9dc89dc0:c078f450 c078effc00000000c67fb460 c6b8d34000000000c67fb460 c64b20f29de0:c07e9e24 c07e9df0 c078fb60 c078f13000000000c078f12080000000c0029a949e00:00000806c6b8d340 c0bee8180000000100000000c4959800 c07e9e64 c07e9e289e20:c002a030 c078f804 c64b207000000000c64b2078 ffc45000 c64b20c2 c085c2dc9e40:00000000c085c2c000000000c081739800086c2ec085c2c4 c07e9e9c c07e9e689e60:c06c2684 c0029bc8000000010000004000000000c085c2dc c085c2c0000000019e80:0000012c00000040c085c2d0 c0bee818 c07e9ed4 c07e9ea0 c00284e0 c06c26089ea0:bf00da5c00086c300000000000000001c097e7d4 c07e800000000100c08162d89ec0:00000002c097e7a0 c07e9f14 c07e9ed8 c00283d0 c00284785625131100023c889ee0:c07e9f0c00000003c08187ac000000180000000001000000c07ebc7000023cbc9f00:5625131100023c88c07e9f24 c07e9f18 c03391e8 c0028348 c07e9f3c c07e9f289f20:c0028070 c03391b0 ffffffff0000001fc07e9f94 c07e9f40 c002d4d0 c00280109f40:0000000000000001c07e9f8860000013c07e8000 c07ebc78 c0868784 c07ebc709f60:00023cbc5625131100023c88c07e9f94 c07e9f98 c07e9f88 c025c3e4 c025c3f49f80:60000013ffffffff c07e9fb4 c07e9f98 c025c578 c025c3cc00000000c09812049fa0:c0025ca0 c0d01140 c07e9fc4 c07e9fb8 c0032094 c025c528 c07e9ff4 c07e9fc89fc0:c0008918 c0032048 c00083880000000000000000c0025ca000000000000539759fe0:c0868834 c00260a400000000c07e9ff800008034c00087080000000000000000Backtrace:[](dev_get_by_flags0x0/0x140)from[](arp_process0xbb4/0xc74)r7:c64b210c r6:00000007r5:c6a00000 r4:c66a0000(1)首先看看这段堆栈信息是在内核中那个文件中打印出来的在fault.c文件中__do_kernel_fault函数在上面的打印中Unable to handle kernel paging request at virtual address 45685516该地址是内核空间不可访问的地址。staticvoid__do_kernel_fault(structmm_struct*mm,unsignedlongaddr,unsignedintfsr,structpt_regs*regs){/** Are we prepared to handle this kernel fault?*/if(fixup_exception(regs))return;/** No handler, well have to terminate things with extreme prejudice.*/bust_spinlocks(1);printk(KERN_ALERTUnable to handle kernel %s at virtual address %08lx\n,(addrshow_pte(mm,addr);die(Oops,regs,fsr);bust_spinlocks(0);do_exit(SIGKILL);}(2) 对于下面的两个信息在函数show_pte中进行了打印下面的打印涉及到了页全局目录页表的知识暂时先不分析后续补上。pgdc65a4000[45685516]*pgd00000000voidshow_pte(structmm_struct*mm,unsignedlongaddr){pgd_t*pgd;if(!mm)mminit_mm;printk(KERN_ALERTpgd %p\n,mm-pgd);pgdpgd_offset(mm,addr);printk(KERN_ALERT[%08lx] *pgd%08lx,addr,pgd_val(*pgd));……………………}(3) die函数中调用在die函数中取得thread_info结构体的地址。structthread_info*threadcurrent_thread_info();staticinlinestructthread_info*current_thread_info(void){registerunsignedlongspasm(sp);return(structthread_info*)(sp~(THREAD_SIZE-1));}Sp: 0xc07e9c28 通过current_thread_info得到 thread_info的地址(0xc07e9c28 0xffffe000) 0xC07E8000(thread_info的地址也就是栈底的地址)(4)下面的打印信息在__die函数中打印Internalerror:Oops:1[#1]lastsysfs file:/sys/devices/form/tpm/cfg_l2/l2_rule_addModuleslinkedin:splic mmp(P)CPU:0Tainted:P(2.6.32.11#42)PCisat dev_get_by_flags0xfc/0x140LRisat dev_get_by_flags0xe8/0x140pc:[]lr:[]psr:20000013sp:c07e9c28 ip:00000000fp:c07e9c64r10:c6bcc560 r9:c646a220 r8:c66a0000r7:c6a00000 r6:c0204e56 r5:30687461r4:30687461r3:00000000r2:00000010r1:c0204e56 r0:ffffffffFlags:nzCvIRQsonFIQsonModeSVC_32 ISA ARMSegmentkernelControl:0005397fTable:065a4000DAC:00000017Processswapper(pid:0,stack limit0xc07e8270)Stack:(0xc07e9c28to0xc07ea000)函数的调用关系die(Oops, regs, fsr);---à __die(str, err, thread, regs);下面是__die函数的定义staticvoid__die(constchar*str,interr,structthread_info*thread,structpt_regs*regs){structtask_struct*tskthread-task;staticintdie_counter;/*Internal error: Oops: 1 [#1]*/printk(KERN_EMERGInternal error: %s: %x [#%d]S_PREEMPT S_SMP\n,str,err,die_counter);/*last sysfs file: /sys/devices/form/tpm/cfg_l2/l2_rule_add*/sysfs_printk_last_file();/*内核中加载的模块信息Modules linked in: splic mmp(P) */print_modules();/*打印寄存器信息*/__show_regs(regs);/*Process swapper (pid: 0, stack limit 0xc07e8270) tsk-comm task_struct结构体中的comm表示的是除去路径后的可执行文件名称这里的swapper为idle进程进程号为0创建内核进程init其中stack limit 0xc07e8270 指向thread_info的结束地址。*/printk(KERN_EMERGProcess %.*s (pid: %d, stack limit 0x%p)\n,TASK_COMM_LEN,tsk-comm,task_pid_nr(tsk),thread1);/* dump_mem 函数打印从栈顶到当前sp之间的内容*/if(!user_mode(regs)||in_interrupt()){dump_mem(KERN_EMERG,Stack: ,regs-ARM_sp,THREAD_SIZE(unsignedlong)task_stack_page(tsk));dump_backtrace(regs,tsk);dump_instr(KERN_EMERG,regs);}}在上面的函数中主要使用了thread_info,task_struct,sp之间的指向关系。task_struct结构体的成员stack是栈底也是对应thread_info结构体的地址。堆栈数据是从栈底8K的地方开始向下存的。SP指向的是当前的栈顶。(unsigned long)task_stack_page(tsk)#define task_stack_page(task) ((task)-stack) 该宏根据task_struct得到栈底也就是thread_info地址。#define task_thread_info(task) ((struct thread_info *)(task)-stack)该宏根据task_struct得到thread_info指针。(5)dump_backtrace函数该函数用于打印函数的调用关系。Fp为帧指针用于追溯程序的方式方向跟踪调用函数。该函数主要是fp进行检查看看能否进行backtrace如果可以就调用汇编的c_backtrace在arch/arm/lib/backtrace.S函数中。staticvoiddump_backtrace(structpt_regs*regs,structtask_struct*tsk){unsignedintfp,mode;intok1;printk(Backtrace: );if(!tsk)tskcurrent;if(regs){fpregs-ARM_fp;modeprocessor_mode(regs);}elseif(tsk!current){fpthread_saved_fp(tsk);mode0x10;}else{asm(mov %0, fp:r(fp)::cc);mode0x10;}if(!fp){printk(no frame pointer);ok0;}elseif(verify_stack(fp)){printk(invalid frame pointer 0x%08x,fp);ok0;}elseif(fpprintk(frame pointer underflow);printk(\n);if(ok)c_backtrace(fp,mode);}(6)dump_instr根据PC指针和指令mode, 打印出当前执行的指令码Code: 0a000008 e5944000 e2545000 0a000005 (e4153010)内核中函数的调用关系Linux Kernel 的详细介绍请点这里Linux Kernel 的下载地址请点这里