https://bugs.kde.org/show_bug.cgi?id=396053
Bug ID: 396053 Summary: Memcheck does not support copy-stack style coroutine Product: valgrind Version: unspecified Platform: RedHat RPMs OS: Linux Status: UNCONFIRMED Severity: normal Priority: NOR Component: memcheck Assignee: jsew...@acm.org Reporter: remus.clearwa...@gmail.com Target Milestone: --- Created attachment 113680 --> https://bugs.kde.org/attachment.cgi?id=113680&action=edit valgrind memcheck test binaries I tried to use valgrind's memcheck on a C copy-stack coroutine program, and got many false positive reports about the invalid write/read on the shared stack when memcpy occurred. Here is the source repository: https://github.com/hnes/libaco/tree/valgrind_memcheck_bug_report_on_copy_stack_coroutine If you choose to clone the repo: $ git clone -b valgrind_memcheck_bug_report_on_copy_stack_coroutine https://github.com/hnes/libaco.git $ cd libaco $ # require gcc >= 5.0 to progress $ bash valgrind_report_make.sh $ # coroutines with standalone stack is fine $ time valgrind --leak-check=full --error-exitcode=2 --tool=memcheck ./val_standalone_stack_co $ # coroutines share same stack (by copy-stack) would get many false positive reports when memcpy occurrs $ time valgrind --leak-check=full --error-exitcode=2 --tool=memcheck ./val_copystack_co Or choose to use the attachment only: $ # coroutines with standalone stack is fine $ time valgrind --leak-check=full --error-exitcode=2 --tool=memcheck ./val_standalone_stack_co $ # coroutines share same stack (by copy-stack) would get many false positive reports when memcpy occurrs $ time valgrind --leak-check=full --error-exitcode=2 --tool=memcheck ./val_copystack_co Output: $time valgrind --leak-check=full --error-exitcode=2 --tool=memcheck ./val_copystack_co ==73028== Memcheck, a memory error detector ==73028== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==73028== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info ==73028== Command: ./val_copystack_co ==73028== co:0x5203260 save_stack:0x5203340 share_stack:0x5604000 yield_ct:0 co:0x52033c0 save_stack:0x52034a0 share_stack:0x5805000 yield_ct:0 co:0x5203520 save_stack:0x5203600 share_stack:0x5805000 yield_ct:0 main_co:0x5203040 co:0x5203260 save_stack:0x5203340 share_stack:0x5604000 yield_ct:1 co:0x52033c0 save_stack:0x5203680 share_stack:0x5805000 yield_ct:1 co:0x5203520 save_stack:0x5203ec0 share_stack:0x5805000 yield_ct:1 main_co:0x5203040 co:0x5203260 save_stack:0x5203340 share_stack:0x5604000 yield_ct:2 co:0x52033c0 save_stack:0x5203680 share_stack:0x5805000 yield_ct:2 co:0x5203520 save_stack:0x5203ec0 share_stack:0x5805000 yield_ct:2 main_co:0x5203040 co:0x5203260 save_stack:0x5203340 share_stack:0x5604000 yield_ct:3 co:0x52033c0 save_stack:0x5203680 share_stack:0x5805000 yield_ct:3 co:0x5203520 save_stack:0x5203ec0 share_stack:0x5805000 yield_ct:3 main_co:0x5203040 co:0x5203260 save_stack:0x5203340 share_stack:0x5604000 yield_ct:4 co:0x52033c0 save_stack:0x5203680 share_stack:0x5805000 yield_ct:4 co:0x5203520 save_stack:0x5203ec0 share_stack:0x5805000 yield_ct:4 main_co:0x5203040 co:0x5203260 save_stack:0x5203340 share_stack:0x5604000 yield_ct:5 co:0x52033c0 save_stack:0x5203680 share_stack:0x5805000 yield_ct:5 co:0x5203520 save_stack:0x5203ec0 share_stack:0x5805000 yield_ct:5 main_co:0x5203040 co:0x5203260 save_stack:0x5203340 share_stack:0x5604000 co_exit() co:0x52033c0 save_stack:0x5203680 share_stack:0x5805000 co_exit() ==73028== Invalid write of size 8 ==73028== at 0x4C2E0C3: memcpy@@GLIBC_2.14 (vg_replace_strmem.c:1022) ==73028== by 0x402EC4: aco_resume (aco.c:440) ==73028== by 0x4037A4: main (val_copystack_co.c:100) ==73028== Address 0x5a04ba0 is in a rw- anonymous segment ==73028== co:0x5203520 save_stack:0x5203ec0 share_stack:0x5805000 co_exit() main_co:0x5203040 copy-stack co:0x5203260: max stack copy size:0 save (from share stack to save stack) counter of the private save stack:0 restore (from save stack to share stack) counter of the private save stack:0 (Since the share stack used by the co has only one user `co`, so there is no need to save/restore the stack every time during resume & yield execution, thus you can call it a co has 'standalone stack' which just is a very special case of copy-stack.) copy-stack co2:0x52033c0: max stack copy size:1096 save (from share stack to save stack) counter of the private save stack:6 restore (from save stack to share stack) counter of the private save stack:6 copy-stack co3:0x5203520: max stack copy size:1096 save (from share stack to save stack) counter of the private save stack:6 restore (from save stack to share stack) counter of the private save stack:6 (The co2 & co3 share the share stack sstk2, thus it is necessary to save/restore the stack every time during resume & yield execution, thus it is a ordinary case of copy-stack.) ==73028== ==73028== HEAP SUMMARY: ==73028== in use at exit: 0 bytes in 0 blocks ==73028== total heap usage: 11 allocs, 11 frees, 5,104 bytes allocated ==73028== ==73028== All heap blocks were freed -- no leaks are possible ==73028== ==73028== For counts of detected and suppressed errors, rerun with: -v ==73028== ERROR SUMMARY: 117 errors from 1 contexts (suppressed: 0 from 0) real 0m0.551s user 0m0.514s sys 0m0.026s -- You are receiving this mail because: You are watching all bug changes.