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.

Reply via email to