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.mzph.cn/news/81528.shtml

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

相关文章

利用爬虫技术自动化采集汽车之家的车型参数数据

导语 汽车之家是一个专业的汽车网站&#xff0c;提供了丰富的汽车信息&#xff0c;包括车型参数、图片、视频、评测、报价等。如果我们想要获取这些信息&#xff0c;我们可以通过浏览器手动访问网站&#xff0c;或者利用爬虫技术自动化采集数据。本文将介绍如何使用Python编写…

MATLAB中findpeaks函数用法

目录 语法 说明 示例 在MATLAB中&#xff0c;findpeaks函数用于查找信号中的峰值&#xff08;peaks&#xff09;。以下是findpeaks函数的基本语法、说明以及示例&#xff1a; 语法 [pks,locs] findpeaks(x) [pks,locs] findpeaks(x, Name, Value)说明 参数说明 x&…

勒索病毒最新变种.halo勒索病毒来袭,如何恢复受感染的数据?

摘要&#xff1a; .halo勒索病毒已成为数字世界中的威胁&#xff0c;通过高级加密技术将文件锁定&#xff0c;并要求支付赎金。本文91数据恢复将深入介绍.halo勒索病毒的工作原理&#xff0c;提供解锁被感染文件的方法&#xff0c;以及探讨如何有效预防这一威胁。如果您正在经…

87 # express 应用和创建应用的分离

创建应用的过程和应用本身要进行分离。路由和创建应用的过程也做一个分离。 下面实现创建应用的过程和应用本身要进行分离&#xff1a; express.js const Application require("./application");function createApplication() {// 通过类来实现分离操作return ne…

unity UDP 通信

客户端 接收端 &#xff1a; using System; using System.IO; using System.Collections; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using UnityEngine; using UnityEngine.UI;public cla…

常见音视频、流媒体开源编解码库及官网(四十一)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药. 更多原创,欢迎关注:Android…

Unity中Shader抓取屏幕并实现扭曲效果(优化)

文章目录 前言一、在之前顶点着色器的输入中&#xff0c;放弃了使用结构体传入&#xff0c;而是直接从应用程序阶段传入参数&#xff0c;这样写的话&#xff0c;对于程序来说&#xff0c;不方便扩张&#xff0c;所以需要对其进行修改实现1、定义结构体用于传入顶点坐标系2、因为…

开始撸 Android 源码

启动找工作模式&#xff0c;发现无比困难。搁在往日&#xff0c;大龄程序员找工作都是一件困难的事情&#xff0c;加上今年形势很差&#xff0c;更是难上加难。关键是我这十几年来主攻的浏览器内核方向&#xff0c;需求量更是几乎为零。在 BOSS 直聘上以 Chromium 为关键词&…

华为云云耀云服务器L实例评测|Git 私服搭建指南

前言 本文为华为云云耀云服务器L实例测评文章&#xff0c;测评内容是 云耀云服务器L实例 Git 私有服务器搭建指南 系统配置&#xff1a;2核2G 3M Ubuntu 20.04 我们平时在使用代码托管服务的时候&#xff0c;可能某些代码托管平台对成员有限制&#xff0c;或是由于内容原因会对…

教你如何清理 Docker 存储驱动的磁盘占用空间

Author&#xff1a;rab 有时候你会发现&#xff0c;你的 Docker 业务容器虽然做了数据持久化&#xff0c;且数据持久化的磁盘空间占用并不大&#xff0c;但是 Docker 的 Overlay2 目录占用却很大。我们知道 Overlay2 是 Docker 的存储驱动&#xff0c;也是 Docker 默认的存储驱…

Vue Router最佳实践,以确保你的Vue.js应用的路由管理清晰、可维护和高效

文章目录 路由结构设计命名路由动态路由参数导航守卫命名视图 (Named Views)懒加载路由错误处理 ✍创作者&#xff1a;全栈弄潮儿 &#x1f3e1; 个人主页&#xff1a; 全栈弄潮儿的个人主页 &#x1f3d9;️ 个人社区&#xff0c;欢迎你的加入&#xff1a;全栈弄潮儿的个人社区…

3D动画制作和渲染需要什么样的硬件规格?

动画是艺术与技术的令人兴奋的融合&#xff0c;为无限的创造力提供了广阔的画布。为了将创意愿景变为现实&#xff0c;动画师需要适合其工艺的强大计算资源。每个动画项目都有不同的硬件需求&#xff0c;无论是制作简单的 2D 动画还是构建复杂的 3D 世界。因此&#xff0c;有抱…

企业架构LNMP学习笔记51

企业案例使用&#xff1a; 主从模式&#xff1a; 缓存集群结构示意图&#xff1a; 去实现Redis的业务分离&#xff1a; 读的请求分配到从服务器上&#xff0c;写的请求分配到主服务器上。 Redis是没有中间件来进行分离的。 是通过业务代码直接来进行读写分离。 准备两台虚…

十七、Webpack搭建本地服务器

一、为什么要搭建本地服务器&#xff1f; 目前我们开发的代码&#xff0c;为了运行需要有两个操作&#xff1a; 操作一&#xff1a;npm run build&#xff0c;编译相关的代码&#xff1b;操作二&#xff1a;通过live server或者直接通过浏览器&#xff0c;打开index.html代码…

Datastage部署与使用

Datastage部署与使用 - 码农教程 https://www.cnblogs.com/lanston/category/739553.html Streamsets定时拉取接口数据同步到HBase集群_streamsets api_webmote的博客-CSDN博客 【SDC】StreamSets实战之路-28-实战篇- 使用StreamSets实时采集指定数据目录文件并写入库Kudu_菜…

【C语言】指针的进阶(二)—— 回调函数的讲解以及qsort函数的使用方式

目录 1、函数指针数组 1.1、函数指针数组是什么&#xff1f; 1.2、函数指针数组的用途&#xff1a;转移表 2、扩展&#xff1a;指向函数指针的数组的指针 3、回调函数 3.1、回调函数介绍 3.2、回调函数的案例&#xff1a;qsort函数 3.2.1、回顾冒泡排序 3.2.1、什么是qso…

构建工具Webpack简介

一、构建工具 当我们习惯了Node中使用ES模块化编写代码以后&#xff0c;用原生的HTML、CSS、JS这些东西会感觉到各种不便。比如&#xff1a;不能放心的使用模块化规范&#xff08;浏览器兼容性问题&#xff09;、即使可以使用模块化规范也会面临模块过多时的加载问题。 这时候…

基于uniapp开发 软盒APP系统源码 软件库系统源码 全开源

软盒APP前端-基于uniapp&#xff0c;一个开源的软件库系统 前端开源地址&#xff1a;软盒APP前端-基于uniapp: 软盒APP前端-基于uniapp (gitee.com) 更新说明 更新日期&#xff1a;2023.07.24 v1.0.8.23724 1.修复部分接口 2.删除根据标签获取软件列表接口&#xff0c;整合…

JDBC和DBUtils框架的使用

课程目录 一、JDBC概述 二、JDBC基本操作 三、使用PreparedStatement处理CRUD 四、数据库连接池 五、Apache的DBUtils 六、Dao类 一、JDBC概述 1. 为什么需要JDBC 没有JDBC时&#xff1a; 有了JDBC后&#xff1a; 2. JDBC概述 JDBC&#xff1a;Java Database Conn…

东芝电视Z750的音画效果好吗?调校的够真实吗?

精准匹配声音与画面,呈现“音画合一”的影院级视听盛宴,东芝电视Z750真的很不错,东芝电视拥有70余年的原色调校技术,色彩看起来细腻且舒服,饱和度和景深等都处理的很恰当,而且还有火箭炮音响系统,也是经过日本专业调校的,针对不同家居场景,都有不同的声音处理方案,让我们听到的…