watchpoint

前言

内存被踩,通过 watchpoint 找到真凶

实例

以 smsc911x 网卡驱动为基体,进行实验,和网卡本身功能无关,

在这里插入图片描述
每执行一次 ifconfig eth0 up,就会调用一次 smsc911x_open(),我在这里设计了一段代码,当第 3 次执行 ifconfig eth0 up 时,bbb() 函数就会将指针变量 a 赋值为 NULL,这样在 aaa() 函数中访问 a 指向的内存时就会发生 crash。

# ifconfig eth0 up
change the value of a to NULL !!!
a = 0x00000000
&a = 0xd78476c7
8<--- cut here ---
Unable to handle kernel NULL pointer dereference at virtual address 00000000
[00000000] *pgd=00000000
Internal error: Oops: 5 [#1] SMP ARM
Modules linked in:
CPU: 0 PID: 123 Comm: ifconfig Not tainted 6.1.44 #14
Hardware name: ARM-Versatile Express
PC is at aaa+0x34/0x48
LR is at aaa+0x30/0x48
pc : [<80655788>]    lr : [<80655784>]    psr: 600a0013
sp : 9b411d20  ip : 0e152000  fp : 00000000
r10: 81834800  r9 : 81015800  r8 : 00001002
r7 : 81015800  r6 : 80d73a10  r5 : 80a83234  r4 : 80d739a0
r3 : 00000000  r2 : 00000000  r1 : 00000000  r0 : 0000000e
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
Control: 10c5387d  Table: 61b84059  DAC: 00000051
Register r0 information: non-paged memory
Register r1 information: NULL pointer
Register r2 information: NULL pointer
Register r3 information: NULL pointer
Register r4 information: non-slab/vmalloc memory
Register r5 information: non-slab/vmalloc memory
Register r6 information: non-slab/vmalloc memory
Register r7 information: slab kmalloc-2k start 81015800 pointer offset 0 size 2048
Register r8 information: non-paged memory
Register r9 information: slab kmalloc-2k start 81015800 pointer offset 0 size 2048
Register r10 information: slab kmalloc-512 start 81834800 pointer offset 0 size 512
Register r11 information: NULL pointer
Register r12 information: non-paged memory
Process ifconfig (pid: 123, stack limit = 0x221691ba)
Stack: (0x9b411d20 to 0x9b412000)
1d20: 81015d80 00000000 81015824 80655808 00000000 9b411d94 0000000e 81015800
1d40: 81834800 80144640 0000000e 9b411d94 81015824 80952860 00001002 8014476c
1d60: 00000000 81015800 00000000 81015824 80952860 00001002 81015800 81834800
1d80: 00000000 8074e6f4 00000000 00000000 81015800 81015800 00000000 45d1466b
1da0: 81015800 81015800 00001043 00000000 00000041 8074eb14 80db44a4 9b411e44
1dc0: 9b411ed4 9b411e24 00000014 45d1466b 81015800 9b411e48 00000000 00001002
1de0: 8183480c 8074eb40 81a59c80 9b411e48 00000000 00000000 8183480c 807f5f34
1e00: ca6f898f 539cfbfe e473426f 00001043 00000000 00000000 00000000 45d1466b
1e20: 9b411e48 00008914 7ee27c84 81bc0000 7ee27c84 00000003 81b98300 81426900
1e40: 76f76000 807f7b14 30687465 00000000 00000000 00000000 00001043 00000000
1e60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
1e80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
1ea0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 45d1466b
1ec0: 00008914 81426880 7ee27c84 80726534 9b411edf 818308f8 818308c0 00000007
1ee0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
1f00: 00000000 45d1466b 81b84010 00008914 81b98300 7ee27f64 7ee27c84 8029fde4
1f20: 00008914 802a12c8 00555000 9b411fb0 00553000 00553441 00000017 00000254
1f40: 818308c0 00000007 81af1080 80113a34 00000000 45d1466b 00000000 00000000
1f60: 81426880 00000017 00553441 9b411fb0 80d09f3c 80c58044 7ee27e6c 45d1466b
1f80: 76f76000 00546138 7ee27c84 7ee27f64 00000036 801002c4 81af1080 00000036
1fa0: 76f76000 80100060 00546138 7ee27c84 00000003 00008914 7ee27c84 7ee27c18
1fc0: 00546138 7ee27c84 7ee27f64 00000036 7ee27e68 7ee27e6c 76f75ce0 76f76000
1fe0: 00556bdc 7ee27c00 0048ed74 76ed246c 200a0010 00000003 00000000 00000000aaa from smsc911x_open+0x18/0x9c8smsc911x_open from __dev_open+0xc8/0x188__dev_open from __dev_change_flags+0x1b0/0x1c8__dev_change_flags from dev_change_flags+0x14/0x44dev_change_flags from devinet_ioctl+0x264/0x6d0devinet_ioctl from inet_ioctl+0x21c/0x248inet_ioctl from sock_ioctl+0x478/0x588sock_ioctl from vfs_ioctl+0x18/0x34vfs_ioctl from sys_ioctl+0xc10/0xcd4sys_ioctl from ret_fast_syscall+0x0/0x54
Exception stack(0x9b411fa8 to 0x9b411ff0)
1fa0:                   00546138 7ee27c84 00000003 00008914 7ee27c84 7ee27c18
1fc0: 00546138 7ee27c84 7ee27f64 00000036 7ee27e68 7ee27e6c 76f75ce0 76f76000
1fe0: 00556bdc 7ee27c00 0048ed74 76ed246c
Code: e1a01006 e1a00005 ebec5b1a e5943070 (e5931000) 
---[ end trace 0000000000000000 ]---
Segmentation fault

内核的 crash 信息帮我们定位到了问题原因是访问的指针变量 a 是一个空指针。
那接着如何追踪是谁将 a 赋值为空了呢?

请忽略 change the value of a to NULL !!! 这句 log,实际项目中没有神仙会帮你加上这句。

在 aaa 函数处打上断点

(gdb) b aaa
Breakpoint 1 at 0x80655754: file drivers/net/ethernet/smsc/smsc911x.c, line 1596.

断点命中后,使用 watch 命令监控指针变量 a,当读或写 a 变量时,就会触发该断点

Breakpoint 1, aaa () at drivers/net/ethernet/smsc/smsc911x.c:1596
1596	{
(gdb) p a
$1 = (int *) 0x80d73a14 <b>
(gdb) p *a
$2 = 10
(gdb) watch a
Hardware watchpoint 2: a

继续运行代码,watchpoint 断点触发,提示 a 的值从 0x80d73a14 变为了 0x0。
代码停留在 smsc911x.c 第 1613 行。

Hardware watchpoint 2: aOld value = (int *) 0x80d73a14 <b>
New value = (int *) 0x0
bbb () at drivers/net/ethernet/smsc/smsc911x.c:1613
1613			printk("change the value of a to NULL !!!\n");

代码停留位置是即将要执行的行,结合代码,上一行,第 1612 行 a = NULL; 是刚执行过的代码,也就是该行代码将指针变量 a 的值由 0x80d73a14 改为了 0x0,这样就找到了真凶。

总结

有人可能会有疑问,这有什么啊,也没看出来 watchpoint 有多强大。
别着急,请大家换一种情景,假如 bbb() 函数在别的文件呢?查找问题难度是不是就升级了。
有小伙伴说,我有搜索啊,全局搜索 a =,不也能找到赋值的地方。是的,不过,如果赋值的地方很多,且右值也是个变量,定位起来是不是难度比较大。
还有,修改变量 a 的代码有可能不在 kernel 源码中,可能在某个内核模块中,这样定位起来也比较费功夫。
最后,有一种情况是非用 watchpoint 不可的,那就是,代码并不是显式修改 a 的值,而是由于某处代码访问越界了,误修改到了 a 的值,这种情况看代码是看不出来的。比如,代码 int c[4]; 定义了一个数组,i = 100,使用 c[i] 访问时就出现了数组越界,c[100],是一个未知地址,说不准就是上面变量 a 所在的内存地址。

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

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

相关文章

数学知识(四)(容斥原理、博弈论)

一、容斥原理 容斥原理公式 一共加或者减的式子个数 &#xff08;一&#xff09;利用容斥原理解决求能被质数整除的数的个数 890计算能被整除的数的个数 因为一共有2^n-1种选法&#xff0c;可以用位运算的方式枚举&#xff0c;对于得到的每一种选法&#xff0c;根据存在的数…

六、回归与聚类算法 - 逻辑回归与二分类

线性回归欠拟合与过拟合线性回归的改进 - 岭回归分类算法&#xff1a;逻辑回归模型保存与加载无监督学习&#xff1a;K-means算法 1、应用场景 2、原理 2.1 输入 2.2 激活函数 3、损失以及优化 3.1 损失 3.2 优化 4、逻辑回归API 5、分类的评估方法 5.1 精确率和召回率 5.2…

【Spring】IoC容器 控制反转 与 DI依赖注入 配置类实现版本 第四期

文章目录 基于 配置类 方式管理 Bean一、 配置类和扫描注解二、Bean定义组件三、高级特性&#xff1a;Bean注解细节四、高级特性&#xff1a;Import扩展五、基于注解配置类方式整合三层架构组件总结 基于 配置类 方式管理 Bean Spring 完全注解配置&#xff08;Fully Annotatio…

Kotlin学习 6

1.接口 interface Movable {var maxSpeed: Intvar wheels: Intfun move(movable: Movable): String}class Car(var name: String, override var wheels: Int 4, _maxSpeed: Int) : Movable {override var maxSpeed: Int _maxSpeedget() fieldset(value) {field value}overr…

C语言读取 ini 配置文件,修改/添加键值对

C语言读取 ini 配置文件&#xff0c;修改/添加键值对 C语言读取 ini 配置文件&#xff0c;对section中的键值对进行修改/添加&#xff0c;如果section不存在&#xff0c;则在末尾将新的section/key/value 添加进去。 一、了解什么是INI文件&#xff1f; ini 文件是Initializ…

【大数据】Flink 之部署篇

Flink 之部署篇 1.概述和参考架构2.可重复的资源清理3.部署模式3.1 Application 模式3.2 Per-Job 模式&#xff08;已废弃&#xff09;3.3 Session 模式 Flink 是一个多用途框架&#xff0c;支持多种不同的混合部署方案。下面&#xff0c;我们将简要介绍 Flink 集群的构建模块、…

【html学习笔记】3.表单元素

1.文本框 1.1 语法 <input type "text">表示文本框。且只能写一行 1.2 属性 使用属性size 设置文本框大小 <input type"text" size"10">2. 使用属性value 来设置文本框的默认文字 <input type"text" size"…

Vue状态管理库-Pinia

一、Pinia是什么&#xff1f; Pinia 是 Vue 的专属状态管理库&#xff0c;它允许支持跨组件或页面共享状态&#xff0c;即共享数据&#xff0c;他的初始设计目的是设计一个支持组合式API的 Vue 状态管理库&#xff08;因为vue3一个很大的改变就是组合式API&#xff09;,当然这…

PFA三角烧瓶实验室PFA锥形瓶本底纯净耐腐蚀性强

PFA三角烧瓶外观呈平底圆锥状&#xff0c;下阔上狭&#xff0c;有一圆柱形颈部&#xff0c;上方有一较颈部阔的开口&#xff0c;可用塞子封闭。PFA三角烧瓶也称PFA锥形瓶&#xff0c;PFA反应瓶&#xff0c;PFA三角烧瓶、PFA依氏烧瓶、PFA锥形烧瓶&#xff0c;PFA鄂伦麦尔瓶等。…

普中51单片机学习(串口通信)

串口通信 原理 计算机通信是将计算机技术和通信技术的相结合&#xff0c;完成计算机与外部设备或计算机与计算机之间的信息交换 。可以分为两大类&#xff1a;并行通信与串行通信。并行通信通常是将数据字节的各位用多条数据线同时进行传送 。控制简单、传输速度快&#xff1…

【Python】Python实现串口通信(Python+Stm32)

&#x1f389;欢迎来到Python专栏~Python实现串口通信 ☆* o(≧▽≦)o *☆嗨~我是小夏与酒&#x1f379; ✨博客主页&#xff1a;小夏与酒的博客 &#x1f388;该系列文章专栏&#xff1a;Python学习专栏 文章作者技术和水平有限&#xff0c;如果文中出现错误&#xff0c;希望…

springboot208基于springboot物流管理系统

基于spring boot物流管理系统设计与实现 摘 要 社会发展日新月异&#xff0c;用计算机应用实现数据管理功能已经算是很完善的了&#xff0c;但是随着移动互联网的到来&#xff0c;处理信息不再受制于地理位置的限制&#xff0c;处理信息及时高效&#xff0c;备受人们的喜爱。…

maven工程打包引入本地jar包

1、通过maven生成本地区仓库包 mvn install:install-file --settings D:\lkx\download\apache-maven-3.6.3\conf\settings.xml -Dfileaspose-cad-21.8.jar -DartifactIdaspose-cad -DgroupIdsystem.core -Dversion21.8 -Dpackagingjar -DgeneratePomtrue # --settings&#xf…

进程线程间的通信:2024/2/22

作业1&#xff1a;代码实现线程互斥机制 代码&#xff1a; #include <myhead.h>//临界资源 int num10;//创建一个互斥锁 pthread_mutex_t mutex;//任务一 void *task1(void *arg) {//获取锁资源pthread_mutex_lock(&mutex);num123;sleep(3);printf("task1:num…

PacketSender-用于发送/接收 TCP、UDP、SSL、HTTP 的网络实用程序

PacketSender-用于发送/接收 TCP、UDP、SSL、HTTP 的网络实用程序 PacketSender是一款开源的用于发送/接收 TCP、UDP、SSL、HTTP 的网络实用程序&#xff0c;作者为dannagle。 其官网地址为&#xff1a;https://packetsender.com/&#xff0c;Github源代码地址&#xff1a;htt…

SQL Server —— While语句循环

一&#xff1a;简介 while 循环是有条件的循环控制语句。满足条件后&#xff0c;再执行循环体中的SQL语句。 while: break, 如果有多条语句可以在while后面添加begin-end。关于while的语法 while(条件) -- begin -- 语句1 -- 语句2 -- break 根据情况是否添加break -- end 二…

leetcode日记(32)字符串相乘

做了很久很久……真的太繁琐了&#xff01;&#xff01; class Solution { public:string multiply(string num1, string num2) {string s;string str;if (num1 "0" || num2 "0") return "0";for(int inum2.size()-1;i>0;i--){int c2num2[…

Qt:tabWidget控件

一、tabWidget用来做什么 tabWidget控件用来进行不同控件页面的跳转&#xff0c; 二、控件的一些函数功能 添加一个页面&#xff0c;返回index int addTab(QWidget *widget, const QString &); int addTab(QWidget *widget, const QIcon& icon, const QString &…

pytest教程-11-初识fixture

领取资料&#xff0c;咨询答疑&#xff0c;请➕wei: June__Go 上一小节我们学习了使用allure生成html测试报告的方法&#xff0c;本小节我们讲解一下pytest fixture测试夹具的使用方法。 前言 在做自动化的过程中&#xff0c;编写用例时候需要用到用例的前置和用例的后置&a…

2024年了,抖店还能做吗?适合新手吗?

我是电商珠珠 现在已经24年了&#xff0c;抖店也已经发展了四年了。其中有很多在门外观望的人&#xff0c;还在犹豫不决。认为抖店发展到今天&#xff0c;所有的红利早已在20年的时候就消失殆尽了&#xff0c;特别是没有经验的如果入驻了&#xff0c;既不能享受平台红利&#…