dimanche 27 novembre 2016

Compiler's alignment assumptions in std::copy

I am dealing with a curious case where I (suddenly) started getting segmentation fault in a library code (which I wrote a while ago).

The library has a code which is responsible to copy buffers, here is the code snapshot:

   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);

Now when I got the segmentation fault, in the backtrace I saw that std::copy called to other STL methods which finally came to __builtin_memmove which in its turn was substituted by the compiler with __memmove_ssse3().

The problem here is that the src_buff value in this specific case was 0xXXXXXXXXX509 and according to what I saw in this SO answer, SSSE3 instructions require some minimal alignment of the parameters. The suggestion in that answer was to try to compile the code with -mpreferred-stack-boundary=4 -mstackrealign flags which kind of resolved my problem (or maybe just masked it???).

Now if the initial assumption was correct and the problem here is the parameter's alignment, then why does the compiler use __memmove_ssse3() when the parameters sent to std::copy are of type char *for which no alignment assumptions can be applied?!

The original compilation was done with g++ version 5.2.0 using the following compilation flags:

-m64 -fPIC -fmessage-length=0 -std=c++11 -O0 -g3

and after adding the additional

-mpreferred-stack-boundary=4 -mstackrealign

everything passed smoothly.

Aucun commentaire:

Enregistrer un commentaire