arm栈推导

按照栈生长方向分:可以分为递增栈(向高地址生长);递减栈(向低地址生长)

按照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 <f3+0x30>dev->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 <printk>dev->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 <f3+0x8>{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 <f3>d = 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 <printk>00003f2c <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 <f2>while (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 <f1+0x34>3f50:	ebfffffe 	bl	0 <printk>void 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 <f1+0x1c>3f5c:	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 <f1>return 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] *pgd=00000000
Internal error: Oops: 817 [#1] SMP ARMEntering kdb (current=0xeea2e880, 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 f3+0x28/0x34
LR is at f3+0x18/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_stack+0x10/0x14)
[<c0010fa4>] (show_stack) from [<c045cc6c>] (dump_stack+0x74/0x90)
[<c045cc6c>] (dump_stack) from [<c00823f4>] (kdb_dumpregs+0x30/0x50)
[<c00823f4>] (kdb_dumpregs) from [<c0084754>] (kdb_main_loop+0x31c/0x70c)
[<c0084754>] (kdb_main_loop) from [<c0087128>] (kdb_stub+0x1e0/0x44c)
[<c0087128>] (kdb_stub) from [<c007dbac>] (kgdb_cpu_enter+0x3c4/0x6e0)
[<c007dbac>] (kgdb_cpu_enter) from [<c007e150>] (kgdb_handle_exception+0x168/0x1d0)
[<c007e150>] (kgdb_handle_exception) from [<c0013998>] (kgdb_notify+0x24/0x3c)
[<c0013998>] (kgdb_notify) from [<c003f95c>] (notifier_call_chain+0x44/0x84)
[<c003f95c>] (notifier_call_chain) from [<c003f9b4>] (__atomic_notifier_call_chain+0x18/0x20)
[<c003f9b4>] (__atomic_notifier_call_chain) from [<c003f9d4>] (atomic_notifier_call_chain+0x18/0x20)
[<c003f9d4>] (atomic_notifier_call_chain) from [<c0040108>] (notify_die+0x3c/0x44)
[<c0040108>] (notify_die) from [<c0011090>] (die+0xe8/0x2c8)
[<c0011090>] (die) from [<c0459e8c>] (__do_kernel_fault.part.8+0x54/0x74)
[<c0459e8c>] (__do_kernel_fault.part.8) from [<c0019a28>] (do_page_fault+0x1a8/0x3a4)
[<c0019a28>] (do_page_fault) from [<c00084dc>] (do_DataAbort+0x34/0x98)
[<c00084dc>] (do_DataAbort) from [<c0011a18>] (__dabt_svc+0x38/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>] (f3+0x28/0x34)
[<c03087a8>] (f3) from [<c03087c4>] (f2+0x10/0x28)
[<c03087c4>] (f2) from [<c03087f0>] (f1+0x14/0x38)
[<c03087f0>] (f1) from [<c0308854>] (test_thread+0x40/0x48)
[<c0308854>] (test_thread) from [<c003c4fc>] (kthread+0xcc/0xe8)
[<c003c4fc>] (kthread) from [<c000e4f8>] (ret_from_fork+0x14/0x3c)

 

从异常log我们可以知道f3的栈顶指针为 sp : ee227f40

f2的返回地址为ee227f40 + 4指向的地址里面的内容

同理一级一级往上推

 

 

 c03087c4 = 0xc03087c4 (f2+0x10)

c03087f0 = 0xc03087f0 (f1+0x14)
c0308854 = 0xc0308854 (test_thread+0x40)
c003c4fc = 0xc003c4fc (kthread+0xcc)

和异常log里面的一样
[<c03087a8>] (f3) from [<c03087c4>] (f2+0x10/0x28)
[<c03087c4>] (f2) from [<c03087f0>] (f1+0x14/0x38)
[<c03087f0>] (f1) from [<c0308854>] (test_thread+0x40/0x48)
[<c0308854>] (test_thread) from [<c003c4fc>] (kthread+0xcc/0xe8)
[<c003c4fc>] (kthread) from [<c000e4f8>] (ret_from_fork+0x14/0x3c)

另外也可以用命令mds直接查看 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/106384.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ChatGPT AIGC总结Excel中Vlookup,lookup,xlookup的区别

在Excel的使用过程中,查找函数是非常重要的,如Vlookup,lookup,Xlookup,index+match等都是使用的最多的函数,我们让ChatGPT,AIGC用思维导图来总结一下,各查找函数的用法与区别。 AIGC ChatGPT ,BI商业智能, 可视化Tableau, PowerBI, FineReport, 数据库Mysql Oracle…

驱动测试开发

测试驱动开发介绍 测试驱动开发&#xff08;Test Driven Development,英文缩写TDD&#xff09;是极限编程的一个重要组成部分它的基本思想就是在开发功能代码之前&#xff0c;先编写测试代码也就是说在明确要开发某个功能后 首先思考如何对这个功能进行测试&#xff0c;并完成…

我们这一代人的机会是什么?

大家好&#xff0c;我是苍何&#xff0c;今天作为专业嘉宾参观了 2023 年中国国际智能产业博览会&#xff08;智博会&#xff09;&#xff0c;是一场以「智汇八方&#xff0c;博采众长」为主题的汇聚全球智能技术和产业创新的盛会&#xff0c;感触颇深&#xff0c;随着中国商业…

linux入门---用匿名管道实现一个功能

前言 在之前的学习中我们知道通信的概念和匿名管道的使用&#xff0c;那么接下来我们就要用匿名管道来实现一个功能&#xff0c;首先我们有很多的函数需要被执行&#xff0c;然后创建一些子进程通过匿名管道方式给子进程传递一些信息&#xff0c;然后子进程就根据这些信息来确…

Grafana配置邮件告警

1、创建一个监控图 2、grafana邮件配置 vim /etc/grafana/grafana.ini [smtp] enabled true host smtp.163.com:465 user qinziteng05163.com password xxxxx # 授权码 from_address qinziteng05163.com from_name Grafanasystemctl restart grafana-serv…

优化SOCKS5的方法

在今天的互联网世界中&#xff0c;保护个人隐私和提升网络速度至关重要。作为一种常用的代理协议&#xff0c;SOCKS5代理服务器不仅可以保护您的隐私&#xff0c;还可以实现更快速的网络访问。本文将为您介绍一些优化SOCKS5代理服务器的方法&#xff0c;以提高网络速度和安全性…

工作不好找,普通打工人如何破局

大家好&#xff0c;我是苍何&#xff0c;我的一位阿里朋友被裁后&#xff0c;找工作找了一个月都没结果&#xff0c;很多到最后一面被pass了&#xff0c;不由得做一下感慨&#xff0c;即使是大厂背景又如何&#xff0c;面对经济环境和大环境市场&#xff0c;每个人都不容易。 …

【Redis】Redis 的学习教程(九)之 发布 Pub、订阅 Sub

1. Pub/Sub 介绍 Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式是一种消息传递机制&#xff0c;它允许在发送者和接收者之间建立松耦合的通信关系。在这种模式中&#xff0c;发送者&#xff08;发布者&#xff09;将消息发布到一个指定的频道或模式&#xff0c;而接收…

数据结构--二叉树-堆(1)

文章目录 树概念相关的基本概念树的表示 二叉树概念特殊二叉树性质 堆二叉树的顺序结构堆的概念 堆的实现初始化数组初始化为堆向上调整向下调整插入删除打印、摧毁、判空、获取堆顶数据验证 堆的应用堆排序TopK问题 树 概念 树是一种常见的非线性的数据结构&#xff0c;&…

Linux 6.6 初步支持AMD 新一代 Zen 5 处理器

AMD 下一代 Zen 5 CPU 现已开始为 Linux 6.6 支持提交相关代码&#xff0c;最新补丁包括提供温度监控和 EDAC 报告等。 最新的 Linux 6.6 代码中已经加入了包括支持硬件监视器温度监控和 EDAC 报告的补丁。此外&#xff0c;新版本还加入了 x86 / misc 补丁&#xff0c;Phoronix…

简单5步骤搞定windows server2019 配置IIS支持PHP

测试成功&#xff0c;记录一笔&#xff0c;感谢网上各位大佬的技术支持。 一、安装vcredist_x64.exe 否则可能会出现 FastCGI进程意外退出 二、IIS开启CGI&#xff08;可能需要重启&#xff09; 控制面板&#xff0c;启用或关闭windows程序&#xff0c;IIS--应用程序开发--CGI…

Android12之/proc/pid/status参数含义(一百六十五)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…