1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/process/memory.h"
11 #include "base/allocator/allocator_shim.h"
12 #include "base/allocator/buildflags.h"
13 #include "base/files/file_path.h"
14 #include "base/files/file_util.h"
15 #include "base/logging.h"
16 #include "base/process/internal_linux.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "build/build_config.h"
20 #if defined(USE_TCMALLOC)
21 #include "third_party/tcmalloc/chromium/src/config.h"
22 #include "third_party/tcmalloc/chromium/src/gperftools/tcmalloc.h"
27 size_t g_oom_size = 0U;
31 void OnNoMemorySize(size_t size) {
35 LOG(FATAL) << "Out of memory, size = " << size;
36 LOG(FATAL) << "Out of memory.";
45 void EnableTerminationOnHeapCorruption() {
46 // On Linux, there nothing to do AFAIK.
49 void EnableTerminationOnOutOfMemory() {
50 // Set the new-out of memory handler.
51 std::set_new_handler(&OnNoMemory);
52 // If we're using glibc's allocator, the above functions will override
53 // malloc and friends and make them die on out of memory.
55 #if BUILDFLAG(USE_ALLOCATOR_SHIM)
56 allocator::SetCallNewHandlerOnMallocFailure(true);
57 #elif defined(USE_TCMALLOC)
58 // For tcmalloc, we need to tell it to behave like new.
63 // NOTE: This is not the only version of this function in the source:
64 // the setuid sandbox (in process_util_linux.c, in the sandbox source)
65 // also has its own C version.
66 bool AdjustOOMScore(ProcessId process, int score) {
67 if (score < 0 || score > kMaxOomScore)
70 FilePath oom_path(internal::GetProcPidDir(process));
72 // Attempt to write the newer oom_score_adj file first.
73 FilePath oom_file = oom_path.AppendASCII("oom_score_adj");
74 if (PathExists(oom_file)) {
75 std::string score_str = IntToString(score);
76 DVLOG(1) << "Adjusting oom_score_adj of " << process << " to "
78 int score_len = static_cast<int>(score_str.length());
79 return (score_len == WriteFile(oom_file, score_str.c_str(), score_len));
82 // If the oom_score_adj file doesn't exist, then we write the old
83 // style file and translate the oom_adj score to the range 0-15.
84 oom_file = oom_path.AppendASCII("oom_adj");
85 if (PathExists(oom_file)) {
86 // Max score for the old oom_adj range. Used for conversion of new
87 // values to old values.
88 const int kMaxOldOomScore = 15;
90 int converted_score = score * kMaxOldOomScore / kMaxOomScore;
91 std::string score_str = IntToString(converted_score);
92 DVLOG(1) << "Adjusting oom_adj of " << process << " to " << score_str;
93 int score_len = static_cast<int>(score_str.length());
94 return (score_len == WriteFile(oom_file, score_str.c_str(), score_len));
100 bool UncheckedMalloc(size_t size, void** result) {
101 #if BUILDFLAG(USE_ALLOCATOR_SHIM)
102 *result = allocator::UncheckedAlloc(size);
103 // FIXME: Since we do not use tcmalloc for chromium-efl in a consistent
104 // manner, we should either fix it or disable tcmalloc.
105 #elif defined(MEMORY_TOOL_REPLACES_ALLOCATOR) || \
106 (!defined(LIBC_GLIBC) && !defined(USE_TCMALLOC) || defined(USE_EFL))
107 *result = malloc(size);
108 #elif defined(LIBC_GLIBC) && !defined(USE_TCMALLOC)
109 *result = __libc_malloc(size);
110 #elif defined(USE_TCMALLOC)
111 *result = tc_malloc_skip_new_handler(size);
113 return *result != nullptr;