From 2de2ade387774effee209a1498f16babab81e4ee Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Wed, 28 Mar 2018 13:16:01 -0700 Subject: [PATCH] adbd: increase oom_score_adj for `adb shell` Previously, processes started via `adb shell` have an oom_score_adj of -1000, making them invisible to the oom killer. This makes running a process that consumes all memory (e.g. by leaking in a loop) lead to the entire rest of the system (including adbd, because of bad heuristics in the kernel) being oom killed before getting to it. Bug: http://b/63143027 Test: `adb shell cat /proc/self/oom_score_adj` with adb root Change-Id: I59111134e36dc271adf4c1dd4bd4400d4fe6aee0 --- adb/daemon/shell_service.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/adb/daemon/shell_service.cpp b/adb/daemon/shell_service.cpp index 17c7ebaa0..da1222bc7 100644 --- a/adb/daemon/shell_service.cpp +++ b/adb/daemon/shell_service.cpp @@ -334,6 +334,15 @@ bool Subprocess::ForkAndExec(std::string* error) { // processes, so we need to manually reset back to SIG_DFL here (http://b/35209888). signal(SIGPIPE, SIG_DFL); + // Increase oom_score_adj from -1000, so that the child is visible to the OOM-killer. + // Don't treat failure as an error, because old Android kernels explicitly disabled this. + int oom_score_adj_fd = adb_open("/proc/self/oom_score_adj", O_WRONLY | O_CLOEXEC); + if (oom_score_adj_fd != -1) { + const char* oom_score_adj_value = "-950"; + TEMP_FAILURE_RETRY( + adb_write(oom_score_adj_fd, oom_score_adj_value, strlen(oom_score_adj_value))); + } + if (command_.empty()) { execle(_PATH_BSHELL, _PATH_BSHELL, "-", nullptr, cenv.data()); } else {