电子商务网站系统规划报告,asp网站做消息提醒功能,菏泽网站建设价格,买了个域名 如何建网站按照栈生长方向分#xff1a;可以分为递增栈#xff08;向高地址生长#xff09;#xff1b;递减栈#xff08;向低地址生长#xff09;
按照sp执行位置来分#xff1a;满栈#xff08;sp指向栈顶元素的位置#xff09;#xff1b;空栈#xff08;sp指向即将入栈的…按照栈生长方向分可以分为递增栈向高地址生长递减栈向低地址生长
按照sp执行位置来分满栈sp指向栈顶元素的位置空栈sp指向即将入栈的元素位置 我这个环境是满减栈 其实通过函数栈推导函数调用过程主要就是结合sp的位置以及汇编代码的压栈信息。找到LR寄存器的位置。
代码示例
起了一个内核线程在函数f3里面会访问空指针然后进入kdb
void f3(void ) {int i 0;int* addr NULL; for (i 0; i 10; i){printk(%d\n, i);}*addr 0x123;return;
}
void f2(int a, int b) {int d 0;int *addr 0;f3();d a b;printk(%d, %p\n, d, addr);return;
}void f1(int a, int b) {int c 0;c a b;f2(c,20);while (c 0){ printk(%d\n, c);--c;}return;
}
struct timer_list timer;
spinlock_t mylock;
static struct task_struct *test_task;
int test_thread(void* a)
{unsigned long flags;printk(KERN_EMERG \r\n softlockup simulate, in_interrupt %u in_softirq %u, cpu id %d\n, in_interrupt(), in_softirq(), smp_processor_id());/*local_irq_disable();while (1){}*/f1(10, 20);return 0;
}
对应的汇编代码如下
void f3(void ) {3ed0: e92d4010 push {r4, lr}int i 0;int* addr NULL; for (i 0; i 10; i)3ed4: e3a04000 mov r4, #0{printk(%d\n, i);3ed8: e1a01004 mov r1, r43edc: e59f001c ldr r0, [pc, #28] ; 3f00 f30x30dev-dev_addr[5] (u8)(mac_high16 8);
}
void f3(void ) {int i 0;int* addr NULL; for (i 0; i 10; i)3ee0: e2844001 add r4, r4, #1{printk(%d\n, i);3ee4: ebfffffe bl 0 printkdev-dev_addr[5] (u8)(mac_high16 8);
}
void f3(void ) {int i 0;int* addr NULL; for (i 0; i 10; i)3ee8: e354000a cmp r4, #103eec: 1afffff9 bne 3ed8 f30x8{printk(%d\n, i);}*addr 0x123;3ef0: e3a03000 mov r3, #03ef4: e3002123 movw r2, #291 ; 0x1233ef8: e5832000 str r2, [r3]3efc: e8bd8010 pop {r4, pc}3f00: 0000034c .word 0x0000034c00003f04 f2:return;
}
void f2(int a, int b) {3f04: e92d4038 push {r3, r4, r5, lr}3f08: e1a04000 mov r4, r03f0c: e1a05001 mov r5, r1int d 0;int *addr 0;f3();3f10: ebfffffe bl 3ed0 f3d a b;printk(%d, %p\n, d, addr);3f14: e0841005 add r1, r4, r53f18: e3000000 movw r0, #03f1c: e3a02000 mov r2, #03f20: e3400000 movt r0, #0return;
}3f24: e8bd4038 pop {r3, r4, r5, lr}
void f2(int a, int b) {int d 0;int *addr 0;f3();d a b;printk(%d, %p\n, d, addr);3f28: eafffffe b 0 printk00003f2c f1:return;
}void f1(int a, int b) {3f2c: e92d4010 push {r4, lr}int c 0;c a b;3f30: e0804001 add r4, r0, r1f2(c,20);3f34: e3a01014 mov r1, #203f38: e1a00004 mov r0, r43f3c: ebfffffe bl 3f04 f2while (c 0)3f40: e3540000 cmp r4, #03f44: d8bd8010 pople {r4, pc}{ printk(%d\n, c);3f48: e1a01004 mov r1, r43f4c: e59f000c ldr r0, [pc, #12] ; 3f60 f10x343f50: ebfffffe bl 0 printkvoid f1(int a, int b) {int c 0;c a b;f2(c,20);while (c 0)3f54: e2544001 subs r4, r4, #13f58: 1afffffa bne 3f48 f10x1c3f5c: e8bd8010 pop {r4, pc}3f60: 0000034c .word 0x0000034c00003f64 test_thread:
}
struct timer_list timer;
spinlock_t mylock;
static struct task_struct *test_task;
int test_thread(void* a)
{3f64: e92d4008 push {r3, lr}3f68: e1a0200d mov r2, sp3f6c: e3c23d7f bic r3, r2, #8128 ; 0x1fc0unsigned long flags;printk(KERN_EMERG \r\n softlockup simulate, in_interrupt %u in_softirq %u, cpu id %d\n, in_interrupt(), in_softirq(), smp_processor_id());3f70: e3a01cff mov r1, #65280 ; 0xff003f74: e3c3303f bic r3, r3, #63 ; 0x3f3f78: e340101f movt r1, #313f7c: e3000000 movw r0, #03f80: e3400000 movt r0, #03f84: e5932004 ldr r2, [r3, #4]3f88: e5933014 ldr r3, [r3, #20]3f8c: e0021001 and r1, r2, r13f90: e2022cff and r2, r2, #65280 ; 0xff003f94: ebfffffe bl 0 printk/*local_irq_disable();while (1){}*/f1(10, 20);3f98: e3a0000a mov r0, #103f9c: e3a01014 mov r1, #203fa0: ebfffffe bl 3f2c f1return 0;
}3fa4: e3a00000 mov r0, #03fa8: e8bd8008 pop {r3, pc}
从上面的汇编代码可以看到每个函数的入栈信息如下。假设函数f3里面的栈顶指针为 sp_f3 完整的异常log如下 Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd c0004000
[00000000] *pgd00000000
Internal error: Oops: 817 [#1] SMP ARMEntering kdb (current0xeea2e880, pid 649) on processor 3 Oops: (null)
due to oops 0xc03087a8dCPU: 3 PID: 649 Comm: test_task Not tainted 3.16.0 #65
dtask: eea2e880 ti: ee226000 task.ti: ee226000
PC is at f30x28/0x34
LR is at f30x18/0x34
pc : [c03087a8] lr : [c0308798] psr: 60000013
sp : ee227f40 ip : 00000001 fp : 00000000
r10: 00000000 r9 : 00000000 r8 : 00000000
r7 : c0308814 r6 : 00000000 r5 : 00000014 r4 : 0000000a
r3 : 00000000 r2 : 00000123 r1 : 20000093 r0 : 00000001
Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel
Control: 10c53c7d Table: 8e30006a DAC: 00000015
dCPU: 3 PID: 649 Comm: test_task Not tainted 3.16.0 #65
[c0014320] (unwind_backtrace) from [c0010fa4] (show_stack0x10/0x14)
[c0010fa4] (show_stack) from [c045cc6c] (dump_stack0x74/0x90)
[c045cc6c] (dump_stack) from [c00823f4] (kdb_dumpregs0x30/0x50)
[c00823f4] (kdb_dumpregs) from [c0084754] (kdb_main_loop0x31c/0x70c)
[c0084754] (kdb_main_loop) from [c0087128] (kdb_stub0x1e0/0x44c)
[c0087128] (kdb_stub) from [c007dbac] (kgdb_cpu_enter0x3c4/0x6e0)
[c007dbac] (kgdb_cpu_enter) from [c007e150] (kgdb_handle_exception0x168/0x1d0)
[c007e150] (kgdb_handle_exception) from [c0013998] (kgdb_notify0x24/0x3c)
[c0013998] (kgdb_notify) from [c003f95c] (notifier_call_chain0x44/0x84)
[c003f95c] (notifier_call_chain) from [c003f9b4] (__atomic_notifier_call_chain0x18/0x20)
[c003f9b4] (__atomic_notifier_call_chain) from [c003f9d4] (atomic_notifier_call_chain0x18/0x20)
[c003f9d4] (atomic_notifier_call_chain) from [c0040108] (notify_die0x3c/0x44)
[c0040108] (notify_die) from [c0011090] (die0xe8/0x2c8)
[c0011090] (die) from [c0459e8c] (__do_kernel_fault.part.80x54/0x74)
[c0459e8c] (__do_kernel_fault.part.8) from [c0019a28] (do_page_fault0x1a8/0x3a4)
[c0019a28] (do_page_fault) from [c00084dc] (do_DataAbort0x34/0x98)
[c00084dc] (do_DataAbort) from [c0011a18] (__dabt_svc0x38/0x60)
Exception stack(0xee227ef8 to 0xee227f40)
7ee0: 00000001 20000093
7f00: 00000123 00000000 0000000a 00000014 00000000 c0308814 00000000 00000000
7f20: 00000000 00000000 00000001 ee227f40 c0308798 c03087a8 60000013 ffffffff
[c0011a18] (__dabt_svc) from [c03087a8] (f30x28/0x34)
[c03087a8] (f3) from [c03087c4] (f20x10/0x28)
[c03087c4] (f2) from [c03087f0] (f10x14/0x38)
[c03087f0] (f1) from [c0308854] (test_thread0x40/0x48)
[c0308854] (test_thread) from [c003c4fc] (kthread0xcc/0xe8)
[c003c4fc] (kthread) from [c000e4f8] (ret_from_fork0x14/0x3c)从异常log我们可以知道f3的栈顶指针为 sp : ee227f40
f2的返回地址为ee227f40 4指向的地址里面的内容 同理一级一级往上推 c03087c4 0xc03087c4 (f20x10) c03087f0 0xc03087f0 (f10x14) c0308854 0xc0308854 (test_thread0x40) c003c4fc 0xc003c4fc (kthread0xcc) 和异常log里面的一样 [c03087a8] (f3) from [c03087c4] (f20x10/0x28) [c03087c4] (f2) from [c03087f0] (f10x14/0x38) [c03087f0] (f1) from [c0308854] (test_thread0x40/0x48) [c0308854] (test_thread) from [c003c4fc] (kthread0xcc/0xe8) [c003c4fc] (kthread) from [c000e4f8] (ret_from_fork0x14/0x3c) 另外也可以用命令mds直接查看