你好,我是杂汤君。
最近踩了公交车错误的坑,简单总结了一下,再分享一下。
什么是公交车错误?
平时开发过程中,我们经常遇到的导致流程崩溃的错误大部分是分段错误。段错误是指访问超出系统提供的内存空间的内存,包括空指针操作、数组超出范围等。
与段错误一样,总线错误(Bus Error)是因为对未排序地址的访问导致CPU读数据违反了特定的总线规则。
出于性能考虑,当需要访问数据时,CPU必须对地址进行排序。如果不是地址排序访问,SIGBUS信号将发送到进程,进程将生成核心dump。
总线错误与CPU体系结构相关,某些体系结构中的CPU支持支持无序访问。下面我们通过例子分析一下。
总线错误示例
# include
# include
#pragma pack(1)
Struct struct_x
{
CHAR A;
float b;
CHAR C;
}
#pragma pack()
int main(void)
{
struct struct _ x test={ 0 };
printf(' sizeof(struct struct _ x)=% LD \ n ',size of(测试));
=1;
=2.0;
=3;
char * a=;
float * b=;
char * c=;
Printf('*a=%d,addr=%p\n ',*a,a);
Printf('*b=%f,addr=%p\n ',*b,b);
Printf('*c=%d,addr=%p\n ',*c,c);
return 0;
}#pragma pack编译器排序可以更改。
#pragma pack(n) /*指定以n字节对齐*/
#pragma pack() /*取消对齐自定义字节*/在PC端正常工作。
X86/x64系列CPU都支持非对齐访问,因此还提供了禁用此机制的开关。如果X86/x64体系结构不需要排序访问,则会产生性能成本。
但是,在arm主板上测试以下内容:
发生总线错误,因为核心变量test的成员B的地址是未排序的地址。CPU访问地址要求是4字节对齐,访问*(addr0x001)导致异常。
此时,请在struct_x的成员a、b之前添加占3个字节的成员d,以查看是否报告了错误。
Struct struct_x
{
CHAR A;
茶d[3];
float b;
CHAR C;
}
此时,成员b可以正常访问,因为b的地址在4字节对齐地址中。
上述公交车错误无疑是由于对齐问题造成的。
但是这里有一个疑问。将成员B的类型更改为int类型是否会导致总线错误?
# include
# include
#pragma pack(1)
Struct struct_x
{
CHAR A;
int b;
CHAR C;
}
#pragma pack()
int main(void)
{
struct struct _ x test={ 0 };
printf(' sizeof(struct struct _ x)=% LD \ n ',size of(测试));
=1;
=2;
=3;
char * a=;
int * b=;
char * c=;
Printf ('sizeof (float)=% d,sizeof (int)=% d \ n ',sizeof (float),sizeof (int)
Printf('*a=%d,addr=%p\n ',*a,a);
Printf('*b=%d,addr=%p\n ',*b,b);
Printf('*c=%d,addr=%p\n ',*c,c);
return 0;
}
其中,int类型的b成员可以正常访问。其中,成员B的地址与上面发生总线错误的成员B的地址(float类型)完全相同。float类型和int类型也占用4个字节,但int类型B成员可能支持未排序的访问。
现在,暂时认为CPU是这样设计的。能说明这个问题的朋友欢迎评论讨论。感谢大家。
摘要
上述int类型的B成员可以正常访问,但在实际编程中,必须小心修改排序。如有必要,请尝试使修改后的排序的代码范围尽可能小。例如,只关注结构体,很清楚有这样的事情,所以在后面添加代码时要非常小心。
以上是这次分享。如果你认为文章有帮助,请转达,谢谢。(大卫亚设)。
我想你喜欢:
共享好的嵌入式数据摘要贴纸。
1024G嵌入式资源广播!包括但不限于C/C、单片机、Linux等。私信回复1024,可以免费收到!
1.《【海尔总线数据调乱了怎么办】通过例子了解公交车错误,不要踩坑。》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。
2.《【海尔总线数据调乱了怎么办】通过例子了解公交车错误,不要踩坑。》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。
3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/why/3089348.html