711 Commits

Author SHA1 Message Date
Christopher Ferris
ef962752d9
[scudo] Allow the quarantine code to be compiled out (#151064)
Add a new configuration option QuarantineDisabled that allows all of the
quarantine code to be compiled out.

Add new tests that verify that the code is removed properly.

On Android, this saves ~4000 bytes for 32 bit and ~6000 bytes for 64
bit.

On Android, I used some microbenchmarks that do malloc/free in a loop
and for allocations in the primary, the performance is about the same
for both 32 bit and 64 bit. For secondary allocations, I saw ~8% speed
up on 32 bit and ~3% on 64 bit speed up which feels like it could just
be code size improvements.
2025-07-30 19:41:14 -07:00
Christopher Ferris
30532c13d2
[scudo] Fix secondary caching for mte (#150156)
The current code always unmaps a secondary allocation when MTE is
enabled. Fix this to match the comment, namely only unmap if MTE was
enabled and is no longer enabled after acquiring the lock.

In addition, allow quaratine to work in the secondary even if MTE is not
enabled.
2025-07-28 12:56:16 -07:00
Fabio D'Urso
fcdcc4ea7a
[scudo] Make Ptr volatile so that the malloc and free calls are not optimized out (#149944)
This fixes the test failure seen in the discussion about
https://github.com/llvm/llvm-project/pull/148066.
2025-07-22 03:31:35 +02:00
Christopher Ferris
34b3ea367c
[scudo] Make release to OS test more specific. (#147852)
The original version of ResidentMemorySize could be a little flaky.
Replace the test with a version that verifies exactly how much of the
map is resident.
2025-07-16 19:25:57 -07:00
Christopher Ferris
309bb1ed68
[scudo] Fix c wrappers double free test. (#148066)
The previous test simply tried to double free the pointer in the
EXPECT_DEATH macro. Unfortunately, the gtest infrastructure can allocate
a pointer that happens to be the previously freed pointer. Thus the free
doesn't fail since the spawned process does not attempt to free all of
the pointers allocated in the original test.

NOTE: Scudo should be checked to make sure that the TSD is not always
returning pointers in the same order they are freed. Although this
appears to be a problem with a program that only does a small number of
allocations.
2025-07-14 11:15:10 -07:00
ChiaHungDuan
4ea0ef2e94
[scudo] Move out the definitions of member functions in primary allocators (#147601)
This greatly improves the readability so that we are able to tell the
design by the concise class definition.
2025-07-09 13:42:02 -07:00
ChiaHungDuan
8b65c9d1ed
[scudo] Make block storage in TransferBatch trailing objects (#144204)
This allows us to change the number of blocks stored according to the
size of BatchClass.

Also change the name `TransferBatch` to `Batch` given that it's never
the unit of transferring blocks.
2025-07-08 11:07:05 -07:00
Christopher Ferris
a2cee05449
[scudo] Make report pointers const. (#144624)
Mark as many of the reportXX functions that take pointers const. This
avoid the need to use const_cast when calling these functions on an
already const pointer.

Fix reportHeaderCorruption calls where an argument was passed into an
append call that didn't use them.
2025-06-18 09:12:53 -07:00
Christopher Ferris
1756fcb8b0
[scudo] Add primary option to enable/disable cache blocks. (#129794)
When configured this way, no primary blocks will be cached except the
batch class. Nothing else changes, no change in the page releasing
strategy.
2025-04-17 14:23:42 -07:00
Christopher Ferris
134cb8877e
[scudo] Use a tryLock in secondary release to OS (#132827)
In the caching part of the secondary path, when about to try to release
memory to the OS, we always wait while acquiring the lock. However, if
multiple threads are attempting this at the same time, all other threads
will likely do nothing when the release call is made. Change the
algorithm to skip the release if there is another release in process.

Also, pull the lock outside the releaseOlderThan function. This is so
that in the store path, we use the tryLock and skip if another thread is
releasing. But in the path where a forced release call is being made,
that call will wait for release to complete which guarantees that all
entries are released when requested.
2025-03-25 16:32:16 -07:00
Christopher Ferris
9db0f91ceb
[scudo] Modify header corrupption error message (#126812)
Update the error message to be explicit that this is likely due to
memory corruption.

In addition, check if the chunk header is all zero, which could mean
corruption or an attempt to free a pointer after the memory has been
released to the kernel. This case results in a slightly different error
message to also indicate this could still be a double free.
2025-02-11 17:41:15 -08:00
Christopher Ferris
3d35246c50
[scudo] Make guard pages optional in the secondary (#125960)
Add an optional flag for the secondary allocator called
`EnableGuardPages` to enable/disable the use of guard pages. By default,
this option is enabled.
2025-02-06 17:03:30 -08:00
Christopher Ferris
84fbed86ff
[scudo] Refactor the secondary test (#125595)
Remove all redundant code and create a couple of structs to handle
automatic init and destruction. This replaces the test fixtures in
prepartion for passing in multiple configs for some of these tests. This
is necessary because not all of the gtest features are supported here,
and there is no easy way to create a test fixture with a template.
2025-02-04 08:46:26 -08:00
Christopher Ferris
c8f4189eeb
[scudo] Clean up secondary tests. (#124999)
Change names to all begin with ScudoSecondary and change tests names
appropriately.

Move the cache option test to the cache test fixture.

Force the allocator test to use the no cached config so that all of
the allocations always fully exercise the allocator function and
don't skip this by using a previously cached element.
2025-01-30 10:15:40 -08:00
ChiaHungDuan
a8d2aeec87
[scudo] Fix the format of getStats() (#121608)
This is a quick fix for b71c44b9be17dc6295eb733d685b38e797f3c846

"last released" was removed by accident in primary64.h and the update of
"NumReleasesAttempted" was missing.
2025-01-13 14:17:48 -08:00
ChiaHungDuan
b71c44b9be
[scudo] Add the record of number of attempted page release (#120497)
This also removes the `RangesReleased` which doesn't give much insight
to whether we should adjust the heuristic of doing page release.
2024-12-19 10:47:44 -08:00
ChiaHungDuan
5a930339a5
[scudo] Minor refactor on element address validation (NFC) (#119436) 2024-12-10 13:58:02 -08:00
ChiaHungDuan
aac000a01b
[scudo] Clean the TODO in list.h (#119323)
* Finished the type and size verification
* Remove the TODO for checking if array size can be fit into LinkTy
because if there's a truncation happens, other DCHECK like offset
checking will catch the failure. In addition, it's supposed to be a rare
case.
2024-12-09 20:39:18 -08:00
ChiaHungDuan
2c0b8b10dd
[scudo] Group type traits into a single header (NFC) (#118888) 2024-12-09 20:34:16 -08:00
ChiaHungDuan
9c5217c4ed
[scudo] Use internal list to manage the LRU cache (#117946) 2024-12-04 11:31:41 -08:00
Christopher Ferris
ed0fd13783
[scudo] Double frees result in chunk state error (#110345)
Fixes bug where a device that supports tagged pointers doesn't use
the tagged pointer when computing the checksum.

Add tests to verify that double frees result in chunk state error
not corrupted header errors.
2024-10-15 17:14:50 -07:00
ChiaHungDuan
cb3e7b39a5
Reapply "[scudo] Apply the min release threshold to the group" (#112252) (#112266)
This reverts commit 037938d637b830332e50232d7b90b5faad039c11.

Fixed the iterator to avoid infinite loop
2024-10-14 21:30:44 -07:00
ChiaHungDuan
037938d637
Revert "[scudo] Apply the min release threshold to the group" (#112252)
Reverts llvm/llvm-project#112014

The change didn't update the iterator
2024-10-14 12:53:07 -07:00
ChiaHungDuan
53c9553562
[scudo] Apply the min release threshold to the group (#112014)
For the block smaller than a page size, one block is unlikely to
introduce more unused pages (at most 2 if it acrosses the page boundary
and both touched pages are unused). So it's better to apply the
threshold to reduce the time of scanning groups that can't release any
new pages.
2024-10-14 10:46:12 -07:00
Evgenii Stepanov
00989f4ab1
[scudo] Fix isOwned on MTE devices. (#111060)
If called on address that is actually not owned, the tags could not
match. Disable tag checks in isOwned().
2024-10-07 14:13:17 -07:00
ChiaHungDuan
b977ec6c1f
[scudo] Fix the loading of a signed value to an unsigned storage (#111039) 2024-10-03 14:15:46 -07:00
ChiaHungDuan
36dff0d011
[scudo] Reduce unsuccessful attempts of page releasing (#110583)
We introduce a new strategy to track how many bytes are not released
because of the contraint of release interval. This will change the
`TryReleaseThreshold` adaptively so that we avoid releasing the same
pages multiple times (and wasting time on the case of no pages to
release).

On Android, the number of release attempts decreases 33% (572 to 382)
and the worst case drops from 251 to 33. At the same time, it maintains
almost the same RSS usage (with some improvements as well).

Note that in this CL, this is only applied to non small blocks. We will
bring the strategy to all the size classes later.
2024-10-02 13:34:46 -07:00
NAKAMURA Takumi
e656b1a690 Revert "[scudo] Fix isOwned on MTE devices. (#110717)"
This caused failures in aarch64 builders.

This reverts commit 98c9523113b550eaca3728bf30cbc346af5eff07.
(llvmorg-20-init-7659-g98c9523113b5)
2024-10-02 20:16:36 +09:00
Evgenii Stepanov
98c9523113
[scudo] Fix isOwned on MTE devices. (#110717)
If called on an address that is actually not owned, the header tag might not
match. This would cause an MTE fault in Chunk::isValid.

Disable tag checks in isOwned().
2024-10-01 12:48:56 -07:00
Evgenii Stepanov
a200201928
[scudo] Fix wording for unsupported test reason. (#110716) 2024-10-01 11:26:01 -07:00
ChiaHungDuan
0347c11226
[scudo] Remove unused field in BatchGroup (#109322)
Also fix the logic while determining the size of BatchClass and update
some legacy comments.
2024-09-19 13:58:47 -07:00
Thurston Dang
ddd1a02048 Revert "[scudo] Update secondary cache time-based release logic (#107507)"
This reverts commit e5271fef8fd8931370f04702ba2f9e8b2ab0e523.

Reason: buildbot breakage: https://lab.llvm.org/buildbot/#/builders/139/builds/3806
2024-09-16 20:43:55 +00:00
Joshua Baehring
e5271fef8f
[scudo] Update secondary cache time-based release logic (#107507)
Secondary cache entries are now released to the OS from least recent to
most recent entries. This helps to avoid unnecessary scans of the cache
since entries ready to be released (specifically, entries that are
considered old relative to the configurable release interval) will
always be at the tail of the list of committed entries by the LRU
ordering. For this same reason, the `OldestTime` variable is no longer
needed to indicate when releases are necessary so it has been removed.
2024-09-16 11:33:03 -07:00
ChiaHungDuan
63d8bd2727
[scudo] Add thread-safety annotation on getMemoryGroupFragmentationIn… (#108277)
Add thread-safety annotation on getMemoryGroupFragmentationInfoInRegion
2024-09-11 14:22:47 -07:00
ChiaHungDuan
323911de27
Reapply "[scudo] Fix the logic of MaxAllowedFragmentedPages" (#108130) (#108134)
This reverts commit 76151c449080b7239c8b442291514a4300d51cba.

Also changed to check MaxAllowedFragmentedPages.
2024-09-10 22:24:06 -07:00
ChiaHungDuan
76151c4490
Revert "[scudo] Fix the logic of MaxAllowedFragmentedPages" (#108130)
Reverts llvm/llvm-project#107927

We are supposed to check the MaxAllowedFragmentedPages instead.
2024-09-10 18:56:49 -07:00
ChiaHungDuan
6e854a6a01
[scudo] Fix the logic of MaxAllowedFragmentedPages (#107927)
MTE doesn't support MaxReleasedCachePages which may break the assumption
that only the first 4 pages will have memory tagged.
2024-09-10 17:46:02 -07:00
ChiaHungDuan
d9a9960203
[scudo] Add fragmentation info for each memory group (#107475)
This information helps with tuning the heuristic of selecting memory
groups to release the unused pages.
2024-09-09 13:59:03 -07:00
Christopher Ferris
4634a480e0
[scudo] Add a method to use a hard-coded page size (#106646)
Currently, only Android supports using a hard-code page size. Make this
a bit more generic so any platform that wants to can use this.

In addition, add a getPageSizeLogCached() function since this value is
used in release.h and can avoid keeping this value around in objects.

Finally, change some of the release.h page size multiplies to shifts
using the new page size log value.
2024-09-05 13:43:34 -07:00
Christopher Ferris
1ff8657b26
[scudo] Use variable instead of recomputing. (#106647)
In the get fragmentation functions, there is already a variable that
computes the
in use bytes, so use that instead of recomputing it.
2024-09-04 14:12:25 -07:00
Joshua Baehring
0ef7b1d21c
[scudo] Update secondary cache released pages bound. (#106466)
`MaxReleasedCachePages` has been set to 4. Initially, in #105009 , we
set `MaxReleasedCachePages` to 0 so that the partial chunk heuristic
could be introduced incrementally as we observed its impact on retrieval
order and more generally, performance.

Co-authored-by: Joshua Baehring <josh.baehring@yale.edu>
2024-09-03 13:56:46 -07:00
Caslyn Tonelli
31204b472e
[scudo] Make comment compatible with gcc (#106137)
gcc interprets a backslash '\\' as the last char before a new line as a
line continuation character, even in a comment context. This can produce
an "error: multi-line comment [-Werror=comment]".

This PR adds delimiters so that the comment can compile with gcc.
2024-08-26 15:29:29 -07:00
Fabio D'Urso
c4b7c47fa5
[scudo] Fix expectation in ScudoTimingTest.VerifyMax (#106062) 2024-08-26 19:55:02 +02:00
Joshua Baehring
643bf6cb01
[scudo] Add partial chunk heuristic to retrieval algorithm. (#105009)
Previously the secondary cache retrieval algorithm would not allow
retrievals of memory chunks where the number of unused bytes would be
greater than than `MaxUnreleasedCachePages * PageSize` bytes. This meant
that even if a memory chunk satisfied the requirements of the optimal
fit algorithm, it may not be returned. This remains true if memory
tagging is enabled. However, if memory tagging is disabled, a new
heuristic has been put in place. Specifically, If a memory chunk is a
non-optimal fit, the cache retrieval algorithm will attempt to release
the excess memory to force a cache hit while keeping RSS down.

In the event that a memory chunk is a non-optimal fit, the retrieval
algorithm will release excess memory as long as the amount of memory to
be released is less than or equal to 4 Pages. If the amount of memory to
be released exceeds 4 Pages, the retrieval algorithm will not consider
that cached memory chunk valid for retrieval.

This change also addresses an alignment issue in a test case submitted
in #104807.
2024-08-26 10:44:39 -07:00
ChiaHungDuan
f9031f00f2
Revert "[scudo] Add partial chunk heuristic to retrieval algorithm." (#104894)
Reverts llvm/llvm-project#104807
2024-08-19 22:25:52 -07:00
Joshua Baehring
27dc247964
[scudo] Add partial chunk heuristic to retrieval algorithm. (#104807)
Previously the secondary cache retrieval algorithm would not allow
retrievals of memory chunks where the number of unused bytes would be
greater than than `MaxUnusedCachePages * PageSize` bytes. This meant
that even if a memory chunk satisfied the requirements of the optimal
fit algorithm, it may not be returned. This remains true if memory
tagging is enabled. However, if memory tagging is disabled, a new
heuristic has been put in place. Specifically, If a memory chunk is a
non-optimal fit, the cache retrieval algorithm will attempt to release
the excess memory to force a cache hit while keeping RSS down.

In the event that a memory chunk is a non-optimal fit, the retrieval
algorithm will release excess memory as long as the amount of memory to
be released is less than or equal to 16 KB. If the amount of memory to
be released exceeds 16 KB, the retrieval algorithm will not consider
that cached memory chunk valid for retrieval.
2024-08-19 18:03:35 -07:00
ChiaHungDuan
fdc4955086
Revert "[scudo] Separated committed and decommitted entries." (#104045)
Reverts llvm/llvm-project#101409

This caused some memory usage regressions and it has a known bug in page
releasing.
2024-08-14 09:09:50 -07:00
Mosè Giordano
248e885235
[compiler-rt] Define __STDC_FORMAT_MACROS to ensure PRId64 is available (#102980)
In
https://github.com/JuliaPackaging/Yggdrasil/pull/9246#issuecomment-2284894139
we ran into
```
[20:54:03] [ 65%] Building CXX object lib/scudo/standalone/CMakeFiles/RTScudoStandalone.x86_64.dir/timing.cpp.o
[20:54:03] cd /workspace/srcdir/compiler-rt-17.0.6.src/build/lib/scudo/standalone && /opt/bin/x86_64-linux-gnu-libgfortran5-cxx11/x86_64-linux-gnu-g++ --sysroot=/opt/x86_64-linux-gnu/x86_64-linux-gnu/sys-root/  -I/workspace/srcdir/compiler-rt-17.0.6.src/lib/scudo/standalone/../.. -I/workspace/srcdir/compiler-rt-17.0.6.src/lib/scudo/standalone/include -Wall -Wno-unused-parameter -O3 -DNDEBUG -m64 -Werror=conversion -Wall -Wextra -pedantic -g -nostdinc++ -fvisibility=hidden -fno-exceptions -Wno-pedantic -fno-lto -O3 -fno-omit-frame-pointer -DGWP_ASAN_HOOKS -std=c++17 -MD -MT lib/scudo/standalone/CMakeFiles/RTScudoStandalone.x86_64.dir/timing.cpp.o -MF CMakeFiles/RTScudoStandalone.x86_64.dir/timing.cpp.o.d -o CMakeFiles/RTScudoStandalone.x86_64.dir/timing.cpp.o -c /workspace/srcdir/compiler-rt-17.0.6.src/lib/scudo/standalone/timing.cpp
[...]
[20:54:03] In file included from /workspace/srcdir/compiler-rt-17.0.6.src/lib/scudo/standalone/timing.cpp:9:
[20:54:03] /workspace/srcdir/compiler-rt-17.0.6.src/lib/scudo/standalone/timing.h: In member function ‘void scudo::TimingManager::printImpl(scudo::ScopedString&, scudo::u32, scudo::u32)’:
[20:54:03] /workspace/srcdir/compiler-rt-17.0.6.src/lib/scudo/standalone/timing.h:182:21: error: expected ‘)’ before ‘PRId64’
[20:54:03]      Str.append("%14" PRId64 ".%" PRId64 "(ns) %-11s", Integral, Fraction, " ");
[20:54:03]                ~     ^~~~~~~
[20:54:03]                      )
[20:54:03] /workspace/srcdir/compiler-rt-17.0.6.src/lib/scudo/standalone/timing.h:182:16: warning: conversion lacks type at end of format [-Wformat=]
[20:54:03]      Str.append("%14" PRId64 ".%" PRId64 "(ns) %-11s", Integral, Fraction, " ");
[20:54:03]                 ^~~~~
[20:54:03] /workspace/srcdir/compiler-rt-17.0.6.src/lib/scudo/standalone/timing.h:182:16: warning: too many arguments for format [-Wformat-extra-args]
[20:54:03] /workspace/srcdir/compiler-rt-17.0.6.src/lib/scudo/standalone/timing.h:186:23: error: expected ‘)’ before ‘PRId64’
[20:54:03]      Str.append("%s (%" PRId64 ")\n", Timers[HandleId].Name, Occurrence);
[20:54:03]                ~       ^~~~~~~
[20:54:03]                        )
[20:54:03] /workspace/srcdir/compiler-rt-17.0.6.src/lib/scudo/standalone/timing.h:186:16: warning: spurious trailing ‘%’ in format [-Wformat=]
[20:54:03]      Str.append("%s (%" PRId64 ")\n", Timers[HandleId].Name, Occurrence);
[20:54:03]                 ^~~~~~~
```
when compiling compiler-rt with GCC 8. This was resolved by defining
`__STDC_FORMAT_MACROS`.
2024-08-13 09:22:11 -07:00
ChiaHungDuan
8ea8f1f2fe
[scudo] Support linking with index in IntrusiveList (#101262)
The nodes of list may be managed in an array. Instead of managing them
with pointers, using the array index will save some memory in some
cases.

When using the list linked with index, remember to call init() to set up
the base address of the array and a `EndOfListVal` which is nil of the
list.
2024-08-12 12:56:24 -07:00
Joshua Baehring
9f3ff8d28a
[scudo] Separated committed and decommitted entries. (#101409)
Initially, the LRU list stored all mapped entries with no distinction
between the committed (non-madvise()'d) entries and decommitted
(madvise()'d) entries. Now these two types of entries re separated into
two lists, allowing future cache logic to branch depending on whether or
not entries are committed or decommitted. Furthermore, the retrieval
algorithm will prioritize committed entries over decommitted entries.
Specifically, committed entries that satisfy the MaxUnusedCachePages
requirement are retrieved before optimal-fit, decommitted entries.

This commit addresses the compiler errors raised
[here](https://github.com/llvm/llvm-project/pull/100818#issuecomment-2261043261).
2024-08-09 10:56:07 -07:00