gcc - 迭代和取消引用未对齐的内存指针会导致段错误吗? GCC 优化器中的错误?

标签 gcc optimization segmentation-fault compiler-optimization memory-alignment

// 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 寄存器。

这可以解释为什么它在以下情况下起作用:

  1. 将偏移量从 15 更改为 16 - 导致 uint16_t 指针对齐
  2. 使用-O2 - 禁用矢量化
  3. 删除循环/在循环内添加打印 - 同时禁用矢量化

请参阅以下链接,其中包含与您的问题类似的问题以及一些精彩详细的答案:

c-undefined-behavior-strict-aliasing-rule-or-incorrect-alignment

关于gcc - 迭代和取消引用未对齐的内存指针会导致段错误吗? GCC 优化器中的错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67684698/

相关文章:

c - 尝试使用 union 来索引结构中的数据

c - 使用 TQLI 算法进行特征值计算失败并出现段错误

php - PHP 中的段错误,使用 SOAP 连接到 SalesForce

linux - 堆栈溢出 - 奇怪的返回地址

c++ - 使用快速排序对可能包含无穷大的容器进行排序是否安全?

c++ - 找出一个数的除数

sql - 有没有比子查询更有效的方法来将 group by 的结果与表连接起来?

gcc - 在至强融核上使用 GCC

gcc - 如何从 gcc(或其他地方)获取合法 ARM 操作码列表?

c++ - 撤销递归树