Bug 384729 - __libc_freeres inhibits cross-platform valgrind
Summary: __libc_freeres inhibits cross-platform valgrind
Status: RESOLVED FIXED
Alias: None
Product: valgrind
Classification: Developer tools
Component: memcheck (show other bugs)
Version: 3.13.0
Platform: Fedora RPMs Linux
: NOR normal
Target Milestone: ---
Assignee: Julian Seward
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-09-15 05:11 UTC by John Reiser
Modified: 2021-02-20 13:09 UTC (History)
3 users (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments
Patch as per discussion (729 bytes, patch)
2020-11-07 15:52 UTC, Paul Floyd
Details

Note You need to log in before you can comment on or make changes to this bug.
Description John Reiser 2017-09-15 05:11:03 UTC
vgpreload_core-arm-linux.so from valgrind-3.13.0-6.fc27.armv7hl demands that the symbol __libc_freeres exist [typically found in GNU libc.so.6], which prevents that particular valgrind from checking apps whose libraries do not have such a symbol, such as the libraries used by Android.  Many Android apps run just fine on Linux (using the Android runtime linker, libc, libm, libdl, etc.), and valgrind should be able to check them.

The complaint from one Android app is:
libc: CANNOT LINK EXECUTABLE "./my_app": cannot locate symbol "__libc_freeres" referenced by "/usr/lib/valgrind/vgpreload_core-arm-inux.so"...

So, do not reference __libc_freeres directly.  Make it a Weak reference (check the pointer value; if 0 then do not use it), or do an explicit lookup equivalent to dlsym(handle, "__libc_freeres").

===== readelf --relocs /usr/lib/valgrind/vgpreload_core-arm-linux.so
Relocation section '.rel.plt' at offset 0x3d0 contains 4 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
0001100c  00000316 R_ARM_JUMP_SLOT   00000000   __cxa_finalize
00011010  00000416 R_ARM_JUMP_SLOT   00000000   _ZN9__gnu_cxx9__freere
00011014  00000616 R_ARM_JUMP_SLOT   00000000   __libc_freeres
00011018  00000816 R_ARM_JUMP_SLOT   00000000   __gmon_start__
=====
Comment 1 John Reiser 2017-09-15 05:22:55 UTC
If __libc_freeres is used by some library function that is invoked by vgpreload_core-arm-linux.so then vgpreload should implement such a function itself, with an implementation that does the explicit lookup and forwarding if found.
Comment 2 Ivo Raisr 2017-09-15 09:26:25 UTC
Calling optional __gnu_cxx::__freeres() already leverages weak reference mechanism. So __libc__freeres() could use the same mechanism.

After you make __libc_freeres() optional, please delete references to it in README_DEVELOPERS as it would be no longer needed.
Comment 3 John Reiser 2019-05-12 02:30:24 UTC
I hit this again today using valgrind-3.15.0 when the default libc on the target platform is glibc-2.29-12.fc30.aarch64 but the actual libc in the target application is from Android 28.

__libc_freeres is not defined for all target app environments; therefore __libc_freeres MUST be a WEAK symbol!
Comment 4 Mark Wielaard 2019-05-12 08:18:21 UTC
See comment #2. This could be done the same way as is done for __gnu_cxx::__freeres().
Comment 5 Paul Floyd 2020-10-29 08:33:01 UTC
This looks fairly straightforward. Just change

#  if defined(VGO_linux)
   /* __libc_freeres() not yet available on Solaris. */
   extern void __libc_freeres(void);
   if ((to_run & VG_RUN__LIBC_FREERES) != 0) {
      __libc_freeres();
   }
#  endif

to

   extern void __libc_freeres(void) __attribute__((weak));
   if (((to_run & VG_RUN__LIBC_FREERES) != 0)) &&
       (__libc_freeres != NULL)) {
      __libc_freeres();
   }

in vg_preloaded.c
Comment 6 Paul Floyd 2020-11-07 15:52:20 UTC
Created attachment 133107 [details]
Patch as per discussion
Comment 7 Mark Wielaard 2020-11-07 23:14:11 UTC
(In reply to Paul Floyd from comment #6)
> Created attachment 133107 [details]
> Patch as per discussion

Looks correct to me.
But I don't have any non-glibc system around to test it.
Comment 8 Paul Floyd 2020-11-08 06:14:02 UTC
(In reply to Mark Wielaard from comment #7)

> Looks correct to me.
> But I don't have any non-glibc system around to test it.

Regtests are OK on Solaris and FreeBSD. However I don't have any non-libc Linux systems to test.

John, could you test this patch?
Comment 9 John Reiser 2020-11-09 14:00:22 UTC
Yes, the patch works, just like the handling of __gnu_cxx::__freeres().  Tested on armv7hl.
Comment 10 Mark Wielaard 2021-02-20 13:09:10 UTC
commit 35c9c33897ef89b08e1518ed16244e70bc6996da
Author: Paul Floyd <pjfloyd@wanadoo.fr>
Date:   Mon Nov 9 16:31:40 2020 +0100

    Bug 384729 - __libc_freeres inhibits cross-platform valgrind