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