1.CPU工作原理
2.Linux内存分配
3.栈
1).存储局部变量 函数参数 函数返回值的地方
2).每个线程的栈空间连续且相互独立
3).使用 x /100a $esp 可以看到栈内存中的原始数据
3.函数调用过程
函数调用过程在栈中如何组织数据的
4.堆 三级堆管理
想详细了解的 阅读《glibc内存管理ptmalloc源代码分析.pdf》 及heapdump 源码
5.信息搜集
线程信息 栈空间 所有堆块 全局及局部变量 所有保存在core中的信息通过以上方法都能挖掘出来
5.1 查看内存信息
X /100x address
5.2 查看调用堆栈 X /100a $esp
5.3查看局部变量
Info locals
5.4 查看全局变量
P 全局变量名
5.5查看类实例
Info symbol *类实例地址
P *(类名*)类实例地址
5.6查看STL容器
Plist pmap …
5.7查看堆内存分配:
Heapdump –a
6.问题排查实例
问题排查的过程就是分析整合信息的过程,排查问题的过程就是,综合使用第二章介绍的各种方法收集信息,一步步刨根问底,抽丝剥茧的过程。 需要不断的尝试,假设,验证。是一种高级的脑力劳动,需要较大的耐心和对于原代码结构的熟悉,有时候定位一个深层次的问题需要几个月的时间的反复论证验证。
程序偶现崩溃 ?接下来怎么办?
6.1 观察以下core文件 有什么线索
1) core 大小200M左右 说明不是内存泄露导致的崩溃
2) 进程号 5030,通过进程号可以关联日志
3) 错误类型11 段错误。说明是内存访问异常了
6.2准备环境 使用gdb打开 core 文件
1) 安装dss7016_tools.tar.gz 工具包 保证 gdb(7.6) heapdump到位
2) 使用 gdb UMTS.exe ../UMTS_5030-1437863062-11.core -x .gdbinit 打开core文件,保证能正确解析stl容器
3) 使用 info sharedlibrary 检查库是否加载正确
6.3确认崩溃的表面原因
1) bt一下 崩溃在CZString::CZString构造函数里
2) disassemble一下 看看崩溃在哪行
3) info registers 一下 看看寄存器的值
4)表面原因确认 Mov edx,[eax +0x4] eax 值不对导致断错误
6.4 Eax 值为什么不对 第一个难点 优化栈的逆向追溯
1)参数__x的值不对 why?
参见stl_map.h和stl_tree.h
2)找到__X的值
3)现在可以确认 是这个map中的值不对导致的
4)map中的值为什么不对 超级难点 没有例行流程排查
5) 根本原因找到 CLiveChannel类已经释放 又操作了里面的锁 导致破坏了 thread 1的map结构导致 段错误