linux系统挂掉问题的分析
玩linux系统,经常遇到的一件事就是做了某个操作之后系统会突然挂掉,这要怎么办?
1. 首先我们要看log,看看是否会留下一些蛛丝马迹,比如PC/LR是否有留下来。
PC是ARM的一个寄存器,即程序计数器,他记下的是当前程序执行的位置;
LR是link register,它保存的是当前函数的返回地址,
所以我们可以善用PC/LR来帮助我们查找问题的根源。
2. 假设我们知道系统挂掉时的PC值,同时我们要知道你的系统中挂掉的process是哪一个,
这样再使用ps aux | grep my_process获取这个process的pid。
获得了process的pid,我们可以使用cat /proc/pid/maps > ./pid_maps获取该procss的虚拟地址空间。
注意每一个用户process的虚拟地址空间都可能不一样,因为虚拟地址空间的关系,
在系统中每一个用户process都认为自己是系统中唯一的一个process。
3. 因为我们有了PC值,所以接下来在pid_maps中找到PC值位于哪一个shared library中,
也就是说系统挂掉的点是在哪个.so中挂掉。此时我们根据PC值结合这只挂掉的libtest.so
计算出在libtest.so中的偏移量。
4. readelf -a ./libtest.so | grep offset
或者nm ./libtest.so | grep offset
或者objdump -d libtest.so > libtest_disassemble.txt(建议使用objdump反汇编)
来查看offset对应的代码中的位置。
5. 结合源代码进行分析,找到系统挂掉的具体位置。
使用这种方法的缺点是:
1. 如果系统挂掉时已经破坏了线程栈,那利用PC值分析的意义不大;
2. 如果系统是挂在内核空间,那也无法确认问题点,除非能够恢复出用户空间的线程栈。
nm命令会列出symbol value(symbol offset)、symbol type以及symbol name。
我们常见的symbol type有"T"和"t",这两种类型的symbol都位于text section(即代码段),
其中symbol type为"T"的symbol对应的是extern类型的函数,为"t"的则对应的是static类型的函数。
因为symbol value和symbol name是对应的,所以我们可以根据PC确定offset后找到
相应的symbol name从而确定问题点。
nm libtest.so > nm_libtest.txt
readelf命令用来显示elf格式文件的信息,以本文讨论的问题范畴来讲,感兴趣的是symbols。
所以我们可以使用readelf -s libtest.so > readelf_libtest.txt将libtest.so中的symbol
dump出来,以便于我们排查问题。
objdump用来dump obj类型文件的信息,有了这条命令我们可以对编译好的obj文件进行反汇编,
这样可以去查看代码执行的流程。很多时候,对我们解决问题会非常有帮助。
objdump -d libtest.so > objdump_libtest.txt
为什么要计算PC对应在.so(shared library)中的偏移量?
shared library不同于静态库:静态库是在编译时即被集成到可执行文件中;
而动态库是在你的程序运行时才被加载到RAM中。
在被映射到虚拟地址空间之前,动态连接库中的各个符号之间的相对地址是确定的;
但是程序运行之前,无法确定其在虚拟地址空间中的位置,所以才需要计算偏移量。
在可执行程序中,仅仅有一个指向动态连接库的指针。/etc/ld.so.conf是动态连接库的配置文件,
在运行程序时当需要某个动态库时,ldconfig根据/etc/ld.so.conf中的配置选择加载特定的动态库到RAM中。
从以上描述,我们知道使用动态库的优点是:(1)可执行程序的代码量会变小;(2)动态库
独立于可执行程序,所以当我们要修改动态库时我们仅仅需要重新编译这个动态库而不需要
将整个可执行程序都重新编译一次;(3)另外可以在程序运行时去替换新的动态库,给调试
程序带来了方便。
正因为动态库的独立性,所以也决定了其一些缺点的存在:
(1)如果你的系统中缺少某个你需要的动态库,那只能在你运行时才会发现问题;
(2)如果你调用的动态库中缺少你需要的API,那也只能在运行程序时才能发现问题。
在之前写过的文章里面,有做过类似的试验,这里我们仍然可以做几个试验:
(1)将libtest.so所在的path从LD_LIBRARY_PATH中移除,再执行你的程序看一下:
sh#error while loading shared libraries:
(2)在系统总暂时性的将你的libtest.so删除,再执行你的程序看一下:
sh#error while loading shared libraries:
(3)将某个API从libtest.so中拿掉,再执行你的程序看一下:
sh#./test_main: symbol lookup error: ./libtest.so: undefined symbol:
如果是加载某个动态库出错,那么先用ldd命令(ldd实际上只是一个script)来查看
可执行文件需要用到哪些共享库,然后依次检查这些共享库是否都存在;
接下来检查共享库所在的path是否都有添加在LD_LIBRARY_PATH中。
如果是动态库中缺少某个API从而导致执行程序时失败,那首先要确认缺少的API是哪一个(如何确认?),
接下来使用nm/readelf或者是objdump来获取libtest.so中的symbol了,然后再确认需要的symbol是否
包含在libtest.so了。
nm libtest.so | grep your_api
readelf -s libtest.so | grep your_api
objdump -d libtest.so | grep your api
因为我们故意移除了your_api,所以在结果中应该搜索不到;
另外我们可以搜索其它的symbol看一下,应该会搜索到的,这样可以确认我们用的工具命令没有问题。
待解决问题:
可执行程序是如何调用动态库中提供的API?
为什么有时候找不到符号,是因为在编译代码时被stripped掉了吗?
linux系统挂掉问题的分析的更多相关文章
- Linux 系统负载查询及分析说明
Linux 系统出现死机或卡顿时,可以参阅如下步骤进行整体排查: 检查服务器进程与服务否占用了过多内存,或者内存没有正常释放,导致出现内存溢出,系统宕机. 检查 /var/spool/cron 等系统 ...
- LInux系统木马植入排查分析 及 应用漏洞修复配置(隐藏bannner版本等)
在日常繁琐的运维工作中,对linux服务器进行安全检查是一个非常重要的环节.今天,分享一下如何检查linux系统是否遭受了入侵? 一.是否入侵检查 1)检查系统日志 检查系统错误登陆日志,统计IP重试 ...
- Linux系统及应用问题分析排查工具
linux 阿里技术协会 摘要: Linux服务器上经常遇到一些系统和应用上的问题,如何分析排查,需要利器,下面总结列表了一些常用工具.trace tool:最后也列举了最近hadoop社区在开发发展 ...
- Linux系统网络性能实例分析
由于TCP/IP是使用最普遍的Internet协议,下面只集中讨论TCP/IP 栈和以太网(Ethernet).术语 LinuxTCP/IP栈和 Linux网络栈可互换使用,因为 TCP/IP栈是 L ...
- linux系统卡顿 性能分析
systemtrap 是一个内核开发者要掌握的工具. linux performance analysis 系统瓶颈性能分析软件
- linux系统 web在线日志分析
线上环境出现问题时,不能像本地环境一样,断点查找问题,只有根据日志分析来定位问题,当然有资深的经验也是可以的,哈哈. 最基本的就是cat命令,可以通过cat filename,来查看文件全部内容, & ...
- 《Linux内核分析》第三周 构建一个简单的Linux系统MenuOS
[刘蔚然 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] WEEK THREE ...
- Linux内核分析第三周学习总结:构造一个简单的Linux系统MenuOS
韩玉琪 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.Linux内 ...
- 一次Linux系统被攻击的分析过程
IT行业发展到现在,安全问题已经变得至关重要,从最近的“棱镜门”事件中,折射出了很多安全问题,信息安全问题已变得刻不容缓,而做为运维人员,就必须了解一些安全运维准则,同时,要保护自己所负责的业务,首先 ...
随机推荐
- Datamatrix码
DataMatrix二维条码原名Datacode,由美国国际资料公司(International Data Matrix, 简称ID Matrix)於1989年发明.DataMatrix二维条码是一种 ...
- Qt见解:Post 与 Get 的区别(Get将参数直接与网址整合为一个整体,而Post则将其拆为两个部分)
第一次接触Qt的Http项目,今天看了一下Post和Get的基本使用方法,就开始尝试了.原先以为Post专门用于向服务器发送请求,然后接收服务器应答的: 而Get只是单纯从服务器获取资源,比如下载这个 ...
- Qt探秘——谈ui文件的用法
转载自:点击打开链接http://blog.csdn.net/luo_isaiah/article/details/5794973 相信用过Qt Designer的朋友,对Qt Project中的.u ...
- mysql记录慢查询
1,配置开启 Linux: 在mysql配置文件my.cnf中增加 log-slow-queries=/var/lib/mysql/slowquery.log (指定日志文件存放位置,可以为空,系统会 ...
- web.xml 中<taglib>报错(转载)
在web.xml加入taglib <taglib> <taglib-uri>/WEB-INF/tiles.tld</taglib- uri> <taglib- ...
- BZOJ 2718: [Violet 4]毕业旅行( 最长反链 )
一不小心速度就成了#1.... 这道题显然是求最长反链, 最长反链=最小链覆盖.最小链覆盖就是先做一次floyd传递闭包, 再求最小路径覆盖. 最小路径覆盖=N - 二分图最大匹配. 所以把所有点拆成 ...
- Get与POST的理解
针对GET& POST的掌握可以说是迷迷糊糊的,今天特意拿出来好好整理一下,便于掌握理解. 在服务器端都有一个用来标识资源位置的符号,被称为统一资源标识(URL). URI有两种形式.分别为U ...
- Pascal Analyzer 4 代码分析使用简要说明
概述 不管在那个开发团队中每个人的编写风格往往是千差万别能力也有高低,如何让别人快速看懂自己的代码维护你的代码.尽量避免不必要的简单错误,为编写代码作一定的约束是必不可少的.如果你说我一个人不需要规范 ...
- DataSource绑定DataTable.Select()显示system.data.DataRow问题解决的方法
有时候我们须要在控件中绑定DataTable中设定条件过滤后的数据,此时,在winForm环境中,一些控件不能正确绑定并显示数据内容.这是由于DataTable.Select()返回的是DataRow ...
- android的fragment基本介绍
可以分为下面的几部分: 使用支持库 创建一个Fragment 创建一个动态UI 多个Fragment之间的通信 1.使用支持库 如果您的应用需要运行在3.0及以上的版本,可以忽略这部分内容. 如果您的 ...