https://bugs.kde.org/show_bug.cgi?id=450962

            Bug ID: 450962
           Summary: helgrind reports false races for printfs using mempcpy
                    manipulating FILE* state in glibc-2.26+
           Product: valgrind
           Version: unspecified
          Platform: Other
                OS: Linux
            Status: REPORTED
          Severity: normal
          Priority: NOR
         Component: helgrind
          Assignee: jsew...@acm.org
          Reporter: jch...@redhat.com
  Target Milestone: ---

Created attachment 147187
  --> https://bugs.kde.org/attachment.cgi?id=147187&action=edit
valgrind run in RHEL 8.5 with glibc 2.28

Description of the issue:

Helgrind reports again false races for printfs as described in bug 352130. This
happens in newer glibc versions.
More specifically I've reproduced this in RHEL-8.5 with
glibc-2.28-164.el8.x86_64 and valgrind-3.17.0-5.el8.x86_64,
and also in Fedora 34 with glibc-2.33-21.fc34.x86_64 and
valgrind-3.18.1-1.fc34.x86_64.

In RHEL-8.5 (with glibc 2.28) I've built and run the reproducer that Mark wrote
originally in bug 352130,
which produces the output shown in the attachment.

It seems that in newer glibc versions mempcpy is used instead __GI_mempcpy,
making
the suppresion from the original bug obsolete. I tracked down the changes to
__GI_mempcpy to the following glibc's commit:
commit 5c3e322d3be3803636e38bcaf083fb59b3a34f0c
Author: H.J. Lu <hjl.to...@gmail.com>
Date:   Wed Jun 14 12:10:57 2017 -0700

    x86-64: Implement memmove family IFUNC selectors in C

    Implement memmove family IFUNC selectors in C.

    All internal calls within libc.so can use IFUNC on x86-64 since unlike
    x86, x86-64 supports PC-relative addressing to access the GOT entry so
    that it can call via PLT without using an extra register.  For libc.a,
    we can't use IFUNC for functions which are called before IFUNC has been
    initialized.  Use IFUNC internally reduces the icache footprint since
    libc.so and other codes in the process use the same implementations.
    This patch uses IFUNC for memmove family functions within libc.

>From there, in glibc repo:
$ git branch --contains 5c3e322d3be3803636e38bcaf083fb59b3a34f0c
  master
  release/2.26/master
  release/2.27/master
  release/2.28/master
  release/2.29/master
  release/2.30/master
  release/2.31/master
  release/2.32/master
  release/2.33/master
  release/2.34/master

To check my assumption, I grabbed glibc 2.25 and 2.26 sources, and
built/installed
into /opt/glibc-2.2[5|6], built the reproducer and patched the elf to use my
custom
built glibc:
[root@localhost ~]# gcc -g t.c -o t -lpthread
[root@localhost ~]# cp t t-glibc2.25
[root@localhost ~]# cp t t-glibc2.26
[root@localhost ~]# patchelf --set-interpreter
/opt/glibc-2.25/lib/ld-linux-x86-64.so.2 --set-rpath /opt/glibc-2.25/lib
t-glibc2.25
[root@localhost ~]# patchelf --set-interpreter
/opt/glibc-2.26/lib/ld-linux-x86-64.so.2 --set-rpath /opt/glibc-2.26/lib
t-glibc2.26
[root@localhost ~]# ldd t-glibc2.2{5,6}
t-glibc2.25:
        linux-vdso.so.1 (0x00007ffce19ea000)
        libpthread.so.0 => /opt/glibc-2.25/lib/libpthread.so.0
(0x00007fe09abc3000)
        libc.so.6 => /opt/glibc-2.25/lib/libc.so.6 (0x00007fe09a824000)
        /opt/glibc-2.25/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2
(0x00007fe09ade1000)
t-glibc2.26:
        linux-vdso.so.1 (0x00007ffe3a5c3000)
        libpthread.so.0 => /opt/glibc-2.26/lib/libpthread.so.0
(0x00007f7fa3f38000)
        libc.so.6 => /opt/glibc-2.26/lib/libc.so.6 (0x00007f7fa3b86000)
        /opt/glibc-2.26/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2
(0x00007f7fa4156000)
[root@localhost ~]# valgrind --tool=helgrind ./t-glibc2.25 > /dev/null
==115881== Helgrind, a thread error detector
==115881== Copyright (C) 2007-2017, and GNU GPL'd, by OpenWorks LLP et al.
==115881== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==115881== Command: ./t-glibc2.25
==115881== 
==115881== 
==115881== Use --history-level=approx or =none to gain increased speed, at
==115881== the cost of reduced accuracy of conflicting-access information
==115881== For lists of detected and suppressed errors, rerun with: -s
==115881== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2898 from 51)
[root@localhost ~]# valgrind --tool=helgrind ./t-glibc2.25 > /dev/null          
==115881== Helgrind, a thread error detector                                    
==115881== Copyright (C) 2007-2017, and GNU GPL'd, by OpenWorks LLP et al.      
==115881== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==115881== Command: ./t-glibc2.25               
==115881==                                                                      
==115881==                                                                      
==115881== Use --history-level=approx or =none to gain increased speed, at      
==115881== the cost of reduced accuracy of conflicting-access information
==115881== For lists of detected and suppressed errors, rerun with: -s
==115881== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2898 from 51)
[root@localhost ~]# valgrind --tool=helgrind ./t-glibc2.26 > /dev/null         
                                                                               
                                                                     [59/20969]
==115884== Helgrind, a thread error detector                                    
==115884== Copyright (C) 2007-2017, and GNU GPL'd, by OpenWorks LLP et al.      
==115884== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info   
==115884== Command: ./t-glibc2.26                                               
==115884==                                                                      
==115884== ---Thread-Announcement------------------------------------------     
==115884==                                                                      
==115884== Thread #3 was created                                                
==115884==    at 0x515522E: clone (clone.S:71)                                  
==115884==    by 0x4E4B1FE: create_thread (createthread.c:100)                  
==115884==    by 0x4E4CC04: pthread_create@@GLIBC_2.2.5 (pthread_create.c:822)  
==115884==    by 0x4C38626: pthread_create_WRK (hg_intercepts.c:436)            
==115884==    by 0x4C39720: pthread_create@* (hg_intercepts.c:469)              
==115884==    by 0x40071A: main (t.c:30)                                        
==115884==                                                                      
==115884== ---Thread-Announcement------------------------------------------
==115884== 
==115884== Thread #2 was created
==115884==    at 0x515522E: clone (clone.S:71)
==115884==    by 0x4E4B1FE: create_thread (createthread.c:100)
==115884==    by 0x4E4CC04: pthread_create@@GLIBC_2.2.5 (pthread_create.c:822)
==115884==    by 0x4C38626: pthread_create_WRK (hg_intercepts.c:436)
==115884==    by 0x4C39720: pthread_create@* (hg_intercepts.c:469)
==115884==    by 0x400701: main (t.c:29)
==115884== 
==115884== ----------------------------------------------------------------
==115884== 
==115884== Possible data race during write of size 1 at 0x5C167DB by thread #3
==115884== Locks held: none
==115884==    at 0x4C3DFEA: mempcpy (vg_replace_strmem.c:1562)
==115884==    by 0x50DB114: _IO_new_file_xsputn (fileops.c:1311)
==115884==    by 0x50DB114: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1271)
==115884==    by 0x50B00A3: vfprintf (vfprintf.c:1328)
==115884==    by 0x50B8958: printf (printf.c:33)
==115884==    by 0x400694: thread3 (t.c:11)
==115884==    by 0x4C3881E: mythread_wrapper (hg_intercepts.c:398)
==115884==    by 0x4E4C45D: start_thread (pthread_create.c:465)
==115884==    by 0x515523E: clone (clone.S:95)
==115884==  Address 0x5c167db is 1,611 bytes inside a block of size 4,096
alloc'd
==115884==    at 0x4C2FEA5: malloc (vg_replace_malloc.c:380)
==115884==    by 0x50CF5A8: _IO_file_doallocate (filedoalloc.c:101)
==115884==    by 0x50DCDDF: _IO_doallocbuf (genops.c:398)
==115884==    by 0x50DC087: _IO_file_overflow@@GLIBC_2.2.5 (fileops.c:812)
==115884==    by 0x50DB1BE: _IO_new_file_xsputn (fileops.c:1323)
==115884==    by 0x50DB1BE: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1271)
==115884==    by 0x50B00A3: vfprintf (vfprintf.c:1328)
==115884==    by 0x50B8958: printf (printf.c:33)
==115884==    by 0x4006D0: thread2 (t.c:22)
==115884==    by 0x4C3881E: mythread_wrapper (hg_intercepts.c:398)
==115884==    by 0x4E4C45D: start_thread (pthread_create.c:465)
==115884==    by 0x515523E: clone (clone.S:95)
==115884==  Block was alloc'd by thread #2
==115884== 
==115884== ----------------------------------------------------------------
==115884== 
==115884== Possible data race during write of size 1 at 0x5C167DC by thread #3
==115884== Locks held: none
==115884==    at 0x4C3E007: mempcpy (vg_replace_strmem.c:1562)
==115884==    by 0x50DB114: _IO_new_file_xsputn (fileops.c:1311)
==115884==    by 0x50DB114: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1271)
==115884==    by 0x50B1752: vfprintf (vfprintf.c:1642)
==115884==    by 0x50B8958: printf (printf.c:33)
==115884==    by 0x400694: thread3 (t.c:11)
==115884==    by 0x4C3881E: mythread_wrapper (hg_intercepts.c:398)
==115884==    by 0x4E4C45D: start_thread (pthread_create.c:465)
==115884==    by 0x515523E: clone (clone.S:95)
==115884==  Address 0x5c167dc is 1,612 bytes inside a block of size 4,096
alloc'd
==115884==    at 0x4C2FEA5: malloc (vg_replace_malloc.c:380)
==115884==    by 0x50CF5A8: _IO_file_doallocate (filedoalloc.c:101)
==115884==    by 0x50DCDDF: _IO_doallocbuf (genops.c:398)
==115884==    by 0x50DC087: _IO_file_overflow@@GLIBC_2.2.5 (fileops.c:812)
==115884==    by 0x50DB1BE: _IO_new_file_xsputn (fileops.c:1323)
==115884==    by 0x50DB1BE: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1271)
==115884==    by 0x50B00A3: vfprintf (vfprintf.c:1328)
==115884==    by 0x50B8958: printf (printf.c:33)
==115884==    by 0x4006D0: thread2 (t.c:22)
==115884==    by 0x4C3881E: mythread_wrapper (hg_intercepts.c:398)
==115884==    by 0x4E4C45D: start_thread (pthread_create.c:465)
==115884==    by 0x515523E: clone (clone.S:95)
==115884==  Block was alloc'd by thread #2
==115884== 
==115884== ----------------------------------------------------------------
==115884== 
==115884== Possible data race during write of size 1 at 0x5C167DD by thread #3
==115884== Locks held: none
==115884==    at 0x4C3DFEA: mempcpy (vg_replace_strmem.c:1562)
==115884==    by 0x50DB114: _IO_new_file_xsputn (fileops.c:1311)
==115884==    by 0x50DB114: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1271)
==115884==    by 0x50B06F4: vfprintf (vfprintf.c:1674)
==115884==    by 0x50B8958: printf (printf.c:33)
==115884==    by 0x400694: thread3 (t.c:11)
==115884==    by 0x4C3881E: mythread_wrapper (hg_intercepts.c:398)
==115884==    by 0x4E4C45D: start_thread (pthread_create.c:465)
==115884==    by 0x515523E: clone (clone.S:95)
==115884==  Address 0x5c167dd is 1,613 bytes inside a block of size 4,096
alloc'd
==115884==    at 0x4C2FEA5: malloc (vg_replace_malloc.c:380)
==115884==    by 0x50CF5A8: _IO_file_doallocate (filedoalloc.c:101)
==115884==    by 0x50DCDDF: _IO_doallocbuf (genops.c:398)
==115884==    by 0x50DC087: _IO_file_overflow@@GLIBC_2.2.5 (fileops.c:812)
==115884==    by 0x50DB1BE: _IO_new_file_xsputn (fileops.c:1323)
==115884==    by 0x50DB1BE: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1271)
==115884==    by 0x50B00A3: vfprintf (vfprintf.c:1328)
==115884==    by 0x50B8958: printf (printf.c:33)
==115884==    by 0x4006D0: thread2 (t.c:22)
==115884==    by 0x4C3881E: mythread_wrapper (hg_intercepts.c:398)
==115884==    by 0x4E4C45D: start_thread (pthread_create.c:465)
==115884==    by 0x515523E: clone (clone.S:95)
==115884==  Block was alloc'd by thread #2
==115884== 
==115884== 
==115884== Use --history-level=approx or =none to gain increased speed, at
==115884== the cost of reduced accuracy of conflicting-access information
==115884== For lists of detected and suppressed errors, rerun with: -s
==115884== ERROR SUMMARY: 1410 errors from 3 contexts (suppressed: 2768 from
42)

I did a similar check using a RHEL-7 distro, where this false races are not
reported with
the available packages valgrind-3.15.0-11.el7.x86_64 and
glibc-2.17-325.el7_9.x86_64.
After building glibc 2.25 and 2.26 and patching the elf, helgrind didn't report
races
with the glibc2.25 executable and did report them with the glibc 2.26 one.

Reproducible:

Always if glibc used is newer/equal to 2.26, in all valgrind versions.

Additional information:

Tested with x86_64, s390x, aarch64 and ppc64le. glibc did not change anything
related
to mempcpy in ppc64le so the old suppression still applies there.

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to