summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Elliott Hughes <enh@google.com> 2020-07-14 15:53:51 -0700
committer Elliott Hughes <enh@google.com> 2020-07-17 21:15:07 +0000
commit6e75720db31f7312fd0443004563a2a9ccf4318c (patch)
treedfc12424a2c4a8028e9315d37f49799ef3fa9d41
parent65530b7549b5cd23d7b53e9611a05f6b1d969a1f (diff)
Remove the watchdog's fd tracker.
The existence of both fdtrack and the older OpenFdMonitor is confusing to partners, and not obviously useful because the fdtrack limit is so much lower than the OpenFdMonitor limit (now that the default RLIMIT_NOFILE is 32Ki). Bug: https://issuetracker.google.com/161199049 Test: builds Change-Id: I86436f287d0e25d1dfae95b915beb78c88dccce2 Merged-In: I86436f287d0e25d1dfae95b915beb78c88dccce2
-rw-r--r--services/core/java/com/android/server/Watchdog.java157
1 files changed, 22 insertions, 135 deletions
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 5f9d1d801441..25c8a3e6eafb 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -23,7 +23,6 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.hidl.manager.V1_0.IServiceManager;
import android.os.Binder;
-import android.os.Build;
import android.os.Debug;
import android.os.Handler;
import android.os.IPowerManager;
@@ -32,10 +31,6 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.system.OsConstants;
-import android.system.StructRlimit;
import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
@@ -48,13 +43,8 @@ import com.android.server.wm.SurfaceAnimationThread;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.HashSet;
import java.util.List;
@@ -132,7 +122,6 @@ public class Watchdog extends Thread {
int mPhonePid;
IActivityController mController;
boolean mAllowRestart = true;
- final OpenFdMonitor mOpenFdMonitor;
/**
* Used for checking status of handle threads and scheduling monitor callbacks.
@@ -337,8 +326,6 @@ public class Watchdog extends Thread {
// Initialize monitor for Binder threads.
addMonitor(new BinderThreadMonitor());
- mOpenFdMonitor = OpenFdMonitor.create();
-
// See the notes on DEFAULT_TIMEOUT.
assert DB ||
DEFAULT_TIMEOUT > ZygoteConnectionConstants.WRAPPED_PID_TIMEOUT_MILLIS;
@@ -560,41 +547,31 @@ public class Watchdog extends Thread {
timeout = CHECK_INTERVAL - (SystemClock.uptimeMillis() - start);
}
- boolean fdLimitTriggered = false;
- if (mOpenFdMonitor != null) {
- fdLimitTriggered = mOpenFdMonitor.monitor();
- }
-
- if (!fdLimitTriggered) {
- final int waitState = evaluateCheckerCompletionLocked();
- if (waitState == COMPLETED) {
- // The monitors have returned; reset
- waitedHalf = false;
- continue;
- } else if (waitState == WAITING) {
- // still waiting but within their configured intervals; back off and recheck
- continue;
- } else if (waitState == WAITED_HALF) {
- if (!waitedHalf) {
- Slog.i(TAG, "WAITED_HALF");
- // We've waited half the deadlock-detection interval. Pull a stack
- // trace and wait another half.
- ArrayList<Integer> pids = new ArrayList<Integer>();
- pids.add(Process.myPid());
- ActivityManagerService.dumpStackTraces(pids, null, null,
+ final int waitState = evaluateCheckerCompletionLocked();
+ if (waitState == COMPLETED) {
+ // The monitors have returned; reset
+ waitedHalf = false;
+ continue;
+ } else if (waitState == WAITING) {
+ // still waiting but within their configured intervals; back off and recheck
+ continue;
+ } else if (waitState == WAITED_HALF) {
+ if (!waitedHalf) {
+ Slog.i(TAG, "WAITED_HALF");
+ // We've waited half the deadlock-detection interval. Pull a stack
+ // trace and wait another half.
+ ArrayList<Integer> pids = new ArrayList<Integer>();
+ pids.add(Process.myPid());
+ ActivityManagerService.dumpStackTraces(pids, null, null,
getInterestingNativePids());
- waitedHalf = true;
- }
- continue;
+ waitedHalf = true;
}
-
- // something is overdue!
- blockedCheckers = getBlockedCheckersLocked();
- subject = describeCheckersLocked(blockedCheckers);
- } else {
- blockedCheckers = Collections.emptyList();
- subject = "Open FD high water mark reached";
+ continue;
}
+
+ // something is overdue!
+ blockedCheckers = getBlockedCheckersLocked();
+ subject = describeCheckersLocked(blockedCheckers);
allowRestart = mAllowRestart;
}
@@ -688,94 +665,4 @@ public class Watchdog extends Thread {
Slog.w(TAG, "Failed to write to /proc/sysrq-trigger", e);
}
}
-
- public static final class OpenFdMonitor {
- /**
- * Number of FDs below the soft limit that we trigger a runtime restart at. This was
- * chosen arbitrarily, but will need to be at least 6 in order to have a sufficient number
- * of FDs in reserve to complete a dump.
- */
- private static final int FD_HIGH_WATER_MARK = 12;
-
- private final File mDumpDir;
- private final File mFdHighWaterMark;
-
- public static OpenFdMonitor create() {
- // Only run the FD monitor on debuggable builds (such as userdebug and eng builds).
- if (!Build.IS_DEBUGGABLE) {
- return null;
- }
-
- final StructRlimit rlimit;
- try {
- rlimit = android.system.Os.getrlimit(OsConstants.RLIMIT_NOFILE);
- } catch (ErrnoException errno) {
- Slog.w(TAG, "Error thrown from getrlimit(RLIMIT_NOFILE)", errno);
- return null;
- }
-
- // The assumption we're making here is that FD numbers are allocated (more or less)
- // sequentially, which is currently (and historically) true since open is currently
- // specified to always return the lowest-numbered non-open file descriptor for the
- // current process.
- //
- // We do this to avoid having to enumerate the contents of /proc/self/fd in order to
- // count the number of descriptors open in the process.
- final File fdThreshold = new File("/proc/self/fd/" + (rlimit.rlim_cur - FD_HIGH_WATER_MARK));
- return new OpenFdMonitor(new File("/data/anr"), fdThreshold);
- }
-
- OpenFdMonitor(File dumpDir, File fdThreshold) {
- mDumpDir = dumpDir;
- mFdHighWaterMark = fdThreshold;
- }
-
- /**
- * Dumps open file descriptors and their full paths to a temporary file in {@code mDumpDir}.
- */
- private void dumpOpenDescriptors() {
- // We cannot exec lsof to get more info about open file descriptors because a newly
- // forked process will not have the permissions to readlink. Instead list all open
- // descriptors from /proc/pid/fd and resolve them.
- List<String> dumpInfo = new ArrayList<>();
- String fdDirPath = String.format("/proc/%d/fd/", Process.myPid());
- File[] fds = new File(fdDirPath).listFiles();
- if (fds == null) {
- dumpInfo.add("Unable to list " + fdDirPath);
- } else {
- for (File f : fds) {
- String fdSymLink = f.getAbsolutePath();
- String resolvedPath = "";
- try {
- resolvedPath = Os.readlink(fdSymLink);
- } catch (ErrnoException ex) {
- resolvedPath = ex.getMessage();
- }
- dumpInfo.add(fdSymLink + "\t" + resolvedPath);
- }
- }
-
- // Dump the fds & paths to a temp file.
- try {
- File dumpFile = File.createTempFile("anr_fd_", "", mDumpDir);
- Path out = Paths.get(dumpFile.getAbsolutePath());
- Files.write(out, dumpInfo, StandardCharsets.UTF_8);
- } catch (IOException ex) {
- Slog.w(TAG, "Unable to write open descriptors to file: " + ex);
- }
- }
-
- /**
- * @return {@code true} if the high water mark was breached and a dump was written,
- * {@code false} otherwise.
- */
- public boolean monitor() {
- if (mFdHighWaterMark.exists()) {
- dumpOpenDescriptors();
- return true;
- }
-
- return false;
- }
- }
}