android ndk空指针导致CRASH的问题
2013-06-03 11:43
363 查看
1. APP启动时隔三差五地随机性地CRASH,捕捉到的日志:
----------------
2013-06-03 10:26:52
----------------
#00 pc 0002e9b4 /data/data/com.XXXX.map/lib/libmapengine.so
#01 lr 8082dc97 /data/data/com.XXXX.map/lib/libmapengine.so
2. CRASH在汇编码2e9b4位置,通过objdump工具生成so包对应的汇编文件,查找定位crash位置:
0002e9b4 <_ZN12TextureCache15ensureCacheSizeEi>:
2e9b4: 6803 ldr r3, [r0, #0]
2e9b6: 428b cmp r3, r1
2e9b8: da00 bge.n 2e9bc <_ZN12TextureCache15ensureCacheSizeEi+0x8>
2e9ba: 6001 str r1, [r0, #0]
2e9bc: 4770 bx lr第一行 2e9b4位置。
3. 对应ensureCacheSize函数源码:
void TextureCache::ensureCacheSize(int size){
if(limit < size){
limit = size;
}
}
看到函数源码以后,一时有点丈二摸不着头脑了,函数内部就一个if判断,何来的crash?2e9b4位置而且是一个ldr寻址操作,根据汇编源码得知是取limit成员变量值。
4. 跟一位经验丰富地同事讨论,他说这是典型地空指针导致的CRASH问题,原因如下:
这个函数如此调用:tileTexCache->ensureCacheSize(blkNum + 1); 当tileTexCache指针为空时,并不是在函数调用这行CRASH,而是在成员函数内部。
原理《C++对象模型》书中有讲解:C++中类的成员函数和成员变量不太一样,成员变量定义在对象内部,跟对象一个级别,与this指针有关;而成员函数则定义在类内部,跟类一个级别,与this指针无关。换个角度理解这句话,即使对象指针为空,通过空对象指针访问成员函数也是可以,只有当成员函数内部需要访问成员变量时才会CRASH,因为成员变量定义在对象内部。这个道理我懂,但怎么也跟空指针联系起来!
5. 测试DEMO
class EmptyPointerApp
{
public:
void safeFunc()
{
cout << "World Peace" << endl;
}
void badFunc()
{
cout << "Will Crash" << endl;
mData = 1;
}
private:
int mData;
};
int main(int argc, char** argv)
{
EmptyPointerApp* pSample = NULL;
pSample->safeFunc();
pSample->badFunc();
}vs2008,CRASH在mData=1语句,此时输出:
World Peace
Will Crash
调试中断后打开反汇编窗口:
![](https://img-blog.csdn.net/20130603112832375)
第一个mov将this指针内容放到eax寄存器中,dword ptr指明了指令访问内存的单元是一个dword,即四个字节长度。
第二个mov通过eax访问mData成员时CRASH!
----------------
2013-06-03 10:26:52
----------------
#00 pc 0002e9b4 /data/data/com.XXXX.map/lib/libmapengine.so
#01 lr 8082dc97 /data/data/com.XXXX.map/lib/libmapengine.so
2. CRASH在汇编码2e9b4位置,通过objdump工具生成so包对应的汇编文件,查找定位crash位置:
0002e9b4 <_ZN12TextureCache15ensureCacheSizeEi>:
2e9b4: 6803 ldr r3, [r0, #0]
2e9b6: 428b cmp r3, r1
2e9b8: da00 bge.n 2e9bc <_ZN12TextureCache15ensureCacheSizeEi+0x8>
2e9ba: 6001 str r1, [r0, #0]
2e9bc: 4770 bx lr第一行 2e9b4位置。
3. 对应ensureCacheSize函数源码:
void TextureCache::ensureCacheSize(int size){
if(limit < size){
limit = size;
}
}
看到函数源码以后,一时有点丈二摸不着头脑了,函数内部就一个if判断,何来的crash?2e9b4位置而且是一个ldr寻址操作,根据汇编源码得知是取limit成员变量值。
4. 跟一位经验丰富地同事讨论,他说这是典型地空指针导致的CRASH问题,原因如下:
这个函数如此调用:tileTexCache->ensureCacheSize(blkNum + 1); 当tileTexCache指针为空时,并不是在函数调用这行CRASH,而是在成员函数内部。
原理《C++对象模型》书中有讲解:C++中类的成员函数和成员变量不太一样,成员变量定义在对象内部,跟对象一个级别,与this指针有关;而成员函数则定义在类内部,跟类一个级别,与this指针无关。换个角度理解这句话,即使对象指针为空,通过空对象指针访问成员函数也是可以,只有当成员函数内部需要访问成员变量时才会CRASH,因为成员变量定义在对象内部。这个道理我懂,但怎么也跟空指针联系起来!
5. 测试DEMO
class EmptyPointerApp
{
public:
void safeFunc()
{
cout << "World Peace" << endl;
}
void badFunc()
{
cout << "Will Crash" << endl;
mData = 1;
}
private:
int mData;
};
int main(int argc, char** argv)
{
EmptyPointerApp* pSample = NULL;
pSample->safeFunc();
pSample->badFunc();
}vs2008,CRASH在mData=1语句,此时输出:
World Peace
Will Crash
调试中断后打开反汇编窗口:
第一个mov将this指针内容放到eax寄存器中,dword ptr指明了指令访问内存的单元是一个dword,即四个字节长度。
第二个mov通过eax访问mData成员时CRASH!
相关文章推荐
- 解决android应用被强杀或应用被回收导致的空指针问题
- Android Studio导致App出现crash的问题
- 【Android】【问题分析】G-sensor因数据交互问题导致手机crash
- Android 7.0 广播导致的crash问题
- Android ButterKnife导入之后编译报错或者空指针问题
- Android7.1 悬浮窗Unable to add window crash问题
- Android大图片导致内存问题小结
- Android singleInstance导致的问题及解析
- Android Bitmap太大导致ImageView不显示的问题
- Android权限问题导致的系统调用bug
- Android系统休眠导致的严重问题
- Android网络请求,请求参数是中文导致的乱码问题
- Android 在安装完成界面,点击打开应用程序。在应用程序点击home键,再从桌面打开程序导致产生多个实例或者说程序被重复打开。(为了把问题写清楚,标题一定要长长长........)
- Android 异步获取网络图片并处理导致内存溢出问题解决方法
- Android开发编码规范导致的内存泄露问题
- Eclipse更新ADT 插件导致Android项目报错问题
- Android 系统截屏与系统内置DVR录像冲突,导致SystemUI重启的问题解决与分享
- Android Recyclerview焦点变化问题导致下拉刷新视觉卡顿
- Android 控件 空指针问题
- android.view.WindowLeaked 问题彻底解决【dialog导致窗口泄露】