While testing the memif plugin (src/plugins/memif) we discovered that one of the calls to clib_memcpy looses its effect in the release build. Specifically, the issue occurs in src/plugins/memif/memif.c, line 371:
else if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) { clib_memcpy (fd_array, CMSG_DATA (cmsg), sizeof (fd_array)); }
Here clib_memcpy has no effect when the plugin is build with the second level of optimizations.
Relevant parameters of my system:
$ uname -a Linux milan-Ubuntu 4.4.0-72-generic #93-Ubuntu SMP Fri Mar 31 14:07:41 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux $ gcc --version gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
You can tell if the issue is reproducible on your system using the following simple program called clib_memcpy.c:
#include <stdio.h> #include <vppinfra/types.h> #if __AVX__ #include <vppinfra/memcpy_avx.h> #elif __SSSE3__ #include <vppinfra/memcpy_sse3.h> #endif #define COUNT 2 // misbehaves for two and three integers; on my system sizeof(int) == 4 // Problematic part (from memcpy_sse3.h): // 217 if (n & 0x08) // 218 { // 219 *(u64 *) dstu = *(const u64 *) srcu; // 220 } int main() { int src[COUNT] = { 0 }, dst[COUNT] = { 0 }; src[0] = 1; #if COUNT > 1 src[1] = 5; #endif clib_memcpy(dst, src, sizeof src); printf("sizeof(src) = %d, dst = { %d, %d }\n", sizeof(src), dst[0], dst[1]); return 0; }
In my case the output is:
$ gcc clib_memcpy.c -w -mavx2 -o clib_memcpy $ ./clib_memcpy sizeof(src) = 8, dst = { 1, 5 } $ gcc -O2 clib_memcpy.c -w -mavx2 -o clib_memcpy $ ./clib_memcpy sizeof(src) = 8, dst = { 0, 0 } $ gcc clib_memcpy.c -w -mssse3 -o clib_memcpy $ ./clib_memcpy sizeof(src) = 8, dst = { 1, 5 } $ gcc -O2 clib_memcpy.c -w -mssse3 -o clib_memcpy $ ./clib_memcpy sizeof(src) = 8, dst = { 0, 0 }
The problem occurs when copying data of size between 8 and 15 bytes.