Android编译器优化导致的奇怪问题
来源:互联网 发布:ps3模拟器og数据损坏 编辑:程序博客网 时间:2024/06/15 07:01
最近在调试一个协程库的时候遇到奇怪的问题:在Ubuntu 10.04上调试协程一直正常,但是将协程库编译成.so文件后放入Android设备中,在应用程序中调用此库却出现强制退出的问题,刚开始遇到十分不解。
因为该协程库是利用单个线程来实现协程的,协程的栈空间其实直接分配在线程的栈空间上,于是对于这个问题我的第一直觉是可能是因为Android中Bionic库与glibc的不同而导致的。
我把这个现象与猜想与其他开发人员交流过后,讨论得出更加有可能是缺页中断而导致的,这种问题在消费电子上出现也可以理解,于是我在设备上做了这么一个实验:
void stack_test(){ int i; char _a[4096]; for(i = 0; i < 4096; i++){ _a[i] = 'A'; LOGD("_a[%d] is %c",i,_a[i]); } char _s = 's'; LOGD("_s is %c",_s); void *p = malloc(getpagesize()); memcpy(p+getpagesize(),'A',sizeof('A')); LOGD("malloc & memcpy done");}
将这个函数编译成为.so库中,在Android设备上调用pthread_create新建一个线程,将线程栈长度设置为足够大之后运行此函数,结果发现一切正常。
如此一来这个程序强制退出的问题是由于缺页中断引起的便站不住脚了。
失去了线索后我继续在库里面加打印尝试寻找新的方向,结果发现是在尝试访问协程栈的内存是出现程序强制退出,再一查看协程栈的内存地址,发现协程栈的地址范围已经超出了线程栈地址范围,这样问题就清晰多了,原来是因为内存访问错误,本来协程栈的内存应该被包括在进程栈里,现在由于不知名的问题导致了协程栈的内存分配错误,所以导致程序强制退出。
继续往下查找发现是库里面使用的检查机器栈增长方向的函数出现了错误,函数如下:
static int check_stack_dir(char *p){ char q; return (int)(p - &q);}static int stack_mp(){ char x; int dir = check_stack_dir(&x);}
正常情况下在Linux下函数check_stack_dir计算出来的结果应该为负值(因为栈的增长方向是由高地址到低地址的),但在Android设备上的计算结果却是正值,既然代码是没问题的,系统也应该没有问题,那么很有可能是编译出问题了。有可能是因为编译器优化将函数check_stack_dir里的变量q放在了stack_mp函数中变量char x前面去了。
根据这个猜测我修改了代码,将函数int check_stack_dir声明为:
int check_stack_dir(char *p)
这样编译器就无法做出刚才的优化了,好,上机调试,一切正常,完毕!
- Android编译器优化导致的奇怪问题
- 奇怪的VS2005编译器问题
- 防止编译器过度优化导致的并发异常问题
- keil编译器很奇怪的问题
- 编译器的优化问题
- 编译器的优化问题
- QT 线程导致奇怪错误的问题
- Android 奇怪的问题
- 奇怪的编译器
- android机器一个奇怪的白屏死机问题--原来是wifi导致
- cuda 1.x 编译器产生的奇怪问题及解决方法
- android studio的奇怪问题
- android 一个奇怪的问题
- 电源问题导致奇怪现象
- 记一次ORACLE SQLPLUS 无响应 导致的奇怪问题
- mapred streaming 脚本输出运行状态导致的奇怪问题
- 虚幻4 pure函数导致的奇怪问题
- 编译器优化导致硬件寄存器写入失败的一个例子
- 获取不固定大小的网络图片,然后在UITableviewCell中显示
- 【Windows】线程漫谈——线程基础(一)
- 实时检测网络状态
- 浅析CVE-2009-2692
- php 伪静态(url rewrite)apache配置!
- Android编译器优化导致的奇怪问题
- 为bootstrap添加更多自定义图标
- 《Effective Java》阅读笔记(二)
- java图片转二进制
- 移植RT3070AP过程
- Java的反射机制(1)-反射功能的基本介绍
- PHP根据访问ip获取所在城市的信息
- strchr函数
- NavigationController 返回箭头的颜色