blob: 6d2b69c4dd6858d3e38f78aee1284b18b35a320b [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2013 The Chromium Authors
[email protected]bac984102013-06-28 17:40:242// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/process/memory.h"
6
avibeced7c2015-12-24 06:47:597#include <stddef.h>
8
[email protected]bac984102013-06-28 17:40:249#include <new>
10
[email protected]bac984102013-06-28 17:40:2411#include "base/files/file_path.h"
[email protected]e3177dd52014-08-13 20:22:1412#include "base/files/file_util.h"
[email protected]bac984102013-06-28 17:40:2413#include "base/logging.h"
14#include "base/process/internal_linux.h"
15#include "base/strings/string_number_conversions.h"
Cheng-Yu Leeacd58b3a2018-08-11 05:32:3716#include "base/threading/thread_restrictions.h"
avibeced7c2015-12-24 06:47:5917#include "build/build_config.h"
Arthur Sonzognifd39d612024-06-26 08:16:2318#include "partition_alloc/buildflags.h"
[email protected]bac984102013-06-28 17:40:2419
Etienne Dechamps4dacf2b2024-12-19 16:31:0520#if PA_BUILDFLAG(USE_ALLOCATOR_SHIM)
21#include "partition_alloc/shim/allocator_shim.h" // nogncheck
22#elif !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) && defined(LIBC_GLIBC)
Takashi Sakamoto76682f32023-11-14 06:21:3623extern "C" {
24void* __libc_malloc(size_t);
25void __libc_free(void*);
26}
27#endif
28
[email protected]bac984102013-06-28 17:40:2429namespace base {
30
31namespace {
32
Benoît Lizé70f64a02020-01-15 00:33:1333void ReleaseReservationOrTerminate() {
Peter Kasting134ef9af2024-12-28 02:30:0934 if (internal::ReleaseAddressSpaceReservation()) {
Benoît Lizé70f64a02020-01-15 00:33:1335 return;
Peter Kasting134ef9af2024-12-28 02:30:0936 }
Torne (Richard Coles)f6e6c272021-01-26 16:58:4037 TerminateBecauseOutOfMemory(0);
Benoît Lizé70f64a02020-01-15 00:33:1338}
39
[email protected]bac984102013-06-28 17:40:2440} // namespace
41
[email protected]bac984102013-06-28 17:40:2442void EnableTerminationOnHeapCorruption() {
43 // On Linux, there nothing to do AFAIK.
44}
45
46void EnableTerminationOnOutOfMemory() {
[email protected]bac984102013-06-28 17:40:2447 // Set the new-out of memory handler.
Benoît Lizé70f64a02020-01-15 00:33:1348 std::set_new_handler(&ReleaseReservationOrTerminate);
[email protected]bac984102013-06-28 17:40:2449 // If we're using glibc's allocator, the above functions will override
50 // malloc and friends and make them die on out of memory.
primiano4e68ed22016-03-09 20:13:4451
Arthur Sonzogni62e877a2024-04-30 16:09:4352#if PA_BUILDFLAG(USE_ALLOCATOR_SHIM)
Yuki Shiino2ff81312022-09-05 13:11:5553 allocator_shim::SetCallNewHandlerOnMallocFailure(true);
primianof7b03f42016-01-26 00:00:2354#endif
[email protected]bac984102013-06-28 17:40:2455}
56
Cheng-Yu Leeacd58b3a2018-08-11 05:32:3757// ScopedAllowBlocking() has private constructor and it can only be used in
58// friend classes/functions. Declaring a class is easier in this situation to
59// avoid adding more dependency to thread_restrictions.h because of the
60// parameter used in AdjustOOMScore(). Specifically, ProcessId is a typedef
61// and we'll need to include another header file in thread_restrictions.h
62// without the class.
63class AdjustOOMScoreHelper {
64 public:
Peter Boström511258be2021-11-03 01:18:4665 AdjustOOMScoreHelper() = delete;
66 AdjustOOMScoreHelper(const AdjustOOMScoreHelper&) = delete;
67 AdjustOOMScoreHelper& operator=(const AdjustOOMScoreHelper&) = delete;
Tomasz Tylenda15aa9822021-11-02 12:30:2368
Peter Boström511258be2021-11-03 01:18:4669 static bool AdjustOOMScore(ProcessId process, int score);
Cheng-Yu Leeacd58b3a2018-08-11 05:32:3770};
71
72// static.
73bool AdjustOOMScoreHelper::AdjustOOMScore(ProcessId process, int score) {
Peter Kasting134ef9af2024-12-28 02:30:0974 if (score < 0 || score > kMaxOomScore) {
[email protected]bac984102013-06-28 17:40:2475 return false;
Peter Kasting134ef9af2024-12-28 02:30:0976 }
[email protected]bac984102013-06-28 17:40:2477
78 FilePath oom_path(internal::GetProcPidDir(process));
79
Cheng-Yu Leeacd58b3a2018-08-11 05:32:3780 // Temporarily allowing blocking since oom paths are pseudo-filesystem paths.
81 base::ScopedAllowBlocking allow_blocking;
82
[email protected]bac984102013-06-28 17:40:2483 // Attempt to write the newer oom_score_adj file first.
84 FilePath oom_file = oom_path.AppendASCII("oom_score_adj");
[email protected]7567484142013-07-11 17:36:0785 if (PathExists(oom_file)) {
Raul Tambrea9c13642019-03-25 13:34:4286 std::string score_str = NumberToString(score);
Peter Kasting134ef9af2024-12-28 02:30:0987 DVLOG(1) << "Adjusting oom_score_adj of " << process << " to " << score_str;
danakj5807186462024-06-06 20:10:3788 return WriteFile(oom_file, as_byte_span(score_str));
[email protected]bac984102013-06-28 17:40:2489 }
90
91 // If the oom_score_adj file doesn't exist, then we write the old
92 // style file and translate the oom_adj score to the range 0-15.
93 oom_file = oom_path.AppendASCII("oom_adj");
[email protected]7567484142013-07-11 17:36:0794 if (PathExists(oom_file)) {
[email protected]bac984102013-06-28 17:40:2495 // Max score for the old oom_adj range. Used for conversion of new
96 // values to old values.
97 const int kMaxOldOomScore = 15;
98
99 int converted_score = score * kMaxOldOomScore / kMaxOomScore;
Raul Tambrea9c13642019-03-25 13:34:42100 std::string score_str = NumberToString(converted_score);
[email protected]bac984102013-06-28 17:40:24101 DVLOG(1) << "Adjusting oom_adj of " << process << " to " << score_str;
danakj5807186462024-06-06 20:10:37102 return WriteFile(oom_file, as_byte_span(score_str));
[email protected]bac984102013-06-28 17:40:24103 }
104
105 return false;
106}
107
Cheng-Yu Leeacd58b3a2018-08-11 05:32:37108// NOTE: This is not the only version of this function in the source:
109// the setuid sandbox (in process_util_linux.c, in the sandbox source)
110// also has its own C version.
111bool AdjustOOMScore(ProcessId process, int score) {
112 return AdjustOOMScoreHelper::AdjustOOMScore(process, score);
113}
114
[email protected]29159eb2014-03-21 22:07:03115bool UncheckedMalloc(size_t size, void** result) {
Arthur Sonzogni62e877a2024-04-30 16:09:43116#if PA_BUILDFLAG(USE_ALLOCATOR_SHIM)
Yuki Shiino2ff81312022-09-05 13:11:55117 *result = allocator_shim::UncheckedAlloc(size);
Benoit Lizef4e14722022-01-12 10:56:52118#elif defined(MEMORY_TOOL_REPLACES_ALLOCATOR) || !defined(LIBC_GLIBC)
[email protected]29159eb2014-03-21 22:07:03119 *result = malloc(size);
Benoit Lizef4e14722022-01-12 10:56:52120#elif defined(LIBC_GLIBC)
[email protected]29159eb2014-03-21 22:07:03121 *result = __libc_malloc(size);
[email protected]29159eb2014-03-21 22:07:03122#endif
Ivan Kotenkova16212a52017-11-08 12:37:33123 return *result != nullptr;
[email protected]29159eb2014-03-21 22:07:03124}
125
Benoit Lize69ecd9f722021-12-13 13:49:05126void UncheckedFree(void* ptr) {
Arthur Sonzogni62e877a2024-04-30 16:09:43127#if PA_BUILDFLAG(USE_ALLOCATOR_SHIM)
Yuki Shiino2ff81312022-09-05 13:11:55128 allocator_shim::UncheckedFree(ptr);
Benoit Lizef4e14722022-01-12 10:56:52129#elif defined(MEMORY_TOOL_REPLACES_ALLOCATOR) || !defined(LIBC_GLIBC)
Benoit Lize69ecd9f722021-12-13 13:49:05130 free(ptr);
Benoit Lizef4e14722022-01-12 10:56:52131#elif defined(LIBC_GLIBC)
Benoit Lize69ecd9f722021-12-13 13:49:05132 __libc_free(ptr);
Benoit Lize69ecd9f722021-12-13 13:49:05133#endif
134}
135
[email protected]bac984102013-06-28 17:40:24136} // namespace base