// Compiled with GCC 7.3.0, x86-64 -g -O3 -std=gnu++11
// Tested on OS (1) Ubuntu 18.04 LTS, (2) Gentoo
int Listen(... socket)
{
char buffer[INT16_MAX];
. . .
. . . = recvfrom(socket, buffer, ....)
ParseMsg(buffer)
}
void ParseMsg(uint8_t *const msg)
{
. . .
uint16_t* word_arr = (uint16_t*)(msg+15); // if I changed 15 to 16 (aligned to uint16_t)
// the program doesn't crash
for(size_t i = 0 ; i < 30 ; ++i)
{
word_arr[i] = 1; // after some iterations (around 13) the program crashes with segmentation fault
// if i add a print statement inside the loop the program doesn't crash
}
// word_arr[20] = 1; // if I assign value not in loop the program doesn't crash
}
我找到了一些讨论此事的链接:
https://github.com/samtools/htslib/issues/400
https://github.com/xianyi/OpenBLAS/issues/1137
但他们用的是处理器术语。有人可以确认这个错误存在吗?
附注
我使用 -O2 优化标志运行代码。没有崩溃
最佳答案
这个问题确实强调了 uint16_t
指针的对齐(应该是 2),结合 -O3
编译器正在尝试使用向量化来优化循环(SIMD),因此尝试将未对齐的参数加载到 SSE 寄存器。
这可以解释为什么它在以下情况下起作用:
- 将偏移量从 15 更改为 16 - 导致
uint16_t
指针对齐 - 使用
-O2
- 禁用矢量化 - 删除循环/在循环内添加打印 - 同时禁用矢量化
请参阅以下链接,其中包含与您的问题类似的问题以及一些精彩详细的答案:
c-undefined-behavior-strict-aliasing-rule-or-incorrect-alignment
关于gcc - 迭代和取消引用未对齐的内存指针会导致段错误吗? GCC 优化器中的错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67684698/