xref: /aosp_15_r20/external/libchrome/base/process/memory_linux.cc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #include "base/process/memory.h"
6*635a8641SAndroid Build Coastguard Worker 
7*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
8*635a8641SAndroid Build Coastguard Worker 
9*635a8641SAndroid Build Coastguard Worker #include <new>
10*635a8641SAndroid Build Coastguard Worker 
11*635a8641SAndroid Build Coastguard Worker #include "base/allocator/allocator_shim.h"
12*635a8641SAndroid Build Coastguard Worker #include "base/allocator/buildflags.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/files/file_path.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/files/file_util.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/logging.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/process/internal_linux.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/strings/string_number_conversions.h"
18*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
19*635a8641SAndroid Build Coastguard Worker 
20*635a8641SAndroid Build Coastguard Worker #if defined(USE_TCMALLOC)
21*635a8641SAndroid Build Coastguard Worker #include "third_party/tcmalloc/gperftools-2.0/chromium/src/config.h"
22*635a8641SAndroid Build Coastguard Worker #include "third_party/tcmalloc/gperftools-2.0/chromium/src/gperftools/tcmalloc.h"
23*635a8641SAndroid Build Coastguard Worker #endif
24*635a8641SAndroid Build Coastguard Worker 
25*635a8641SAndroid Build Coastguard Worker extern "C" {
26*635a8641SAndroid Build Coastguard Worker void* __libc_malloc(size_t size);
27*635a8641SAndroid Build Coastguard Worker }
28*635a8641SAndroid Build Coastguard Worker 
29*635a8641SAndroid Build Coastguard Worker namespace base {
30*635a8641SAndroid Build Coastguard Worker 
31*635a8641SAndroid Build Coastguard Worker size_t g_oom_size = 0U;
32*635a8641SAndroid Build Coastguard Worker 
33*635a8641SAndroid Build Coastguard Worker namespace {
34*635a8641SAndroid Build Coastguard Worker 
OnNoMemorySize(size_t size)35*635a8641SAndroid Build Coastguard Worker void OnNoMemorySize(size_t size) {
36*635a8641SAndroid Build Coastguard Worker   g_oom_size = size;
37*635a8641SAndroid Build Coastguard Worker 
38*635a8641SAndroid Build Coastguard Worker   if (size != 0)
39*635a8641SAndroid Build Coastguard Worker     LOG(FATAL) << "Out of memory, size = " << size;
40*635a8641SAndroid Build Coastguard Worker   LOG(FATAL) << "Out of memory.";
41*635a8641SAndroid Build Coastguard Worker }
42*635a8641SAndroid Build Coastguard Worker 
OnNoMemory()43*635a8641SAndroid Build Coastguard Worker void OnNoMemory() {
44*635a8641SAndroid Build Coastguard Worker   OnNoMemorySize(0);
45*635a8641SAndroid Build Coastguard Worker }
46*635a8641SAndroid Build Coastguard Worker 
47*635a8641SAndroid Build Coastguard Worker }  // namespace
48*635a8641SAndroid Build Coastguard Worker 
EnableTerminationOnHeapCorruption()49*635a8641SAndroid Build Coastguard Worker void EnableTerminationOnHeapCorruption() {
50*635a8641SAndroid Build Coastguard Worker   // On Linux, there nothing to do AFAIK.
51*635a8641SAndroid Build Coastguard Worker }
52*635a8641SAndroid Build Coastguard Worker 
EnableTerminationOnOutOfMemory()53*635a8641SAndroid Build Coastguard Worker void EnableTerminationOnOutOfMemory() {
54*635a8641SAndroid Build Coastguard Worker   // Set the new-out of memory handler.
55*635a8641SAndroid Build Coastguard Worker   std::set_new_handler(&OnNoMemory);
56*635a8641SAndroid Build Coastguard Worker   // If we're using glibc's allocator, the above functions will override
57*635a8641SAndroid Build Coastguard Worker   // malloc and friends and make them die on out of memory.
58*635a8641SAndroid Build Coastguard Worker 
59*635a8641SAndroid Build Coastguard Worker #if BUILDFLAG(USE_ALLOCATOR_SHIM)
60*635a8641SAndroid Build Coastguard Worker   allocator::SetCallNewHandlerOnMallocFailure(true);
61*635a8641SAndroid Build Coastguard Worker #elif defined(USE_TCMALLOC)
62*635a8641SAndroid Build Coastguard Worker   // For tcmalloc, we need to tell it to behave like new.
63*635a8641SAndroid Build Coastguard Worker   tc_set_new_mode(1);
64*635a8641SAndroid Build Coastguard Worker #endif
65*635a8641SAndroid Build Coastguard Worker }
66*635a8641SAndroid Build Coastguard Worker 
67*635a8641SAndroid Build Coastguard Worker // NOTE: This is not the only version of this function in the source:
68*635a8641SAndroid Build Coastguard Worker // the setuid sandbox (in process_util_linux.c, in the sandbox source)
69*635a8641SAndroid Build Coastguard Worker // also has its own C version.
AdjustOOMScore(ProcessId process,int score)70*635a8641SAndroid Build Coastguard Worker bool AdjustOOMScore(ProcessId process, int score) {
71*635a8641SAndroid Build Coastguard Worker   if (score < 0 || score > kMaxOomScore)
72*635a8641SAndroid Build Coastguard Worker     return false;
73*635a8641SAndroid Build Coastguard Worker 
74*635a8641SAndroid Build Coastguard Worker   FilePath oom_path(internal::GetProcPidDir(process));
75*635a8641SAndroid Build Coastguard Worker 
76*635a8641SAndroid Build Coastguard Worker   // Attempt to write the newer oom_score_adj file first.
77*635a8641SAndroid Build Coastguard Worker   FilePath oom_file = oom_path.AppendASCII("oom_score_adj");
78*635a8641SAndroid Build Coastguard Worker   if (PathExists(oom_file)) {
79*635a8641SAndroid Build Coastguard Worker     std::string score_str = IntToString(score);
80*635a8641SAndroid Build Coastguard Worker     DVLOG(1) << "Adjusting oom_score_adj of " << process << " to "
81*635a8641SAndroid Build Coastguard Worker              << score_str;
82*635a8641SAndroid Build Coastguard Worker     int score_len = static_cast<int>(score_str.length());
83*635a8641SAndroid Build Coastguard Worker     return (score_len == WriteFile(oom_file, score_str.c_str(), score_len));
84*635a8641SAndroid Build Coastguard Worker   }
85*635a8641SAndroid Build Coastguard Worker 
86*635a8641SAndroid Build Coastguard Worker   // If the oom_score_adj file doesn't exist, then we write the old
87*635a8641SAndroid Build Coastguard Worker   // style file and translate the oom_adj score to the range 0-15.
88*635a8641SAndroid Build Coastguard Worker   oom_file = oom_path.AppendASCII("oom_adj");
89*635a8641SAndroid Build Coastguard Worker   if (PathExists(oom_file)) {
90*635a8641SAndroid Build Coastguard Worker     // Max score for the old oom_adj range.  Used for conversion of new
91*635a8641SAndroid Build Coastguard Worker     // values to old values.
92*635a8641SAndroid Build Coastguard Worker     const int kMaxOldOomScore = 15;
93*635a8641SAndroid Build Coastguard Worker 
94*635a8641SAndroid Build Coastguard Worker     int converted_score = score * kMaxOldOomScore / kMaxOomScore;
95*635a8641SAndroid Build Coastguard Worker     std::string score_str = IntToString(converted_score);
96*635a8641SAndroid Build Coastguard Worker     DVLOG(1) << "Adjusting oom_adj of " << process << " to " << score_str;
97*635a8641SAndroid Build Coastguard Worker     int score_len = static_cast<int>(score_str.length());
98*635a8641SAndroid Build Coastguard Worker     return (score_len == WriteFile(oom_file, score_str.c_str(), score_len));
99*635a8641SAndroid Build Coastguard Worker   }
100*635a8641SAndroid Build Coastguard Worker 
101*635a8641SAndroid Build Coastguard Worker   return false;
102*635a8641SAndroid Build Coastguard Worker }
103*635a8641SAndroid Build Coastguard Worker 
UncheckedMalloc(size_t size,void ** result)104*635a8641SAndroid Build Coastguard Worker bool UncheckedMalloc(size_t size, void** result) {
105*635a8641SAndroid Build Coastguard Worker #if BUILDFLAG(USE_ALLOCATOR_SHIM)
106*635a8641SAndroid Build Coastguard Worker   *result = allocator::UncheckedAlloc(size);
107*635a8641SAndroid Build Coastguard Worker #elif defined(MEMORY_TOOL_REPLACES_ALLOCATOR) || \
108*635a8641SAndroid Build Coastguard Worker     (!defined(LIBC_GLIBC) && !defined(USE_TCMALLOC))
109*635a8641SAndroid Build Coastguard Worker   *result = malloc(size);
110*635a8641SAndroid Build Coastguard Worker #elif defined(LIBC_GLIBC) && !defined(USE_TCMALLOC)
111*635a8641SAndroid Build Coastguard Worker   *result = __libc_malloc(size);
112*635a8641SAndroid Build Coastguard Worker #elif defined(USE_TCMALLOC)
113*635a8641SAndroid Build Coastguard Worker   *result = tc_malloc_skip_new_handler(size);
114*635a8641SAndroid Build Coastguard Worker #endif
115*635a8641SAndroid Build Coastguard Worker   return *result != nullptr;
116*635a8641SAndroid Build Coastguard Worker }
117*635a8641SAndroid Build Coastguard Worker 
118*635a8641SAndroid Build Coastguard Worker }  // namespace base
119