blob: 6d802c2839033587ec1f42a71e356ae93cf4c5f3 [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"
Yuki Shiino985ab91e2024-03-14 07:20:4619#include "partition_alloc/shim/allocator_shim.h"
[email protected]bac984102013-06-28 17:40:2420
Arthur Sonzogni62e877a2024-04-30 16:09:4321#if !PA_BUILDFLAG(USE_ALLOCATOR_SHIM) && \
Takashi Sakamoto76682f32023-11-14 06:21:3622 !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) && defined(LIBC_GLIBC)
23extern "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() {
34 if (internal::ReleaseAddressSpaceReservation())
35 return;
Torne (Richard Coles)f6e6c272021-01-26 16:58:4036 TerminateBecauseOutOfMemory(0);
Benoît Lizé70f64a02020-01-15 00:33:1337}
38
[email protected]bac984102013-06-28 17:40:2439} // namespace
40
[email protected]bac984102013-06-28 17:40:2441void EnableTerminationOnHeapCorruption() {
42 // On Linux, there nothing to do AFAIK.
43}
44
45void EnableTerminationOnOutOfMemory() {
[email protected]bac984102013-06-28 17:40:2446 // Set the new-out of memory handler.
Benoît Lizé70f64a02020-01-15 00:33:1347 std::set_new_handler(&ReleaseReservationOrTerminate);
[email protected]bac984102013-06-28 17:40:2448 // If we're using glibc's allocator, the above functions will override
49 // malloc and friends and make them die on out of memory.
primiano4e68ed22016-03-09 20:13:4450
Arthur Sonzogni62e877a2024-04-30 16:09:4351#if PA_BUILDFLAG(USE_ALLOCATOR_SHIM)
Yuki Shiino2ff81312022-09-05 13:11:5552 allocator_shim::SetCallNewHandlerOnMallocFailure(true);
primianof7b03f42016-01-26 00:00:2353#endif
[email protected]bac984102013-06-28 17:40:2454}
55
Cheng-Yu Leeacd58b3a2018-08-11 05:32:3756// ScopedAllowBlocking() has private constructor and it can only be used in
57// friend classes/functions. Declaring a class is easier in this situation to
58// avoid adding more dependency to thread_restrictions.h because of the
59// parameter used in AdjustOOMScore(). Specifically, ProcessId is a typedef
60// and we'll need to include another header file in thread_restrictions.h
61// without the class.
62class AdjustOOMScoreHelper {
63 public:
Peter Boström511258be2021-11-03 01:18:4664 AdjustOOMScoreHelper() = delete;
65 AdjustOOMScoreHelper(const AdjustOOMScoreHelper&) = delete;
66 AdjustOOMScoreHelper& operator=(const AdjustOOMScoreHelper&) = delete;
Tomasz Tylenda15aa9822021-11-02 12:30:2367
Peter Boström511258be2021-11-03 01:18:4668 static bool AdjustOOMScore(ProcessId process, int score);
Cheng-Yu Leeacd58b3a2018-08-11 05:32:3769};
70
71// static.
72bool AdjustOOMScoreHelper::AdjustOOMScore(ProcessId process, int score) {
[email protected]bac984102013-06-28 17:40:2473 if (score < 0 || score > kMaxOomScore)
74 return false;
75
76 FilePath oom_path(internal::GetProcPidDir(process));
77
Cheng-Yu Leeacd58b3a2018-08-11 05:32:3778 // Temporarily allowing blocking since oom paths are pseudo-filesystem paths.
79 base::ScopedAllowBlocking allow_blocking;
80
[email protected]bac984102013-06-28 17:40:2481 // Attempt to write the newer oom_score_adj file first.
82 FilePath oom_file = oom_path.AppendASCII("oom_score_adj");
[email protected]7567484142013-07-11 17:36:0783 if (PathExists(oom_file)) {
Raul Tambrea9c13642019-03-25 13:34:4284 std::string score_str = NumberToString(score);
[email protected]bac984102013-06-28 17:40:2485 DVLOG(1) << "Adjusting oom_score_adj of " << process << " to "
86 << score_str;
danakj5807186462024-06-06 20:10:3787 return WriteFile(oom_file, as_byte_span(score_str));
[email protected]bac984102013-06-28 17:40:2488 }
89
90 // If the oom_score_adj file doesn't exist, then we write the old
91 // style file and translate the oom_adj score to the range 0-15.
92 oom_file = oom_path.AppendASCII("oom_adj");
[email protected]7567484142013-07-11 17:36:0793 if (PathExists(oom_file)) {
[email protected]bac984102013-06-28 17:40:2494 // Max score for the old oom_adj range. Used for conversion of new
95 // values to old values.
96 const int kMaxOldOomScore = 15;
97
98 int converted_score = score * kMaxOldOomScore / kMaxOomScore;
Raul Tambrea9c13642019-03-25 13:34:4299 std::string score_str = NumberToString(converted_score);
[email protected]bac984102013-06-28 17:40:24100 DVLOG(1) << "Adjusting oom_adj of " << process << " to " << score_str;
danakj5807186462024-06-06 20:10:37101 return WriteFile(oom_file, as_byte_span(score_str));
[email protected]bac984102013-06-28 17:40:24102 }
103
104 return false;
105}
106
Cheng-Yu Leeacd58b3a2018-08-11 05:32:37107// NOTE: This is not the only version of this function in the source:
108// the setuid sandbox (in process_util_linux.c, in the sandbox source)
109// also has its own C version.
110bool AdjustOOMScore(ProcessId process, int score) {
111 return AdjustOOMScoreHelper::AdjustOOMScore(process, score);
112}
113
[email protected]29159eb2014-03-21 22:07:03114bool UncheckedMalloc(size_t size, void** result) {
Arthur Sonzogni62e877a2024-04-30 16:09:43115#if PA_BUILDFLAG(USE_ALLOCATOR_SHIM)
Yuki Shiino2ff81312022-09-05 13:11:55116 *result = allocator_shim::UncheckedAlloc(size);
Benoit Lizef4e14722022-01-12 10:56:52117#elif defined(MEMORY_TOOL_REPLACES_ALLOCATOR) || !defined(LIBC_GLIBC)
[email protected]29159eb2014-03-21 22:07:03118 *result = malloc(size);
Benoit Lizef4e14722022-01-12 10:56:52119#elif defined(LIBC_GLIBC)
[email protected]29159eb2014-03-21 22:07:03120 *result = __libc_malloc(size);
[email protected]29159eb2014-03-21 22:07:03121#endif
Ivan Kotenkova16212a52017-11-08 12:37:33122 return *result != nullptr;
[email protected]29159eb2014-03-21 22:07:03123}
124
Benoit Lize69ecd9f722021-12-13 13:49:05125void UncheckedFree(void* ptr) {
Arthur Sonzogni62e877a2024-04-30 16:09:43126#if PA_BUILDFLAG(USE_ALLOCATOR_SHIM)
Yuki Shiino2ff81312022-09-05 13:11:55127 allocator_shim::UncheckedFree(ptr);
Benoit Lizef4e14722022-01-12 10:56:52128#elif defined(MEMORY_TOOL_REPLACES_ALLOCATOR) || !defined(LIBC_GLIBC)
Benoit Lize69ecd9f722021-12-13 13:49:05129 free(ptr);
Benoit Lizef4e14722022-01-12 10:56:52130#elif defined(LIBC_GLIBC)
Benoit Lize69ecd9f722021-12-13 13:49:05131 __libc_free(ptr);
Benoit Lize69ecd9f722021-12-13 13:49:05132#endif
133}
134
[email protected]bac984102013-06-28 17:40:24135} // namespace base