内核模块踩内存问题定位利器- hardware breakpoint
内核由于共享内存地址空间,如果没有合适的工具,很多踩内存的问题即使复现,也无法快速定位;
在新的内核版本中引入了一个新工具hardware breakpoint,其能够监视对指定的地址的特定类型(读/写)的数据访问,有利于该类问题的定位;
以下是一个使用该工具的例子(来自内核代码linux-3.10/samples/hw_breakpoint/data_breakpoint.c)
struct perf_event * __percpu *sample_hbp;
static char ksym_name[KSYM_NAME_LEN] = "pid_max";
module_param_string(ksym, ksym_name, KSYM_NAME_LEN, S_IRUGO);
MODULE_PARM_DESC(ksym, "Kernel symbol to monitor; this module will report any"
" write operations on the kernel symbol");
static void sample_hbp_handler(struct perf_event *bp,
struct perf_sample_data *data,
struct pt_regs *regs)
{
printk(KERN_INFO "%s value is changed\n", ksym_name);
dump_stack();
printk(KERN_INFO "Dump stack from sample_hbp_handler\n");
}
static int __init hw_break_module_init(void)
{
int ret;
struct perf_event_attr attr;
hw_breakpoint_init(&attr);
attr.bp_addr = kallsyms_lookup_name(ksym_name);
attr.bp_len = HW_BREAKPOINT_LEN_4;
attr.bp_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R;
sample_hbp = register_wide_hw_breakpoint(&attr, sample_hbp_handler, NULL);
if (IS_ERR((void __force *)sample_hbp)) {
ret = PTR_ERR((void __force *)sample_hbp);
goto fail;
}
printk(KERN_INFO "HW Breakpoint for %s write installed\n", ksym_name);
return 0;
fail:
printk(KERN_INFO "Breakpoint registration failed\n");
return ret;
}
static void __exit hw_break_module_exit(void)
{
unregister_wide_hw_breakpoint(sample_hbp);
printk(KERN_INFO "HW Breakpoint for %s write uninstalled\n", ksym_name);
}
module_init(hw_break_module_init);
module_exit(hw_break_module_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("K.Prasad");
MODULE_DESCRIPTION("ksym breakpoint");
注意:
1、各个不同的CPU有同时支持的hardwarebreakpoint数量限制,对X86,为4个.
所以对于随机的内存踩踏(频繁的申请、使用、释放)是很难处理的,比较适合固定的地址踩踏2、指定的回调函数的调用时机:对X86,如果监视的是数据地址,则是在访问该数据的指令执行完成后,通过exception触发回调,如果监视的是指令地址,则是在该指令被执行前通过exception触发回调
- 该方式只能监视通过CPU访问地址的情况,对DMA就无能为力了
补充:
如何跟踪指令地址
- 1、该工具用于跟踪指令地址(函数等)的访问,这个时候attr.bp_type需要设置为HW_BREAKPOINT_X
关于PER_CPU变量的跟踪
1、获取per_cpu变量的地址
如果跟踪的是内核的per_cpu变量,那么用kallsyms_lookup_name获取到的地址不是per_cpu变量的实际地址,仅仅是该per_cpu变量相对于各个cpu自己的per_cpu数据存放区起始地址的偏移,需要通过per_cpu_ptr获取到真实的地址,比如:
addr = kallsyms_lookup_name("gcwq_nr_running");
addr = (unsigned long)per_cpu_ptr((atomic_t *)addr,cpu);
attr.bp_addr = addr
2、关于可用的hw breakpoint数量
由于CPU硬件支持的hw breakpoint数量非常有限,当前CPU和核心数量较多,很多时候不可能为每个CPU核心对于的per cpu变量都注册hw breakpoint,但是很多per_cpu变量的改写,甚至是读取,都限定在本CPU,而不是所有的CPU,如果是出于内核执行跟踪的目的,就没有必要把要在其它CPU上访问的per_cpu变量地址都注册在当前CPU的hw breakpoint了,这时就可以修改hw breakpoint接口register_wide_hw_breakpoint,把其中的for_each_online_cpu循环修改为仅仅处理当前CPU即可
内核模块踩内存问题定位利器- hardware breakpoint的更多相关文章
- 记一次《C语言踩内存》问题定位有感
踩内存问题,个人认为算是比较容易出现但是有很难定位的问题,被踩者轻者功能瘫痪,重者一命呜呼,直接诱发死机.产生踩内存的的原因也比较多样,比较典型的有如下几种: 数组越界访问 字符串越界操作 直接操作野 ...
- Android内存泄漏检测利器:LeakCanary
Android内存泄漏检测利器:LeakCanary MAR 28TH, 2016 是什么? 一言以蔽之:LeakCanary是一个傻瓜化并且可视化的内存泄露分析工具 为什么需要LeakCanary? ...
- 根据内存布局定位的一个fastdfs坑
在使用fastdfs时,编写数据上传代码时,遇到一个坑.最终根据指针对应的内存布局定位到一个其client API的一个坑,值得记录一下.具体是在 tracker_connect_server() 这 ...
- 一个未完成的2.6.32-220内核踩内存crash分析记录
遇到一个crash,log如下: BUG: unable to handle kernel NULL pointer dereference at (null) IP: [<ffffffff81 ...
- 构造函数,C++内存管理,内存泄漏定位
构造函数 1.构造顺序 虚基类构造函数,基类构造函数,类对象构造函数,自己的构造函数 2.必须使用初始化列表 (1) 引用成员,常量成员: (2) 基类没默认构造函数(自己重载覆盖了), (3)类对象 ...
- C++ 踩内存
1.从上往下,栈在堆上面(记忆方法:站在堆上面),二者向里压缩,也就是说,栈地址减少,堆地址增加.栈顶是小地址. 2.模拟踩内存,让程序崩溃.代码如下: int main(int argc, char ...
- 内存问题检查利器——Purify
内存问题检查利器——Purify 一. 引言 我们都知道软件的测试(在以产品为主的软件公司中叫做QA—Quality Assessment)占了整个软件工程的30% -50%,但有 ...
- Java内存泄漏定位
Java虚拟机内存分为五个区域:方法区,堆,虚拟机栈,本地方法栈,程序计数器.其中方法区和堆是java虚拟机共享的内存区域,虚拟机栈,本地方法栈,程序计数器是线程私有的. 程序计数器(Program ...
- Linux进程内存分析和内存泄漏定位
在Linux产品开发过程中,通常需要注意系统内存使用量,和评估单一进程的内存使用情况,便于我们选取合适的机器配置,来部署我们的产品. Linux本身提供了一些工具方便我们达成这些需求,查看进程实时资源 ...
- Android 内存泄漏分析利器——leakcanary
LeakCanary Android 和 Java 内存泄露检测. “A small leak will sink a great ship.” - Benjamin Franklin 千里之堤, 毁 ...
随机推荐
- TCP协议测试
TCP协议测试 首先需要测试TCP协议的连接 tcping命令是针对tcp监控的,也可以看到ping值,即使源地址禁ping也可以通过tcping来监控服务器网络状态,除了简单的ping之外,tcpi ...
- 【Redis】02 Redis 搭建与操作
Redis的安装及启动停止 官网地址: https://redis.io/download 使用wget命令下载redis wget 下载地址 下载: [root@VM-0-7-centos ~]# ...
- 树莓派 3b+型号 pip3方式 安装 TensorFlow
树莓派系统为: 首先选择 pip3 方式进行安装: 树莓派上执行: 发现速度过慢,于是选择先在Windows主机上下载,然后再把文件传到树莓派上进行安装. 不过后来发现即使使用迅雷这样强大的下载工具 ...
- 报错 qt.qpa.plugin: Could not load the Qt platform plugin “xcb“ in ““ even though it was found
参考: https://blog.csdn.net/qq_39938666/article/details/120452028 ==================================== ...
- 【转载】 机器人真·涨姿势了:比肩人类抓取能力,上海交大、非夕科技联合提出全新方法AnyGrasp
原文地址: https://developer.aliyun.com/article/822654 ================================================= ...
- 结合实例看 maven 传递依赖与优先级,难顶也得上丫
开心一刻 想买摩托车了,但是钱不够,想找老爸借点 我:老爸,我想买一辆摩托车,上下班也方便 老爸:你表哥上个月骑摩托车摔走了,你不知道?还要买摩托车? 我:对不起,我不买了 老板:就是啊,骑你表哥那辆 ...
- 运维 + AI,你得先搞懂这些
很感谢夜莺提供如此优质的平台能和行业内顶尖技术大佬做面对面的交流,在这个会议中又学习到了很多有趣有深度的内容,给我在未来探索的道路上提供了一些新的指引方向.同时感谢夜莺社区的邀请,在此再做一次关于AI ...
- VisionOn:新一代在线制图工具,简单易用又高颜值
Vision On 一款集流程图.思维导图.白板于一体的轻量级在线图形工具 在工作和学习过程中,通过可视化的图形,有助于清晰高效地表达我们的灵感.想法.思想. 工欲善其事,必先利其器. 目前,思维导图 ...
- [NOIP2010 提高组] 关押罪犯 - 洛谷
P1525 [NOIP2010 提高组] 关押罪犯 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 种类并查集 #include <bits/stdc++.h> #def ...
- Java抽象类 小白版
什么是抽象 抽象就是从多个事物中将共性的,本质的内容抽象出来. 什么是抽象类 Java语言中,用abstract关键字修饰的类叫作抽象类.类本身是不存在的,所以抽象类无法创建对象无法实例化. 在面向对 ...