即使在i386上,是否有可能捕获数据对齐错误?也许通过设置i386特定的机器寄存器或类似的东西。
在Solaris-Sparc上我在这种情况下收到一个SIGBUS,但是在i386上一切都很好。
环境:
修改: 这就是我问这个问题的原因:
答案 0 :(得分:9)
与此同时,我发现了一个处理此主题的英特尔CPU文档。
请参阅Intel® 64 and IA-32 Architectures Software Developer’s Manual。
似乎很难将所有这些东西放在一起。然而,这听起来并非完全不可能。有趣的章节是 4.10.5检查对齐
编辑(上述文件中的一些简明材料):
第5-60页
Interrupt 17 Alignment Check Exception (#AC)
to enable alignment checking, the following conditions must be true:
AM flag is set(bit 18 of control regisster CR0)
AC flag is set (bit 18 of the EFLAGS)
The CPL is 3 (protected mode or virtual-8086 mode).
另外 - 在14.8.2.6中 - 提到内存控制器错误。我不知道它是否只是换句话说:
table 14-11, Encoding of MMM and CCCC Sub-Fields
Address/Command Error AC 011
答案 1 :(得分:4)
为了扩展Vokuhila-Oliba的答案,看看“SOF Mis-aligned pointers on x86.”线程,似乎gcc可以生成具有错误对齐的内存访问的代码。 AFAIK你无法控制它。
对gcc编译的代码启用对齐检查是个坏主意。您可能会因良好的 C代码而出现SIGBUS错误。
ReEdited:对不起
答案 2 :(得分:3)
我在SOF上找到了一个非常简单的解决方案!请参阅:Mis-aligned pointers on x86。
int main(int argc, char **argv)
{
# if defined i386
/* EDIT: enable AC check */
asm("pushf; "
"orl $(1<<18), (%esp); "
"popf;");
# endif
char d[] = "12345678"; /* yep! - causes SIGBUS even on Linux-i386 */
return 0;
}
但我必须承认,我不明白为什么要分配
char d [] =“12345678”;
被认为是错位的?
编辑:
在SPARC机器上在 char d [] 的赋值行上没有SIGBUS。
答案 3 :(得分:3)
英特尔在支持未对齐的负载方面非常重要。如果我必须在Intel平台上检测到这样的负载,我想我必须修改valgrind
以将未对齐的负载视为错误。这样的修改并非易事,但是valgrind的设计理念是用户可以创建新的“工具”。我认为对memcheck
工具的简单修改会检测到您的未对齐引用。错误报告非常好。
答案 4 :(得分:1)
许多年后:如果你的gcc / clang足够新(GCC 4.9,clang 3.3?),你可以使用未定义的行为清理程序(-fsanitize=undefined
)构建代码,以获取有关未对齐访问的警告给定的平台(但请记住,不同的平台有不同的对齐要求,不同的编译器会选择不同的布局等)。有关详细信息,请参阅https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html和https://developers.redhat.com/blog/2014/10/16/gcc-undefined-behavior-sanitizer-ubsan/。
答案 5 :(得分:0)
英特尔从一开始就建立了不对齐的转让 - 这是x86全新的卖点之一。我理解你想要捕获未对齐访问的原因,但我认为这是不可能的。
编辑:非常高兴被证明是错误的。