编译器在std :: copy中的对齐假设

时间:2016-11-27 20:29:32

标签: c++ stl g++ compiler-optimization built-in

我正在处理一个奇怪的案例,我(突然)开始在库代码中开始出现分段错误(我刚才写过)。

该库有一个代码,负责复制缓冲区,这里是代码快照:

   memory_manager_types::translation_status_t memory_manager::setMem(const uint64_t i_la, const void * const src_buff, const uint32_t i_size)
   {
        ...
        char* dst_ptr = reinterpret_cast<char*>(pa); // pa is a 'uint64_t' which holds the destination address
        const char* src_ptr = static_cast<const char*>(src_buff);
        std::copy(src_ptr, src_ptr + i_size, dst_ptr);

现在当我得到分段错误时,在回溯中我看到std::copy调用了其他STL方法,这些方法最终来到__builtin_memmove,而__memmove_ssse3()又被编译器替换为src_buff }。

这里的问题是这个特定情况下的-mpreferred-stack-boundary=4 -mstackrealign值是0xXXXXXXXXX 509 ,根据我在this SO answer中看到的,SSSE3指令需要一些最小的对齐参数。该答案中的建议是尝试使用__memmove_ssse3()标志编译代码,这样可以解决我的问题(或者只是掩盖它?)。

现在,如果初始假设是正确的,并且此处的问题是参数的对齐,那么为什么当发送到std::copy的参数属于类型时,编译器会使用char *可以应用无对齐假设g++?!

使用以下编译标志使用-m64 -fPIC -fmessage-length=0 -std=c++11 -O0 -g3 版本5.2.0完成原始编译:

-mpreferred-stack-boundary=4 -mstackrealign

并在添加其他

之后
-mstackrealign
一切顺利通过。

EDIT1

我没有提到的并且可能是我的问题的答案是,使用我的库的代码是使用较低版本的GCC(4.2.2)编译的。

现在根据 const char* text = "hi"; printf("%s\n",text); printf("%p\n", &text); printf("%p\n", text); 标志的描述:

  

-mstackrealign

     

在入口处重新对齐堆栈。在Intel x86上,-mstackrealign选项将生成备用序言和结尾,以便在必要时重新调整运行时堆栈。这支持混合   遗留代码,保持4字节对齐堆栈与现代代码   保持一个16字节的堆栈以实现SSE兼容性。另请参见属性   force_align_arg_pointer,适用于个别职能。

默认情况下,G ++ 5.2.0是否假设16字节堆栈对齐?

0 个答案:

没有答案