ARMLinux下Alignment trap的一些测试 【转自 李迟的专栏 CSDN http://blog.csdn.net/subfate/article/details/7847356
项目中有时会遇到字节对齐的问题,英文为“Alignment trap”,如果直译,意思为“对齐陷阱”,不过这个说法不太好理解,还是直接用英文来表达。
ARM平台下一般是4字节对齐,可以参考文后的给出的文章链接。此处不细说。后面提及“字节对齐”
下面的例子使用了几种重现Alignment trap的方法,例子1是将char*指针直接转换成int*指针,经测试,未发现有字节对齐的问题。例子2和例子3相似,主要是结构体中的字段没有进行对齐(或者访问的地址没有4字节对齐)。例子4是直接访问了没有字节对齐的指针。后3个例子在测试时均出现了错误。
*
Linux下对Alignment trap的处理有下面几种方式:
0 (ignored)
1 (warn)
2 (fixup)
3 (fixup+warn)
4 (signal)
5 (signal+warn)
使用方法:
# echo 3 > /proc/cpu/alignment
*/
#include <stdio.h>
#include <stdlib.h>
/// case 1
void fool(unsigned char* buf, int len)
{
unsigned int* p = (unsigned int*)buf;
int i;
for (i = 0; i < len; i++)
{
*p++ = i+1;
printf("%d ", *p);
}
}
void foolish()
{
unsigned char poor[100];
fool(poor, sizeof(poor)/sizeof(int));
}
// case 1 end
////////////////////////////////////////////////////////////////
/// case 2
struct rte_unpacked_struct_t
{
char c1;
int i;
char c2;
short s1;
char c3;
};
struct rte_packed_struct_t
{
char c1;
int i;
char c2;
short s1;
char c3;
}__attribute__((__packed__));
struct rte_unpacked_struct_t unpacked;
struct rte_packed_struct_t packed;
void print_addr()
{
printf("sizeof(unpacked) = %d sizeof(packed) = %d\n", sizeof(unpacked), sizeof(packed));
printf("Addr of unpacked: %p\n", &unpacked);
printf("Addr of unpacked.c1: %p\n", &unpacked.c1);
printf("Addr of unpacked.i: %p\n", &unpacked.i);
printf("Addr of unpacked.c2: %p\n", &unpacked.c2);
printf("Addr of unpacked.s1: %p\n", &unpacked.s1);
printf("Addr of unpacked.c3: %p\n", &unpacked.c3);
printf("Addr of packed: %p\n", &packed);
printf("Addr of packed.c1: %p\n", &packed.c1);
printf("Addr of packed.i: %p\n", &packed.i);
printf("Addr of packed.c2: %p\n", &packed.c2);
printf("Addr of packed.s1: %p\n", &packed.s1);
printf("Addr of packed.c3: %p\n", &packed.c3);
}
short* rte_get_s1(void)
{
return &unpacked.s1;
}
void case2()
{
print_addr();
int* val = (int *)rte_get_s1();
printf("val = %d\n", *val);
}
/// case 2 end
////////////////////////////////////////////////////////////////
/// case 3
struct foo_t
{
short a;
short b;
short c;
short d;
};
struct foo_t foo;
short* get_foo_c(void)
{
return &foo.c;
}
void case3()
{
printf("sizeof(foo) = %d\n", sizeof(foo));
// 注意!!此处将short*强制转换为int*,造成出错
int* val = (int *)get_foo_c();
printf("val: %d\n", *val);
}
// case 3 end
//////////////////////////////////////////////////////////////
/// case 4
void case4()
{
char* str = "01234567";
unsigned* u = (unsigned *)(str+1);
printf("0x%08x\n", *u);
}
/// case 4 end
int main()
{
printf("test of alignment trap...\n");
//foolish();
//case2();
//case3();
case4();
return 0;
}
以下是在某ARMLinux平台下的测试结果,依次将错误处理等级设置为0到5,出现不的结果,如下:
# ./a.out
test of alignment trap...
0x30333231
# echo 1 > /proc/cpu/alignment
# ./a.out
testAlignment trap: a.out (1125) PC=0x000086c8 Instr=0xe5931000 Address=0x00008961 FSR 0x001
of alignment trap...
0x30333231
# echo 2 > /proc/cpu/alignment
# ./a.out
test of alignment trap...
0x34333231
# echo 3 > /proc/cpu/alignment
# ./a.out
testAlignment trap: a.out (1127) PC=0x000086c8 Instr=0xe5931000 Address=0x00008961 FSR 0x001
of alignment trap...
0x34333231
# echo 4 > /proc/cpu/alignment
# ./a.out
test of alignment trap...
Bus error
# echo 5 > /proc/cpu/alignment
# ./a.out
testAlignment trap: a.out (1129) PC=0x000086c8 Instr=0xe5931000 Address=0x00008961 FSR 0x001
of alignment trap...
Bus error
常用的是使用等级3来处理,即提示错误并进行修复。
上面只讲到如何使用代码出现字节对齐错误,但没涉及如何排查问题。示例代码十分简单,很容易定位错误地方,但如果在大型项目中,就很难定位,尤其是在嵌入
式中,——嵌入式的调试也相对比较困难、麻烦。以我的经验,与其用gdbserver来调试,不如靠经验及printf大法解决问题来得更快(当然,仅个
人看法)。
本来想用工具调试来发现出错的代码位置,但尝试了,没结果。
在代码编写中,需要注意一下以下的事:
1、结构体尽量使用4字节对齐,比如设置一个传输长度len的类型时,用short表示的范围已经足够,当然也可以用int。像制定一些网络协议,最好考虑一下4字节对齐。
2、分配内存时也尽量4字节对齐,无论是申请的内存还是定义数组大小。
3、对指针进行访问的时候也要十分注意4字节对齐,特别是一些为了避免编译警告的强制类型转换。
参考资料:
http://www.rt-embedded.com/blog/archives/resolving-alignment-traps/
http://simplemachines.it/arm-linux/book/afaq.html
迟 代码随笔 即日
ARMLinux下Alignment trap的一些测试 【转自 李迟的专栏 CSDN http://blog.csdn.net/subfate/article/details/7847356的更多相关文章
- Alignment trap 解决方法 【转 结合上一篇
前几天交叉编译crtmpserver到arm9下.编译通过,但是运行的时候,总是提示Alignment trap,但是并不影响程序的运行.这依然很令人不爽,因为不知道是什么原因引起的,这就像一颗定时炸 ...
- coreseek实战(一):windows下coreseek的安装与测试
coreseek实战(一):windows下coreseek的安装与测试 网上关于 coreseek 在 windows 下安装与使用的教程有很多,官方也有详细的教程,这里我也只是按着官方提供的教程详 ...
- linux下开发板网络速度测试记录
由于做的项目对于网络和USB的读写速度有很高的要求,因此新拿回来的板子要测试网络和usb的最佳传输速度.要考虑不少因素,先把我能想到的记录下来. 测试的环境是开发板和ubuntu虚拟机 ...
- ubuntu下opencv2.4.9安装测试
ubuntu下opencv2.4.9安装测试 whowhoha@outlook.com 一.依赖包安装 1. build-essential 软件包 sudo apt-get install bui ...
- mosquitto在Linux环境下的部署/安装/使用/测试
mosquitto在Linux环境下的部署 看了有三四天的的源码,(当然没怎么好好看了),突然发现对mosquitto的源码有了一点点感觉,于是在第五天决定在Linux环境下部署mosquitto. ...
- Tomcat免安装版的环境变量配置以及Eclipse下的Tomcat配置和测试
Tomcat是目前比较流行的开源且免费的Web应用服务器,在我的电脑上第一次安装Tomcat,再经过网上教程和自己的摸索后,将这个过程 重新记录下来,以便以后如果忘记了可以随时查看. 注意:首先要明确 ...
- [原创]MinHook测试与分析(x64下 E9,EB,CALL指令测试,且逆推测试微软热补丁)
依稀记得第一次接触Hook的概念是在周伟民先生的书中-><<多任务下的数据结构与算法>>,当时觉得Hook很奇妙,有机会要学习到,正好近段日子找来了MiniHook,就一 ...
- win10下caffe安装与mnist测试实验注意点
caffe安装 安装内容:win10教育版+anaconda2+python(无gpu版本) 安装教程:主要依照三年一梦教程:https://www.cnblogs.com/king-lps/p/65 ...
- linux环境下使用jmeter进行压力测试
linux环境下使用jmeter进行压力测试 linux环境下使用就meter进行压力测试: linux环境部署: 在Linux服务器先安装jdk: 2.以jdk-8u172-linux-x64.ta ...
随机推荐
- 关于GRUB2
grub2启动引导 GRUB 2是GNU GRUB(GRand Unified Bootloader)的最新版本.bootloader(引导程序)是计算机开机后(bios自检之后)第一个运行的软件程序 ...
- MYSQL 模糊查询
下面介绍mysql中模糊查询的四种用法: 1,%:表示任意0个或多个字符.可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示. 比如 SELECT * FROM [user] ...
- spring框架学习(六)AOP
AOP(Aspect-OrientedProgramming)面向方面编程,与OOP完全不同,使用AOP编程系统被分为方面或关注点,而不是OOP中的对象. AOP的引入 在OOP面向对象的使用中,无可 ...
- mysql大数据分表记录app用户的坐标数据
最近提到一个需求.需要记录app用户在使用app中的移动轨迹,即坐标值.每分钟上传一次XY坐标,有点类似跑步软件的描线轨迹. 不考虑app如何获取,反正api只要接受到坐标数据 就记录下来保存到数据库 ...
- 原生Android App项目调用Untiy导出的Android项目
背景:采用Google VR SDK for Unity 开发3D场景功能,然后导出Android项目,合并到一个Android App里面,供其它Activity调用. 用Google VR for ...
- 简述linux的发行版,并描述不同发行版之间的联系与区别
bash命令行返回值和展开 标签(空格分隔): bash,命令,状态,展开 1.命令状态结果和执行结果 (1)命令执行的状态返回值,命令执行完成之后,其执行状态结果值保存于bash的特殊状态变量$?中 ...
- nodejs解决找不到express命令的问题
一般的书或者教程上的安装步骤是:(需要是-g,即全局安装) npm install -g express //全局安装 而我们应该多多关注下express的文档,github地址:https://gi ...
- oracle 中数据库完全导入导出:cmd命令行模式(转载)
http://www.3lian.com/edu/2012/12-01/47252.html Oracle数据导入导出imp/exp就相当于oracle数据还原与备份.exp命令可以把数据从远程数据库 ...
- Jquery mobile 新手问题总汇
1页面缩放显示问题 问题描述: 页面似乎被缩小了,屏幕太宽了. 解决办法: 在head标签内加入: <meta name="viewport" content="w ...
- php知识案列分享
今天再跟大家分享一下,以下案列. 使用array_flip函数生成随机数,可以去掉重复值. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 < ...