摘要
arm下出现段错误,却没有回溯到具体的函数,一直在寻找这个问题的原因,在x86 之类的模式下同样的代码是有回溯的。
arm 32 位设备下测试
分析
尝试了很多方法,最终找到一些线索
基础知识
这里就是栈布局的基本原因,网上有很多说这个的,这个可以去尝试搜索一下,这边暂时不讲这方面的知识,网上太多了
主要说一下区别,x86模式下能回溯,arm下不能回溯,主要原因就是在于对栈布局的格式不同,x86模式下会有全面的入栈顺序,寄存器中的值是可能详细追踪具体位置的。
但是在arm下,可能因为速度等方面的追求,默认情况下栈相关的寄存器有些是没有的。
具体信息
以下方的代码为例
static char *p = NULL;
void d()
{
printf("this is d\n");
}
typedef struct Test
{
char s[1024];
int a;
} Test;
void c()
{
d();
// *p = 8;
Test *s_test;
sprintf(s_test->s, "%ld", time(NULL));
}
void b()
{
c();
printf("this is c\n");
}
void a()
{
b();
printf("this is a\n");
}
int main()
{
init_signal();
a();
return 0;
}
init_signal 为信号捕捉,可以不用管
其中 c() 函数会出现段错误,这里测了 全局的p指针和结构体两种,下面会说明两个的区别
默认编译
arm-xxx-g++ -g -o xxx xxx.c xxx
这样编译出来的代码反编译如下
00010c90 <_Z1dv>:
10c90: e92d4800 push {
fp, lr}
10c94: e28db004 add fp, sp, #4
10c98: e30200a0 movw r0, #8352 ; 0x20a0
10c9c: e3400001 movt r0, #1
10ca0: ebffffa8 bl 10b48 <puts@plt>
10ca4: e320f000 nop