1.linux内核调试工具crash并不能直接显示函数参数,而这个对调试又非常重要
下面是工作中一个实际的问题,我们的进程hang在如下一个内核栈中了,通过栈回溯可知是打开了一个nfs3的网盘文件或者目录,已知客户机器的NAS盘不可访问了,只要访问就会hang住,但我们的进程理论上是不会访问该NAS盘的,那么如何知道open打开的是什么文件呢,这时候就迫切的需要知道do_sys_open的filename参数了(此时多么希望VS, gdb能够出手相救)。
但在x64位linux系统中,前6个参数使用的是rdi, rsi, rdx, rcx, r8, r9寄存器来传递,超出的才会用栈来传递,filename是第2个参数,会用rsi来传递,这下就GG了,函数经过这么多层调用,到当前栈帧的时候rsi早就是n手货了,而且rsi又不是保留寄存器,下层函数不会给他提供VIP待遇做保存,绝望,绝望,就是这么的绝望。

 

 
 
2.希望之光:通过函数参数被局部变量缓存获取

1> 上帝关上了一扇门,必然会为你打开另一扇窗

虽然寄存器不会被缓存,但局部变量会啊,局部变量是用栈保存的,函数调用栈未返回之前,栈都会一直给你当宝一样存着,so换个思路,假设,我们假设这个函数参数filename传递给了某个路人局部变量,那么我们找到这个路人,不就相当于找到了filename么。
 

2> 思路打开,上帝就立马给你送来了这个路人。

我们看do_sys_open,开头就把filename丢给了tmp这个路人,因此我们只要去栈上把tmp逮捕归案就能收工下班。

 

3> 逮捕方案1:"-FF"

crash的bt命令提供了"-FF"参数,宣称可以打印局部变量。但是吗,往往宣称是一回事,实际又是另一回事。"bt -FF"一敲,甭说放大镜,用电子显微镜也找不到tmp在哪。

4> 逮捕方案2:速请汇编大仙

既然tmp是个局部变量,又会作为第二个参数传递给do_filp_open,那么我们找到汇编大仙call do_filp_open的地方,就能找到tmp了。
来吧,dis照妖镜,do_sys_open原形毕露如下,tmp是调用getname返回的,返回值rax立马给了r14(汇编里返回值都是用rax传递),不妙不妙,还是不给留栈上啊,难怪"bt -FF"瞎眼了。虽然但是呢,上帝又给留了一扇窗(PS: 这上帝给的有点多),r14是保留寄存器,享受终生大保健VIP待遇,下层函数调用一定会给留个位的,走,去do_filp_open栈上逛逛。
 
dis给do_filp_open一照,嘿,上帝对咱是true love了,第2个push就把r14留do_filp_open栈上了,下班收工指日可待了这不。
调转枪头再来看一眼前面让我们绝望的"bt -FF"的栈,根据汇编基础知识,linux x64调用函数先将返回地址压栈,调用do_filp_open后再将rbp压栈,最后就是我们朝思暮想的r14了,所以从do_filp_open栈底数第3个就是tmp了,抓!!!
原来是用的第三方库openssl里面会打开一个编译机上的openssl.cnf文件,刚好在编译机的/mnt目录下,而/mnt目录是NAS等网盘默认挂载路径,当NAS出现异常时(如在有文件被占用情况下卸载NAS),此时访问NAS文件目录都会hang住,导致进程hang。

 
3.后记
上面的例子上帝开的窗有点多,通过保存了函数参数的局部变量,咱们很快就真相大白了,但是如果万一万一非常点背,我们要找的函数参数就是没有在局部变量中保存,那怎么办呢。这种情况一般是不会有的,因为重要的参数只要有需要,就会传递到某一层函数局部变量中,耐心点找找就会有的,如果确实没有,可能就需要更耐心的分析整个调用栈,看看哪里会有些勾勾搭搭的局部变量,寄存器没有被破坏,也终究是可以抓出来的。

linux内核调试痛点之函数参数抓捕记的更多相关文章

  1. linux 内核调试之关键函数名记要

    gdbserver + gdb 调试内核 记到函数名,其它就能用gdb看了 start_kernel 内核启动 run_init_process    init进程启动 主要是根据shell脚本初始化 ...

  2. Linux内核调试方法总结【转】

    转自:http://my.oschina.net/fgq611/blog/113249 内核开发比用户空间开发更难的一个因素就是内核调试艰难.内核错误往往会导致系统宕机,很难保留出错时的现场.调试内核 ...

  3. linux内核调试指南

    linux内核调试指南 一些前言 作者前言 知识从哪里来 为什么撰写本文档 为什么需要汇编级调试 ***第一部分:基础知识*** 总纲:内核世界的陷阱 源码阅读的陷阱 代码调试的陷阱 原理理解的陷阱 ...

  4. 【转】Linux内核调试方法总结

    目录[-] 一  调试前的准备 二  内核中的bug 三  内核调试配置选项 1  内核配置 2  调试原子操作 四  引发bug并打印信息 1  BUG()和BUG_ON() 2  dump_sta ...

  5. Linux内核调试方法总结

    Linux内核调试方法总结 一  调试前的准备 二  内核中的bug 三  内核调试配置选项 1  内核配置 2  调试原子操作 四  引发bug并打印信息 1  BUG()和BUG_ON() 2   ...

  6. Linux内核调试方法【转】

    转自:http://www.cnblogs.com/shineshqw/articles/2359114.html kdb:只能在汇编代码级进行调试: 优点是不需要两台机器进行调试. gdb:在调试模 ...

  7. Linux Kernel - Debug Guide (Linux内核调试指南 )

    http://blog.csdn.net/blizmax6/article/details/6747601 linux内核调试指南 一些前言 作者前言 知识从哪里来 为什么撰写本文档 为什么需要汇编级 ...

  8. Linux内核调试的方式以及工具集锦【转】

    转自:https://blog.csdn.net/gatieme/article/details/68948080 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原 ...

  9. Linux内核调试的方式以及工具集锦

    原文:https://blog.csdn.net/gatieme/article/details/68948080 CSDN GitHubLinux内核调试的方式以及工具集锦 LDD-LinuxDev ...

  10. Linux内核调试方法总结之栈帧

    栈帧 栈帧和指针可以说是C语言的精髓.栈帧是一种特殊的数据结构,在C语言函数调用时,栈帧用来保存当前函数的父一级函数的栈底指针,当前函数的局部变量以及被调用函数返回后下一条汇编指令的地址.如下图所示: ...

随机推荐

  1. PHP 高性能框架 Workerman 凭什么能硬刚 Swoole ?

    大家好,我是码农先森. 一次偶然看到了国外某机构针对 PHP 周边生态框架及扩展的性能测试排行榜,看到 Workerman 竟遥遥领先 Swoole.在我们 PHP 程序员现有的认知里,Swoole ...

  2. python统计班级学生

    python统计班级学生 如下场景: 假设我有一个学生类和一个班级类,想要实现的功能为:    执行班级人数增加的操作.获得班级的总人数:    学生类继承自班级类,每实例化一个学生,班级人数都能增加 ...

  3. 【Vue】可编辑表格与三级联动下拉

    需求是给员工分配岗位,设计上是一人多岗的存在... 单位 -- 部门 -- 岗位 这样的层级 功能效果: 因为员工可以在不同的单位下任职岗位,所以这个每一个岗位都是一个独立 查询单位列表是固定的,但是 ...

  4. 【Java】Collection 集合框架概述

    Collection 集合框架概述 1.集合.数组都是为了存储数据而产生的 2.为什么需要集合?为了更灵活方便的存储数据,且集合能存储的容量比数组更大 3.存储的概念还停留在内存活动范围内,也只是短暂 ...

  5. 【DataBase】MySQL 08 SQL函数 单行函数其二 数值函数

    数值函数 # 数值函数 -- ROUND() 四舍五入 SELECT ROUND(3.14),ROUND(-3.14); -- 重载,保留指定参数的小数位数 SELECT ROUND(-3.14,3) ...

  6. 【ECharts】01 快速上手

    简单介绍: ECharts 是一个使用 JavaScript 实现的开源可视化库,涵盖各行业图表,满足各种需求. ECharts 遵循 Apache-2.0 开源协议,免费商用. ECharts 兼容 ...

  7. 近似最优的分层路径搜索(Near Optimal Hierarchical Path-Finding)—— A*算法的变种 —— 分层A*算法(HPA*)

    论文地址: https://webdocs.cs.ualberta.ca/~mmueller/ps/hpastar.pdf Near Optimal Hierarchical Path-Finding

  8. Google的TPU的向量化内存的读取规格——单次读取/写入的数据量

    异构加速设备: GPU.TPU.NPU 这几种设备,除了GPU公开了部分硬件设计原理和软件编程范式以外,所有的TPU和NPU的资料都是不公开的,都是被其所属公司保留的,然后这些公司会自己在这些硬件之上 ...

  9. 9组-Alpha冲刺-6/4

    一.基本情况 队名:不行就摆了吧 组长博客:https://www.cnblogs.com/Microsoft-hc/p/15546712.html 小组人数: 8 二.冲刺概况汇报 卢浩玮 过去两天 ...

  10. SMU 2024 spring 天梯赛自主训练2

    SMU 2024 spring 天梯赛自主训练2 7-1 I Love GPLT - SMU 2024 spring 天梯赛自主训练2 (pintia.cn) PHP 点击查看代码 I L o v e ...