From 1d6c40a6698d271517e5b333f2d0dd4459913884 Mon Sep 17 00:00:00 2001 From: riddle_hsu Date: Thu, 31 Jul 2014 00:18:00 +0800 Subject: [PATCH] Prevent system server dump stuck by pipe buffer full. Symptom: Watchdog timeout during dumping db info. Root Cause: When the caller is system server, this invocation is not IPC that means it is not asynchronous, it will need writer has written all data to finish. But pipe has 16*4KB buffer limit, if no reader consumes the data, it will keep waiting. Solution: Check if caller is system server, then use another thread to write so reader could consume the data in buffer. Change-Id: I4bf80fd645cc9396f51ffc0eb27fb895756c1dcf --- core/java/android/app/ActivityThread.java | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index c931d79bdaa69..36fdeb905db7d 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1061,14 +1061,29 @@ public final class ActivityThread { WindowManagerGlobal.getInstance().dumpGfxInfo(fd); } - @Override - public void dumpDbInfo(FileDescriptor fd, String[] args) { + private void dumpDatabaseInfo(FileDescriptor fd, String[] args) { PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd)); PrintWriterPrinter printer = new PrintWriterPrinter(pw); SQLiteDebug.dump(printer, args); pw.flush(); } + @Override + public void dumpDbInfo(final FileDescriptor fd, final String[] args) { + if (mSystemThread) { + // Ensure this invocation is asynchronous to prevent + // writer waiting due to buffer cannot be consumed. + AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() { + @Override + public void run() { + dumpDatabaseInfo(fd, args); + } + }); + } else { + dumpDatabaseInfo(fd, args); + } + } + @Override public void unstableProviderDied(IBinder provider) { sendMessage(H.UNSTABLE_PROVIDER_DIED, provider);