* commit '6ab3ea5f48abfd777d5bd18d92acc3bc766f78ce': Watchdog: Improvement of debuggability
This commit is contained in:
committed by
Android Git Automerger
commit
4698e36db6
@@ -26,6 +26,7 @@ import android.content.ContentResolver;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Debug;
|
import android.os.Debug;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
@@ -39,6 +40,8 @@ import android.util.Log;
|
|||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
|
||||||
@@ -429,11 +432,10 @@ public class Watchdog extends Thread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If we got here, that means that the system is most likely hung.
|
// If we got here, that means that the system is most likely hung.
|
||||||
// First collect stack traces from all threads of the system process.
|
|
||||||
// Then kill this process so that the system will restart.
|
|
||||||
|
|
||||||
final String name = (mCurrentMonitor != null) ?
|
final String name = (mCurrentMonitor != null) ?
|
||||||
mCurrentMonitor.getClass().getName() : "null";
|
mCurrentMonitor.getClass().getName() : "null";
|
||||||
|
Slog.w(TAG, "WATCHDOG PROBLEM IN SYSTEM SERVER: " + name);
|
||||||
EventLog.writeEvent(EventLogTags.WATCHDOG, name);
|
EventLog.writeEvent(EventLogTags.WATCHDOG, name);
|
||||||
|
|
||||||
ArrayList<Integer> pids = new ArrayList<Integer>();
|
ArrayList<Integer> pids = new ArrayList<Integer>();
|
||||||
@@ -468,11 +470,15 @@ public class Watchdog extends Thread {
|
|||||||
dropboxThread.join(2000); // wait up to 2 seconds for it to return.
|
dropboxThread.join(2000); // wait up to 2 seconds for it to return.
|
||||||
} catch (InterruptedException ignored) {}
|
} catch (InterruptedException ignored) {}
|
||||||
|
|
||||||
// Only kill the process if the debugger is not attached.
|
// Only kill/crash the process if the debugger is not attached.
|
||||||
if (!Debug.isDebuggerConnected()) {
|
if (!Debug.isDebuggerConnected()) {
|
||||||
Slog.w(TAG, "*** WATCHDOG KILLING SYSTEM PROCESS: " + name);
|
Slog.w(TAG, "*** WATCHDOG KILLING SYSTEM PROCESS: " + name);
|
||||||
Process.killProcess(Process.myPid());
|
if (!Build.TYPE.equals("user")) {
|
||||||
System.exit(10);
|
forceCrashDump();
|
||||||
|
} else {
|
||||||
|
Process.killProcess(Process.myPid());
|
||||||
|
System.exit(10);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Slog.w(TAG, "Debugger connected: Watchdog is *not* killing the system process");
|
Slog.w(TAG, "Debugger connected: Watchdog is *not* killing the system process");
|
||||||
}
|
}
|
||||||
@@ -481,6 +487,50 @@ public class Watchdog extends Thread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void forceCrashDump() {
|
||||||
|
/* Sync file system to flash the data which is written just before the
|
||||||
|
* crash.
|
||||||
|
*/
|
||||||
|
java.lang.Process p = null;
|
||||||
|
try {
|
||||||
|
p = Runtime.getRuntime().exec("sync");
|
||||||
|
if (p != null) {
|
||||||
|
// It is not necessary to check the exit code, here.
|
||||||
|
// 'sync' command always succeeds, and this function returns 0.
|
||||||
|
p.waitFor();
|
||||||
|
} else {
|
||||||
|
Slog.e(TAG, "Failed to execute 'sync' command. (no process handle)");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// This code is an emergency path to crash MUT. The system already
|
||||||
|
// caused fatal error, and then calls this function to create a
|
||||||
|
// crash dump. This function must run the code below to force a
|
||||||
|
// crash, even if the sync command failed.
|
||||||
|
// Therefore, ignore all exceptions, here.
|
||||||
|
Slog.e(TAG, "Failed to execute 'sync' command prior to forcing crash: " + e);
|
||||||
|
} finally {
|
||||||
|
if (p != null) {
|
||||||
|
p.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FileWriter out = null;
|
||||||
|
try {
|
||||||
|
out = new FileWriter("/proc/sysrq-trigger");
|
||||||
|
out.write("c");
|
||||||
|
} catch (IOException e) {
|
||||||
|
Slog.e(TAG, "Failed to write to sysrq-trigger while triggering crash: " + e);
|
||||||
|
} finally {
|
||||||
|
if (out != null) {
|
||||||
|
try {
|
||||||
|
out.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Slog.e(TAG, "Failed to close sysrq-trigger while triggering crash: " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private File dumpKernelStackTraces() {
|
private File dumpKernelStackTraces() {
|
||||||
String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
|
String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
|
||||||
if (tracesPath == null || tracesPath.length() == 0) {
|
if (tracesPath == null || tracesPath.length() == 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user