Bug 374963 - increase valgrind's load address to prevent mmap failure
Summary: increase valgrind's load address to prevent mmap failure
Status: RESOLVED FIXED
Alias: None
Product: valgrind
Classification: Developer tools
Component: general (show other bugs)
Version: 3.12.0
Platform: unspecified Linux
: NOR wishlist
Target Milestone: ---
Assignee: Ivo Raisr
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-01-12 15:45 UTC by roland_wirth
Modified: 2020-01-23 13:09 UTC (History)
3 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
Patch to make valgrind work with -mcmodel=large (2.42 KB, patch)
2017-01-12 15:45 UTC, roland_wirth
Details
Patch to increase tool load addresses via configure option (6.84 KB, patch)
2017-03-31 18:09 UTC, roland_wirth
Details
patch to increase load address for almost all platforms to 0x58000000 (14.10 KB, patch)
2017-05-15 07:52 UTC, Ivo Raisr
Details
patch to increase load address for almost all platforms to 0x58000000 (v2) (14.50 KB, patch)
2017-05-15 14:33 UTC, Ivo Raisr
Details

Note You need to log in before you can comment on or make changes to this bug.
Description roland_wirth 2017-01-12 15:45:06 UTC
Created attachment 103372 [details]
Patch to make valgrind work with -mcmodel=large

Valgrind startup fails when the executable contains large text, data or bss segments (see also #138424):

    valgrind: mmap(0x602000, 933228544) failed in UME with error 22 (Invalid argument).
    valgrind: this can be caused by executables with very large text, data or bss segments.

Reason for this is valgrind's load address, which is set to 0x38000000 (on amd64). Once the combined size of the text, data and bss segments is larger than approx. 892 MiB, the executable image overlaps with valgrind's image and the mmap call allocating space for the segments fails because part of the requested address space is already in use.

The problem cannot be solved by mapping the segments in another location because the location of the segments is hard-coded into the executable during linking. So the only way to mitigate this is to load valgrind at a higher memory address.

Attached is a proof-of-principle patch for amd64-linux that demonstrates that support for high load addresses can be implemented with only a few changes to the code. The patch sets the load address to 0x80000000 (2GiB). Currently, there are two caveats:

 1. valgrind has to be configured with CFLAGS='-mcmodel=large' CXXFLAGS='-mcmodel=large'
 2. the call to __gnu_cxx::__freeres() in vg_preloaded.c for some reason jumps to a non-code location,
    which crashes C++ programs during exit (it seems to miscalculate the argument to a callq instruction).
Comment 1 roland_wirth 2017-03-31 18:09:24 UTC
Created attachment 104834 [details]
Patch to increase tool load addresses via configure option

I've had some time to clean up the patch and work around the __gnu_cxx::__freeres problem. The patch introduces a new configure flag, --enable-high-load, that increases the base address and switches the memory model to large when compiling the tools, but not the preloaded so's (this gets rid of the freeres problem). Through a few additional tweaks, the load address can now be set to much higher values. It is currently set to 1TiB, which should be enough for virtually any executable linked with the default base address.

Apart from the modifications to configure.ac and Makefile.all.am, the patch changes some assembly instructions so they work when the symbols inserted by the linker have values not representable as signed 32bit ints. Also, the eh_frame descriptors in coregrind/m_trampoline.S have changed from an absolute to a PC-relative addressing scheme.

The diff is against Valgrind 3.12.0. Regtest completes with the same failures as the unmodified version.
Comment 2 Ivo Raisr 2017-05-05 16:10:46 UTC
Thank you for the patch, it looks plausible.
We also need to document new functionality and command line option.
Please can you update the patch or attach a new one?
Comment 3 Julian Seward 2017-05-11 14:19:07 UTC
An alternative proposal is to change the load address to
from 3800'0000 to 5800'0000 on all targets.  This gives
an extra 512MB for the executable without getting us into
the complexities of linkage models, etc.
Comment 4 Ivo Raisr 2017-05-15 07:52:26 UTC
Created attachment 105544 [details]
patch to increase load address for almost all platforms to 0x58000000
Comment 5 Ivo Raisr 2017-05-15 07:54:57 UTC
Please test the attached patch [1] which increases the load address for almost all platforms to 0x58000000 (from 0x38000000). This gives another 512 MB for executable without changing linkage model (which is different on every platform).

I've tested on x86/Linux, amd64/Linux, x86/Solaris, amd64/Solaris.
32-bit only, 64-bit only, mix and outer/inner setup.


[1] https://bugs.kde.org/attachment.cgi?id=105544
Comment 6 Ivo Raisr 2017-05-15 14:33:06 UTC
Created attachment 105560 [details]
patch to increase load address for almost all platforms to 0x58000000 (v2)

The previous patch forgot to change suggested client stack end on Solaris.
This is now rectified.
Comment 7 Ivo Raisr 2017-05-16 08:23:11 UTC
Committed in Valgrind SVN as r16383.
Comment 8 Rhys Kidd 2017-05-23 03:26:42 UTC
No regressions noted on macOS.