Thanks to visit codestin.com
Credit goes to chromium.googlesource.com

blob: 4f1aefa5472bdd5ba5927190673cdf440ec9eae5 [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*);
Etienne Dechamps8e1287b2025-09-17 14:59:2226void* __libc_calloc(size_t, size_t);
Takashi Sakamoto76682f32023-11-14 06:21:3627}
28#endif
29
[email protected]bac984102013-06-28 17:40:2430namespace base {
31
32namespace {
33
Benoît Lizé70f64a02020-01-15 00:33:1334void ReleaseReservationOrTerminate() {
Peter Kasting134ef9af2024-12-28 02:30:0935 if (internal::ReleaseAddressSpaceReservation()) {
Benoît Lizé70f64a02020-01-15 00:33:1336 return;
Peter Kasting134ef9af2024-12-28 02:30:0937 }
Torne (Richard Coles)f6e6c272021-01-26 16:58:4038 TerminateBecauseOutOfMemory(0);
Benoît Lizé70f64a02020-01-15 00:33:1339}
40
[email protected]bac984102013-06-28 17:40:2441} // namespace
42
[email protected]bac984102013-06-28 17:40:2443void EnableTerminationOnHeapCorruption() {
44 // On Linux, there nothing to do AFAIK.
45}
46
47void EnableTerminationOnOutOfMemory() {
[email protected]bac984102013-06-28 17:40:2448 // Set the new-out of memory handler.
Benoît Lizé70f64a02020-01-15 00:33:1349 std::set_new_handler(&ReleaseReservationOrTerminate);
[email protected]bac984102013-06-28 17:40:2450 // If we're using glibc's allocator, the above functions will override
51 // malloc and friends and make them die on out of memory.
primiano4e68ed22016-03-09 20:13:4452
Arthur Sonzogni62e877a2024-04-30 16:09:4353#if PA_BUILDFLAG(USE_ALLOCATOR_SHIM)
Yuki Shiino2ff81312022-09-05 13:11:5554 allocator_shim::SetCallNewHandlerOnMallocFailure(true);
primianof7b03f42016-01-26 00:00:2355#endif
[email protected]bac984102013-06-28 17:40:2456}
57
Cheng-Yu Leeacd58b3a2018-08-11 05:32:3758// ScopedAllowBlocking() has private constructor and it can only be used in
59// friend classes/functions. Declaring a class is easier in this situation to
60// avoid adding more dependency to thread_restrictions.h because of the
61// parameter used in AdjustOOMScore(). Specifically, ProcessId is a typedef
62// and we'll need to include another header file in thread_restrictions.h
63// without the class.
64class AdjustOOMScoreHelper {
65 public:
Peter Boström511258be2021-11-03 01:18:4666 AdjustOOMScoreHelper() = delete;
67 AdjustOOMScoreHelper(const AdjustOOMScoreHelper&) = delete;
68 AdjustOOMScoreHelper& operator=(const AdjustOOMScoreHelper&) = delete;
Tomasz Tylenda15aa9822021-11-02 12:30:2369
Peter Boström511258be2021-11-03 01:18:4670 static bool AdjustOOMScore(ProcessId process, int score);
Cheng-Yu Leeacd58b3a2018-08-11 05:32:3771};
72
73// static.
74bool AdjustOOMScoreHelper::AdjustOOMScore(ProcessId process, int score) {
Peter Kasting134ef9af2024-12-28 02:30:0975 if (score < 0 || score > kMaxOomScore) {
[email protected]bac984102013-06-28 17:40:2476 return false;
Peter Kasting134ef9af2024-12-28 02:30:0977 }
[email protected]bac984102013-06-28 17:40:2478
79 FilePath oom_path(internal::GetProcPidDir(process));
80
Cheng-Yu Leeacd58b3a2018-08-11 05:32:3781 // Temporarily allowing blocking since oom paths are pseudo-filesystem paths.
82 base::ScopedAllowBlocking allow_blocking;
83
[email protected]bac984102013-06-28 17:40:2484 // Attempt to write the newer oom_score_adj file first.
85 FilePath oom_file = oom_path.AppendASCII("oom_score_adj");
[email protected]7567484142013-07-11 17:36:0786 if (PathExists(oom_file)) {
Raul Tambrea9c13642019-03-25 13:34:4287 std::string score_str = NumberToString(score);
Peter Kasting134ef9af2024-12-28 02:30:0988 DVLOG(1) << "Adjusting oom_score_adj of " << process << " to " << score_str;
danakj5807186462024-06-06 20:10:3789 return WriteFile(oom_file, as_byte_span(score_str));
[email protected]bac984102013-06-28 17:40:2490 }
91
92 // If the oom_score_adj file doesn't exist, then we write the old
93 // style file and translate the oom_adj score to the range 0-15.
94 oom_file = oom_path.AppendASCII("oom_adj");
[email protected]7567484142013-07-11 17:36:0795 if (PathExists(oom_file)) {
[email protected]bac984102013-06-28 17:40:2496 // Max score for the old oom_adj range. Used for conversion of new
97 // values to old values.
98 const int kMaxOldOomScore = 15;
99
100 int converted_score = score * kMaxOldOomScore / kMaxOomScore;
Raul Tambrea9c13642019-03-25 13:34:42101 std::string score_str = NumberToString(converted_score);
[email protected]bac984102013-06-28 17:40:24102 DVLOG(1) << "Adjusting oom_adj of " << process << " to " << score_str;
danakj5807186462024-06-06 20:10:37103 return WriteFile(oom_file, as_byte_span(score_str));
[email protected]bac984102013-06-28 17:40:24104 }
105
106 return false;
107}
108
Cheng-Yu Leeacd58b3a2018-08-11 05:32:37109// NOTE: This is not the only version of this function in the source:
110// the setuid sandbox (in process_util_linux.c, in the sandbox source)
111// also has its own C version.
112bool AdjustOOMScore(ProcessId process, int score) {
113 return AdjustOOMScoreHelper::AdjustOOMScore(process, score);
114}
115
Aldo Culquicondor189a4b52025-09-12 16:22:03116bool UncheckedCalloc(size_t num_items, size_t size, void** result) {
117#if PA_BUILDFLAG(USE_ALLOCATOR_SHIM)
118 *result = allocator_shim::UncheckedCalloc(num_items, size);
119#elif defined(MEMORY_TOOL_REPLACES_ALLOCATOR) || !defined(LIBC_GLIBC)
120 *result = calloc(num_items, size);
121#elif defined(LIBC_GLIBC)
122 *result = __libc_calloc(num_items, size);
123#endif
124 return *result != nullptr;
125}
126
[email protected]29159eb2014-03-21 22:07:03127bool UncheckedMalloc(size_t size, void** result) {
Arthur Sonzogni62e877a2024-04-30 16:09:43128#if PA_BUILDFLAG(USE_ALLOCATOR_SHIM)
Yuki Shiino2ff81312022-09-05 13:11:55129 *result = allocator_shim::UncheckedAlloc(size);
Benoit Lizef4e14722022-01-12 10:56:52130#elif defined(MEMORY_TOOL_REPLACES_ALLOCATOR) || !defined(LIBC_GLIBC)
[email protected]29159eb2014-03-21 22:07:03131 *result = malloc(size);
Benoit Lizef4e14722022-01-12 10:56:52132#elif defined(LIBC_GLIBC)
[email protected]29159eb2014-03-21 22:07:03133 *result = __libc_malloc(size);
[email protected]29159eb2014-03-21 22:07:03134#endif
Ivan Kotenkova16212a52017-11-08 12:37:33135 return *result != nullptr;
[email protected]29159eb2014-03-21 22:07:03136}
137
Benoit Lize69ecd9f722021-12-13 13:49:05138void UncheckedFree(void* ptr) {
Arthur Sonzogni62e877a2024-04-30 16:09:43139#if PA_BUILDFLAG(USE_ALLOCATOR_SHIM)
Yuki Shiino2ff81312022-09-05 13:11:55140 allocator_shim::UncheckedFree(ptr);
Benoit Lizef4e14722022-01-12 10:56:52141#elif defined(MEMORY_TOOL_REPLACES_ALLOCATOR) || !defined(LIBC_GLIBC)
Benoit Lize69ecd9f722021-12-13 13:49:05142 free(ptr);
Benoit Lizef4e14722022-01-12 10:56:52143#elif defined(LIBC_GLIBC)
Benoit Lize69ecd9f722021-12-13 13:49:05144 __libc_free(ptr);
Benoit Lize69ecd9f722021-12-13 13:49:05145#endif
146}
147
[email protected]bac984102013-06-28 17:40:24148} // namespace base