Valgrind не обнаруживает перекрытие memcpy?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Valgrind не обнаруживает перекрытие memcpy?

Сообщение Anonymous »

У меня есть функция, которая, как мне кажется, имеет перекрывающуюся память. Поскольку я пишу перед тем, откуда буду читать, похоже, что memcpy перейдет в неопределенное поведение

Код: Выделить всё

void overlappingMemcpy() {
int* data = new int[20];
iota(data, data + 20, 1);
printIntData(data, 20);
memcpy(data+1, data, 19*sizeof(int));
printIntData(data, 20);
delete[] data;
}
Но когда он запускается с помощью Valgrind, я не вижу ошибок,

Код: Выделить всё

> valgrind --tool=memcheck  ./ValgrindExamples
==81068== Memcheck, a memory error detector
==81068== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==81068== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==81068== Command: ./ValgrindExamples
==81068==
Hello World!
int data for memory at 0x5b210c0of size 20
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
int data for memory at 0x5b210c0of size 20
1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
==81068==
==81068== HEAP SUMMARY:
==81068==     in use at exit: 0 bytes in 0 blocks
==81068==   total heap usage: 3 allocs, 3 frees, 73,808 bytes allocated
==81068==
==81068== All heap blocks were freed -- no leaks are possible
==81068==
==81068== For counts of detected and suppressed errors, rerun with: -v
==81068== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Я компилирую с помощью -O0 -g -fno-inlines -std=c++14. Сборка показывает вызов memcpy, что указывает на то, что компилятор не встроил его, поэтому я совершенно не понимаю, почему это не срабатывает. Полная сборка, созданная указанным выше методом,

Код: Выделить всё

        128 [1] void overlappingMemcpy() {
0x401320                   55                                            push   %rbp
0x401321          48 89 e5                                      mov    %rsp,%rbp
0x401324          48 83 ec 20                                   sub    $0x20,%rsp
0x401328          b8 50 00 00 00                                mov    $0x50,%eax
0x40132d          89 c7                                         mov    %eax,%edi
129 [1]     int* data = new int[20];
0x40132f          e8 dc f9 ff ff                                callq  0x400d10 
0x401334          ba 01 00 00 00                                mov    $0x1,%edx
0x401339          48 89 45 f8                                   mov    %rax,-0x8(%rbp)
130 [1]     iota(data, data + 20, 1);
0x40133d          48 8b 7d f8                                   mov    -0x8(%rbp),%rdi
0x401341          48 8b 45 f8                                   mov    -0x8(%rbp),%rax
0x401345          48 83 c0 50                                   add    $0x50,%rax
0x401349          48 89 c6                                      mov    %rax,%rsi
0x40134c          e8 cf 00 00 00                                callq  0x401420 
0x401351          ba 14 00 00 00                                mov    $0x14,%edx
0x401356          89 d6                                         mov    %edx,%esi
131 [1]     printIntData(data, 20);
0x401358          48 8b 7d f8                                   mov    -0x8(%rbp),%rdi
0x40135c          e8 df fb ff ff                                callq  0x400f40 
0x401361          ba 14 00 00 00                                mov    $0x14,%edx
0x401366          89 d6                                         mov    %edx,%esi
0x401368          ba 4c 00 00 00                                mov    $0x4c,%edx
132 [1]     memcpy(data+1, data, 19*sizeof(int));
0x40136d          48 8b 45 f8                                   mov    -0x8(%rbp),%rax
0x401371          48 83 c0 04                                   add    $0x4,%rax
0x401375          48 8b 7d f8                                   mov    -0x8(%rbp),%rdi
0x401379          48 89 7d f0                                   mov    %rdi,-0x10(%rbp)
0x40137d          48 89 c7                                      mov    %rax,%rdi
0x401380          48 8b 45 f0                                   mov    -0x10(%rbp),%rax
0x401384          48 89 75 e8                                   mov    %rsi,-0x18(%rbp)
0x401388          48 89 c6                                      mov    %rax,%rsi
0x40138b          e8 d0 f9 ff ff                                callq  0x400d60 
133 [1]     printIntData(data, 20);
0x401390          48 8b 7d f8                                   mov    -0x8(%rbp),%rdi
0x401394          48 8b 75 e8                                   mov    -0x18(%rbp),%rsi
0x401398          e8 a3 fb ff ff                                callq  0x400f40 
134 [1]     delete[] data;
0x40139d          48 8b 45 f8                                   mov    -0x8(%rbp),%rax
0x4013a1          48 83 f8 00                                   cmp    $0x0,%rax
0x4013a5          48 89 45 e0                                   mov    %rax,-0x20(%rbp)
0x4013a9          0f 84 0c 00 00 00                             je     0x4013bb 
0x4013af          48 8b 45 e0                                   mov    -0x20(%rbp),%rax
0x4013b3          48 89 c7                                      mov    %rax,%rdi
0x4013b6          e8 05 fa ff ff                                callq  0x400dc0 
135 [1] }
0x4013bb          48 83 c4 20                                   add    $0x20,%rsp
0x4013bf          5d                                            pop    %rbp
0x4013c0           c3                                            retq
Разве инструмент не должен сообщать об этом? На странице документации говорится, что он обнаруживает «Передаёт перекрывающиеся блоки памяти источника и назначения в memcpy() и связанные функции».
Редактировать
Благодаря комментатору я обнаружил, что оптимизированная версия memcpy, которая, по-видимому, вызывается в приведенной выше сборке, перенаправляется Valgrind на memmove (по крайней мере, я так предполагаю). Подробный запуск Valgrind приведен ниже:

Код: Выделить всё

> valgrind -v  ./ValgrindExamples
==56912== Memcheck, a memory error detector
==56912== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==56912== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==56912== Command: ./ValgrindExamples
==56912==
--56912-- Valgrind options:
--56912--    -v
--56912-- Contents of /proc/version:
--56912--   Linux version 4.14.7-041407-generic (kernel@gloin) (gcc version 7.2.0 (Ubuntu 7.2.0-8ubuntu3)) #201712171031 SMP Sun Dec 17 15:33:35 UTC 2017
--56912--
--56912-- Arch and hwcaps: AMD64, LittleEndian, amd64-cx16-lzcnt-rdtscp-sse3-avx-avx2-bmi
--56912-- Page sizes: currently 4096, max supported 4096
--56912-- Valgrind library directory: /usr/lib/valgrind
--56912-- Reading syms from /home/charlie/Projects/build-ValgrindExamples-Desktop-Default/ValgrindExamples
--56912-- Reading syms from /lib/x86_64-linux-gnu/ld-2.26.so
--56912--   Considering /lib/x86_64-linux-gnu/ld-2.26.so ..
--56912--   .. CRC mismatch (computed 89c8df08 wanted 47b839f9)
--56912--   Considering /usr/lib/debug/lib/x86_64-linux-gnu/ld-2.26.so ..
--56912--   .. CRC is valid
--56912-- Reading syms from /usr/lib/valgrind/memcheck-amd64-linux
--56912--   Considering /usr/lib/valgrind/memcheck-amd64-linux ..
--56912--   .. CRC mismatch (computed 9fa343a0 wanted dc854ea8)
--56912--    object doesn't have a symbol table
--56912--    object doesn't have a dynamic symbol table
--56912-- Scheduler: using generic scheduler lock implementation.
--56912-- Reading suppressions file: /usr/lib/valgrind/default.supp
==56912== embedded gdbserver: reading from /tmp/vgdb-pipe-from-vgdb-to-56912-by-charlie-on-???
==56912== embedded gdbserver: writing to   /tmp/vgdb-pipe-to-vgdb-from-56912-by-charlie-on-???
==56912== embedded gdbserver: shared mem   /tmp/vgdb-pipe-shared-mem-vgdb-56912-by-charlie-on-???
==56912==
==56912== TO CONTROL THIS PROCESS USING vgdb (which you probably
==56912== don't want to do, unless you know exactly what you're doing,
==56912== or are doing some strange experiment):
==56912==   /usr/lib/valgrind/../../bin/vgdb --pid=56912 ...command...
==56912==
==56912== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==56912==   /path/to/gdb ./ValgrindExamples
==56912== and then give GDB the following command
==56912==   target remote | /usr/lib/valgrind/../../bin/vgdb --pid=56912
==56912== --pid is optional if only one valgrind process is running
==56912==
--56912-- REDIR: 0x401f860 (ld-linux-x86-64.so.2:strlen) redirected to 0x58060901 (???)
--56912-- REDIR: 0x401f640 (ld-linux-x86-64.so.2:index) redirected to 0x5806091b (???)
--56912-- Reading syms from /usr/lib/valgrind/vgpreload_core-amd64-linux.so
--56912--   Considering /usr/lib/valgrind/vgpreload_core-amd64-linux.so ..
--56912--   .. CRC mismatch (computed f3fb86a7 wanted 0b99f9ab)
--56912--    object doesn't have a symbol table
--56912-- Reading syms from /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so
--56912--   Considering /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so ..
--56912--   .. CRC mismatch (computed 5ffa922b wanted 4228a583)
--56912--    object doesn't have a symbol table
==56912== WARNING: new redirection conflicts with existing -- ignoring it
--56912--     old: 0x0401f860 (strlen              ) R-> (0000.0) 0x58060901 ???
--56912--     new: 0x0401f860 (strlen              ) R-> (2007.0) 0x04c32db0 strlen
--56912-- REDIR: 0x401d8d0 (ld-linux-x86-64.so.2:strcmp) redirected to 0x4c33ee0 (strcmp)
--56912-- REDIR: 0x401fda0 (ld-linux-x86-64.so.2:mempcpy) redirected to 0x4c374f0 (mempcpy)
--56912-- Reading syms from /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.24
--56912--    object doesn't have a symbol table
--56912-- Reading syms from /lib/x86_64-linux-gnu/libm-2.26.so
--56912--   Considering /lib/x86_64-linux-gnu/libm-2.26.so ..
--56912--   .. CRC mismatch (computed b616e9a5 wanted 56d31e5b)
--56912--   Considering /usr/lib/debug/lib/x86_64-linux-gnu/libm-2.26.so ..
--56912--   ..  CRC is valid
--56912-- Reading syms from /lib/x86_64-linux-gnu/libgcc_s.so.1
--56912--    object doesn't have a symbol table
--56912-- Reading syms from /lib/x86_64-linux-gnu/libc-2.26.so
--56912--   Considering /lib/x86_64-linux-gnu/libc-2.26.so ..
--56912--   .. CRC mismatch (computed b6c34c34 wanted f79829d1)
--56912--   Considering /usr/lib/debug/lib/x86_64-linux-gnu/libc-2.26.so ..
--56912--   ..  CRC is valid
--56912-- REDIR: 0x57c3f50 (libc.so.6:memmove) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57c3010 (libc.so.6:strncpy) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57c4230 (libc.so.6:strcasecmp) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57c2a60 (libc.so.6:strcat) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57c3040 (libc.so.6:rindex) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57c5bb0 (libc.so.6:rawmemchr) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57c40c0 (libc.so.6:mempcpy) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57c3ee0 (libc.so.6:bcmp) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57c2fd0 (libc.so.6:strncmp) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57c2ad0 (libc.so.6:strcmp) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57c4020 (libc.so.6:memset) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57e1f10 (libc.so.6:wcschr) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57c2f70 (libc.so.6:strnlen) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57c2b40 (libc.so.6:strcspn) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57c4280 (libc.so.6:strncasecmp) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57c2b10 (libc.so.6:strcpy) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57c43c0 (libc.so.6:memcpy@@GLIBC_2.14) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57c3070 (libc.so.6:strpbrk) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57c2a90 (libc.so.6:index) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57c2f40 (libc.so.6:strlen) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57ce510 (libc.so.6:memrchr) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57c42d0 (libc.so.6:strcasecmp_l) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57c3eb0 (libc.so.6:memchr) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57e2cc0 (libc.so.6:wcslen) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57c3350 (libc.so.6:strspn) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57c4200 (libc.so.6:stpncpy) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57c41d0 (libc.so.6:stpcpy) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57c5be0 (libc.so.6:strchrnul) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x57c4320 (libc.so.6:strncasecmp_l) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--56912-- REDIR: 0x58ad6f0 (libc.so.6:__strrchr_avx2) redirected to 0x4c32730 (rindex)
--56912-- REDIR: 0x57bdeb0 (libc.so.6:malloc) redirected to 0x4c2faa0 (malloc)
--56912-- REDIR: 0x58ad8c0 (libc.so.6:__strlen_avx2) redirected to 0x4c32cf0 (strlen)
--56912-- REDIR: 0x58a9ed0 (libc.so.6:__memcmp_avx2_movbe) redirected to 0x4c35e00 (bcmp)
--56912-- REDIR: 0x58890b0 (libc.so.6:__strcmp_ssse3) redirected to 0x4c33da0 (strcmp)
Hello World!
--56912-- REDIR: 0x4ecc500 (libstdc++.so.6:operator new[](unsigned long)) redirected to 0x4c30830 (operator new[](unsigned long))
--56912-- REDIR: 0x58adde0 (libc.so.6:__mempcpy_avx_unaligned_erms) redirected to 0x4c37130 (mempcpy)
int data for memory at 0x5b210c0of size 20
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
--56912-- REDIR: 0x58ade00 (libc.so.6:__memcpy_avx_unaligned_erms) redirected to 0x4c366e0 (memmove)
int data for memory at 0x5b210c0of size 20
1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
--56912-- REDIR: 0x4eca3b0 (libstdc++.so.6:operator delete[](void*)) redirected to 0x4c316d0 (operator delete[](void*))
--56912-- REDIR: 0x57be3e0 (libc.so.6:free) redirected to 0x4c30cd0 (free)
==56912==
==56912== HEAP SUMMARY:
==56912==     in use at exit: 0 bytes in 0 blocks
==56912==   total heap usage: 3 allocs, 3 frees, 73,808 bytes allocated
==56912==
==56912== All heap blocks were freed -- no leaks are possible
==56912==
==56912== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==56912== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Итак, дополнительный вопрос: что вызывает __memcpy_avx_unaligned_erms, я не вижу этого в сборке. Из-за того, что REDIR выравнивается при вызове memcpy, мне кажется, что Valgrind выяснил что-то, чего я не вижу в сборке: $


Подробнее здесь: https://stackoverflow.com/questions/484 ... ing-memcpy
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»