xref: /aosp_15_r20/external/cronet/base/process/memory_linux.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "base/process/memory.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include <new>
10*6777b538SAndroid Build Coastguard Worker 
11*6777b538SAndroid Build Coastguard Worker #include "base/files/file_path.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/files/file_util.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/process/internal_linux.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_number_conversions.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/threading/thread_restrictions.h"
17*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
18*6777b538SAndroid Build Coastguard Worker #include "partition_alloc/partition_alloc_buildflags.h"
19*6777b538SAndroid Build Coastguard Worker #include "partition_alloc/shim/allocator_shim.h"
20*6777b538SAndroid Build Coastguard Worker 
21*6777b538SAndroid Build Coastguard Worker #if !BUILDFLAG(USE_ALLOCATOR_SHIM) && \
22*6777b538SAndroid Build Coastguard Worker     !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) && defined(LIBC_GLIBC)
23*6777b538SAndroid Build Coastguard Worker extern "C" {
24*6777b538SAndroid Build Coastguard Worker void* __libc_malloc(size_t);
25*6777b538SAndroid Build Coastguard Worker void __libc_free(void*);
26*6777b538SAndroid Build Coastguard Worker }
27*6777b538SAndroid Build Coastguard Worker #endif
28*6777b538SAndroid Build Coastguard Worker 
29*6777b538SAndroid Build Coastguard Worker namespace base {
30*6777b538SAndroid Build Coastguard Worker 
31*6777b538SAndroid Build Coastguard Worker namespace {
32*6777b538SAndroid Build Coastguard Worker 
ReleaseReservationOrTerminate()33*6777b538SAndroid Build Coastguard Worker void ReleaseReservationOrTerminate() {
34*6777b538SAndroid Build Coastguard Worker   if (internal::ReleaseAddressSpaceReservation())
35*6777b538SAndroid Build Coastguard Worker     return;
36*6777b538SAndroid Build Coastguard Worker   TerminateBecauseOutOfMemory(0);
37*6777b538SAndroid Build Coastguard Worker }
38*6777b538SAndroid Build Coastguard Worker 
39*6777b538SAndroid Build Coastguard Worker }  // namespace
40*6777b538SAndroid Build Coastguard Worker 
EnableTerminationOnHeapCorruption()41*6777b538SAndroid Build Coastguard Worker void EnableTerminationOnHeapCorruption() {
42*6777b538SAndroid Build Coastguard Worker   // On Linux, there nothing to do AFAIK.
43*6777b538SAndroid Build Coastguard Worker }
44*6777b538SAndroid Build Coastguard Worker 
EnableTerminationOnOutOfMemory()45*6777b538SAndroid Build Coastguard Worker void EnableTerminationOnOutOfMemory() {
46*6777b538SAndroid Build Coastguard Worker   // Set the new-out of memory handler.
47*6777b538SAndroid Build Coastguard Worker   std::set_new_handler(&ReleaseReservationOrTerminate);
48*6777b538SAndroid Build Coastguard Worker   // If we're using glibc's allocator, the above functions will override
49*6777b538SAndroid Build Coastguard Worker   // malloc and friends and make them die on out of memory.
50*6777b538SAndroid Build Coastguard Worker 
51*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_ALLOCATOR_SHIM)
52*6777b538SAndroid Build Coastguard Worker   allocator_shim::SetCallNewHandlerOnMallocFailure(true);
53*6777b538SAndroid Build Coastguard Worker #endif
54*6777b538SAndroid Build Coastguard Worker }
55*6777b538SAndroid Build Coastguard Worker 
56*6777b538SAndroid Build Coastguard Worker // ScopedAllowBlocking() has private constructor and it can only be used in
57*6777b538SAndroid Build Coastguard Worker // friend classes/functions. Declaring a class is easier in this situation to
58*6777b538SAndroid Build Coastguard Worker // avoid adding more dependency to thread_restrictions.h because of the
59*6777b538SAndroid Build Coastguard Worker // parameter used in AdjustOOMScore(). Specifically, ProcessId is a typedef
60*6777b538SAndroid Build Coastguard Worker // and we'll need to include another header file in thread_restrictions.h
61*6777b538SAndroid Build Coastguard Worker // without the class.
62*6777b538SAndroid Build Coastguard Worker class AdjustOOMScoreHelper {
63*6777b538SAndroid Build Coastguard Worker  public:
64*6777b538SAndroid Build Coastguard Worker   AdjustOOMScoreHelper() = delete;
65*6777b538SAndroid Build Coastguard Worker   AdjustOOMScoreHelper(const AdjustOOMScoreHelper&) = delete;
66*6777b538SAndroid Build Coastguard Worker   AdjustOOMScoreHelper& operator=(const AdjustOOMScoreHelper&) = delete;
67*6777b538SAndroid Build Coastguard Worker 
68*6777b538SAndroid Build Coastguard Worker   static bool AdjustOOMScore(ProcessId process, int score);
69*6777b538SAndroid Build Coastguard Worker };
70*6777b538SAndroid Build Coastguard Worker 
71*6777b538SAndroid Build Coastguard Worker // static.
AdjustOOMScore(ProcessId process,int score)72*6777b538SAndroid Build Coastguard Worker bool AdjustOOMScoreHelper::AdjustOOMScore(ProcessId process, int score) {
73*6777b538SAndroid Build Coastguard Worker   if (score < 0 || score > kMaxOomScore)
74*6777b538SAndroid Build Coastguard Worker     return false;
75*6777b538SAndroid Build Coastguard Worker 
76*6777b538SAndroid Build Coastguard Worker   FilePath oom_path(internal::GetProcPidDir(process));
77*6777b538SAndroid Build Coastguard Worker 
78*6777b538SAndroid Build Coastguard Worker   // Temporarily allowing blocking since oom paths are pseudo-filesystem paths.
79*6777b538SAndroid Build Coastguard Worker   base::ScopedAllowBlocking allow_blocking;
80*6777b538SAndroid Build Coastguard Worker 
81*6777b538SAndroid Build Coastguard Worker   // Attempt to write the newer oom_score_adj file first.
82*6777b538SAndroid Build Coastguard Worker   FilePath oom_file = oom_path.AppendASCII("oom_score_adj");
83*6777b538SAndroid Build Coastguard Worker   if (PathExists(oom_file)) {
84*6777b538SAndroid Build Coastguard Worker     std::string score_str = NumberToString(score);
85*6777b538SAndroid Build Coastguard Worker     DVLOG(1) << "Adjusting oom_score_adj of " << process << " to "
86*6777b538SAndroid Build Coastguard Worker              << score_str;
87*6777b538SAndroid Build Coastguard Worker     int score_len = static_cast<int>(score_str.length());
88*6777b538SAndroid Build Coastguard Worker     return (score_len == WriteFile(oom_file, score_str.c_str(), score_len));
89*6777b538SAndroid Build Coastguard Worker   }
90*6777b538SAndroid Build Coastguard Worker 
91*6777b538SAndroid Build Coastguard Worker   // If the oom_score_adj file doesn't exist, then we write the old
92*6777b538SAndroid Build Coastguard Worker   // style file and translate the oom_adj score to the range 0-15.
93*6777b538SAndroid Build Coastguard Worker   oom_file = oom_path.AppendASCII("oom_adj");
94*6777b538SAndroid Build Coastguard Worker   if (PathExists(oom_file)) {
95*6777b538SAndroid Build Coastguard Worker     // Max score for the old oom_adj range.  Used for conversion of new
96*6777b538SAndroid Build Coastguard Worker     // values to old values.
97*6777b538SAndroid Build Coastguard Worker     const int kMaxOldOomScore = 15;
98*6777b538SAndroid Build Coastguard Worker 
99*6777b538SAndroid Build Coastguard Worker     int converted_score = score * kMaxOldOomScore / kMaxOomScore;
100*6777b538SAndroid Build Coastguard Worker     std::string score_str = NumberToString(converted_score);
101*6777b538SAndroid Build Coastguard Worker     DVLOG(1) << "Adjusting oom_adj of " << process << " to " << score_str;
102*6777b538SAndroid Build Coastguard Worker     int score_len = static_cast<int>(score_str.length());
103*6777b538SAndroid Build Coastguard Worker     return (score_len == WriteFile(oom_file, score_str.c_str(), score_len));
104*6777b538SAndroid Build Coastguard Worker   }
105*6777b538SAndroid Build Coastguard Worker 
106*6777b538SAndroid Build Coastguard Worker   return false;
107*6777b538SAndroid Build Coastguard Worker }
108*6777b538SAndroid Build Coastguard Worker 
109*6777b538SAndroid Build Coastguard Worker // NOTE: This is not the only version of this function in the source:
110*6777b538SAndroid Build Coastguard Worker // the setuid sandbox (in process_util_linux.c, in the sandbox source)
111*6777b538SAndroid Build Coastguard Worker // also has its own C version.
AdjustOOMScore(ProcessId process,int score)112*6777b538SAndroid Build Coastguard Worker bool AdjustOOMScore(ProcessId process, int score) {
113*6777b538SAndroid Build Coastguard Worker   return AdjustOOMScoreHelper::AdjustOOMScore(process, score);
114*6777b538SAndroid Build Coastguard Worker }
115*6777b538SAndroid Build Coastguard Worker 
UncheckedMalloc(size_t size,void ** result)116*6777b538SAndroid Build Coastguard Worker bool UncheckedMalloc(size_t size, void** result) {
117*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_ALLOCATOR_SHIM)
118*6777b538SAndroid Build Coastguard Worker   *result = allocator_shim::UncheckedAlloc(size);
119*6777b538SAndroid Build Coastguard Worker #elif defined(MEMORY_TOOL_REPLACES_ALLOCATOR) || !defined(LIBC_GLIBC)
120*6777b538SAndroid Build Coastguard Worker   *result = malloc(size);
121*6777b538SAndroid Build Coastguard Worker #elif defined(LIBC_GLIBC)
122*6777b538SAndroid Build Coastguard Worker   *result = __libc_malloc(size);
123*6777b538SAndroid Build Coastguard Worker #endif
124*6777b538SAndroid Build Coastguard Worker   return *result != nullptr;
125*6777b538SAndroid Build Coastguard Worker }
126*6777b538SAndroid Build Coastguard Worker 
UncheckedFree(void * ptr)127*6777b538SAndroid Build Coastguard Worker void UncheckedFree(void* ptr) {
128*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_ALLOCATOR_SHIM)
129*6777b538SAndroid Build Coastguard Worker   allocator_shim::UncheckedFree(ptr);
130*6777b538SAndroid Build Coastguard Worker #elif defined(MEMORY_TOOL_REPLACES_ALLOCATOR) || !defined(LIBC_GLIBC)
131*6777b538SAndroid Build Coastguard Worker   free(ptr);
132*6777b538SAndroid Build Coastguard Worker #elif defined(LIBC_GLIBC)
133*6777b538SAndroid Build Coastguard Worker   __libc_free(ptr);
134*6777b538SAndroid Build Coastguard Worker #endif
135*6777b538SAndroid Build Coastguard Worker }
136*6777b538SAndroid Build Coastguard Worker 
137*6777b538SAndroid Build Coastguard Worker }  // namespace base
138