Some debugging support.
- New feature to "am monitor" to have it automatically launch gdbserv for you when a crash/ANR happens, and tell you how to run the client. - Update dumpstate to match new location of binder debug logs - Various commented out logs that are being used to track down issues. Change-Id: Ia5dd0cd2df983a1fc6be697642a4590aa02a26a5
This commit is contained in:
@ -35,9 +35,7 @@ import android.util.AndroidException;
|
|||||||
import android.view.IWindowManager;
|
import android.view.IWindowManager;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
@ -433,6 +431,8 @@ public class Am {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MyActivityController extends IActivityController.Stub {
|
class MyActivityController extends IActivityController.Stub {
|
||||||
|
final String mGdbPort;
|
||||||
|
|
||||||
static final int STATE_NORMAL = 0;
|
static final int STATE_NORMAL = 0;
|
||||||
static final int STATE_CRASHED = 1;
|
static final int STATE_CRASHED = 1;
|
||||||
static final int STATE_EARLY_ANR = 2;
|
static final int STATE_EARLY_ANR = 2;
|
||||||
@ -454,6 +454,14 @@ public class Am {
|
|||||||
|
|
||||||
int mResult;
|
int mResult;
|
||||||
|
|
||||||
|
Process mGdbProcess;
|
||||||
|
Thread mGdbThread;
|
||||||
|
boolean mGotGdbPrint;
|
||||||
|
|
||||||
|
MyActivityController(String gdbPort) {
|
||||||
|
mGdbPort = gdbPort;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean activityResuming(String pkg) throws RemoteException {
|
public boolean activityResuming(String pkg) throws RemoteException {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
@ -483,7 +491,7 @@ public class Am {
|
|||||||
System.out.println("stack:");
|
System.out.println("stack:");
|
||||||
System.out.print(stackTrace);
|
System.out.print(stackTrace);
|
||||||
System.out.println("#");
|
System.out.println("#");
|
||||||
int result = waitControllerLocked(STATE_CRASHED);
|
int result = waitControllerLocked(pid, STATE_CRASHED);
|
||||||
return result == RESULT_CRASH_KILL ? false : true;
|
return result == RESULT_CRASH_KILL ? false : true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -496,7 +504,7 @@ public class Am {
|
|||||||
System.out.println("processName: " + processName);
|
System.out.println("processName: " + processName);
|
||||||
System.out.println("processPid: " + pid);
|
System.out.println("processPid: " + pid);
|
||||||
System.out.println("annotation: " + annotation);
|
System.out.println("annotation: " + annotation);
|
||||||
int result = waitControllerLocked(STATE_EARLY_ANR);
|
int result = waitControllerLocked(pid, STATE_EARLY_ANR);
|
||||||
if (result == RESULT_EARLY_ANR_KILL) return -1;
|
if (result == RESULT_EARLY_ANR_KILL) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -512,14 +520,83 @@ public class Am {
|
|||||||
System.out.println("processStats:");
|
System.out.println("processStats:");
|
||||||
System.out.print(processStats);
|
System.out.print(processStats);
|
||||||
System.out.println("#");
|
System.out.println("#");
|
||||||
int result = waitControllerLocked(STATE_ANR);
|
int result = waitControllerLocked(pid, STATE_ANR);
|
||||||
if (result == RESULT_ANR_KILL) return -1;
|
if (result == RESULT_ANR_KILL) return -1;
|
||||||
if (result == RESULT_ANR_WAIT) return 1;
|
if (result == RESULT_ANR_WAIT) return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int waitControllerLocked(int state) {
|
void killGdbLocked() {
|
||||||
|
mGotGdbPrint = false;
|
||||||
|
if (mGdbProcess != null) {
|
||||||
|
System.out.println("Stopping gdbserver");
|
||||||
|
mGdbProcess.destroy();
|
||||||
|
mGdbProcess = null;
|
||||||
|
}
|
||||||
|
if (mGdbThread != null) {
|
||||||
|
mGdbThread.interrupt();
|
||||||
|
mGdbThread = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int waitControllerLocked(int pid, int state) {
|
||||||
|
if (mGdbPort != null) {
|
||||||
|
killGdbLocked();
|
||||||
|
|
||||||
|
try {
|
||||||
|
System.out.println("Starting gdbserver on port " + mGdbPort);
|
||||||
|
System.out.println("Do the following:");
|
||||||
|
System.out.println(" adb forward tcp:" + mGdbPort + " tcp:" + mGdbPort);
|
||||||
|
System.out.println(" gdbclient app_process :" + mGdbPort);
|
||||||
|
|
||||||
|
mGdbProcess = Runtime.getRuntime().exec(new String[] {
|
||||||
|
"gdbserver", ":" + mGdbPort, "--attach", Integer.toString(pid)
|
||||||
|
});
|
||||||
|
final InputStreamReader converter = new InputStreamReader(
|
||||||
|
mGdbProcess.getInputStream());
|
||||||
|
mGdbThread = new Thread() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
BufferedReader in = new BufferedReader(converter);
|
||||||
|
String line;
|
||||||
|
int count = 0;
|
||||||
|
while (true) {
|
||||||
|
synchronized (MyActivityController.this) {
|
||||||
|
if (mGdbThread == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (count == 2) {
|
||||||
|
mGotGdbPrint = true;
|
||||||
|
MyActivityController.this.notifyAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
line = in.readLine();
|
||||||
|
if (line == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
System.out.println("GDB: " + line);
|
||||||
|
count++;
|
||||||
|
} catch (IOException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
mGdbThread.start();
|
||||||
|
|
||||||
|
// Stupid waiting for .5s. Doesn't matter if we end early.
|
||||||
|
try {
|
||||||
|
this.wait(500);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("Failure starting gdbserver: " + e);
|
||||||
|
killGdbLocked();
|
||||||
|
}
|
||||||
|
}
|
||||||
mState = state;
|
mState = state;
|
||||||
System.out.println("");
|
System.out.println("");
|
||||||
printMessageForState();
|
printMessageForState();
|
||||||
@ -531,6 +608,8 @@ public class Am {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
killGdbLocked();
|
||||||
|
|
||||||
return mResult;
|
return mResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -632,7 +711,19 @@ public class Am {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void runMonitor() throws Exception {
|
private void runMonitor() throws Exception {
|
||||||
MyActivityController controller = new MyActivityController();
|
String opt;
|
||||||
|
String gdbPort = null;
|
||||||
|
while ((opt=nextOption()) != null) {
|
||||||
|
if (opt.equals("--gdb")) {
|
||||||
|
gdbPort = nextArgRequired();
|
||||||
|
} else {
|
||||||
|
System.err.println("Error: Unknown option: " + opt);
|
||||||
|
showUsage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MyActivityController controller = new MyActivityController(gdbPort);
|
||||||
controller.run();
|
controller.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -806,7 +897,8 @@ public class Am {
|
|||||||
" start profiling: am profile <PROCESS> start <FILE>\n" +
|
" start profiling: am profile <PROCESS> start <FILE>\n" +
|
||||||
" stop profiling: am profile <PROCESS> stop\n" +
|
" stop profiling: am profile <PROCESS> stop\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
" start monitoring: am monitor\n" +
|
" start monitoring: am monitor [--gdb <port>]\n" +
|
||||||
|
" --gdb: start gdbserv on the given port at crash/ANR\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
" <INTENT> specifications include these flags:\n" +
|
" <INTENT> specifications include these flags:\n" +
|
||||||
" [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]\n" +
|
" [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]\n" +
|
||||||
|
@ -122,11 +122,11 @@ static void dumpstate() {
|
|||||||
run_command("PROCESSES AND THREADS", 10, "ps", "-t", "-p", "-P", NULL);
|
run_command("PROCESSES AND THREADS", 10, "ps", "-t", "-p", "-P", NULL);
|
||||||
run_command("LIBRANK", 10, "librank", NULL);
|
run_command("LIBRANK", 10, "librank", NULL);
|
||||||
|
|
||||||
dump_file("BINDER FAILED TRANSACTION LOG", "/proc/binder/failed_transaction_log");
|
dump_file("BINDER FAILED TRANSACTION LOG", "/sys/kernel/debug/binder/failed_transaction_log");
|
||||||
dump_file("BINDER TRANSACTION LOG", "/proc/binder/transaction_log");
|
dump_file("BINDER TRANSACTION LOG", "/sys/kernel/debug/binder/transaction_log");
|
||||||
dump_file("BINDER TRANSACTIONS", "/proc/binder/transactions");
|
dump_file("BINDER TRANSACTIONS", "/sys/kernel/debug/binder/transactions");
|
||||||
dump_file("BINDER STATS", "/proc/binder/stats");
|
dump_file("BINDER STATS", "/sys/kernel/debug/binder/stats");
|
||||||
run_command("BINDER PROCESS STATE", 10, "sh", "-c", "cat /proc/binder/proc/*");
|
dump_file("BINDER STATE", "/sys/kernel/debug/binder/state");
|
||||||
|
|
||||||
run_command("FILESYSTEMS & FREE SPACE", 10, "df", NULL);
|
run_command("FILESYSTEMS & FREE SPACE", 10, "df", NULL);
|
||||||
|
|
||||||
|
@ -2637,6 +2637,7 @@ public final class ViewRoot extends Handler implements ViewParent,
|
|||||||
if (DBG) Log.d(TAG, "WindowLayout in layoutWindow:" + params);
|
if (DBG) Log.d(TAG, "WindowLayout in layoutWindow:" + params);
|
||||||
}
|
}
|
||||||
mPendingConfiguration.seq = 0;
|
mPendingConfiguration.seq = 0;
|
||||||
|
//Log.d(TAG, ">>>>>> CALLING relayout");
|
||||||
int relayoutResult = sWindowSession.relayout(
|
int relayoutResult = sWindowSession.relayout(
|
||||||
mWindow, params,
|
mWindow, params,
|
||||||
(int) (mView.mMeasuredWidth * appScale + 0.5f),
|
(int) (mView.mMeasuredWidth * appScale + 0.5f),
|
||||||
@ -2644,6 +2645,7 @@ public final class ViewRoot extends Handler implements ViewParent,
|
|||||||
viewVisibility, insetsPending, mWinFrame,
|
viewVisibility, insetsPending, mWinFrame,
|
||||||
mPendingContentInsets, mPendingVisibleInsets,
|
mPendingContentInsets, mPendingVisibleInsets,
|
||||||
mPendingConfiguration, mSurface);
|
mPendingConfiguration, mSurface);
|
||||||
|
//Log.d(TAG, "<<<<<< BACK FROM relayout");
|
||||||
if (restore) {
|
if (restore) {
|
||||||
params.restore();
|
params.restore();
|
||||||
}
|
}
|
||||||
|
@ -517,12 +517,26 @@ status_t IPCThreadState::transact(int32_t handle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & TF_ONE_WAY) == 0) {
|
if ((flags & TF_ONE_WAY) == 0) {
|
||||||
|
#if 0
|
||||||
|
if (code == 4) { // relayout
|
||||||
|
LOGI(">>>>>> CALLING transaction 4");
|
||||||
|
} else {
|
||||||
|
LOGI(">>>>>> CALLING transaction %d", code);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (reply) {
|
if (reply) {
|
||||||
err = waitForResponse(reply);
|
err = waitForResponse(reply);
|
||||||
} else {
|
} else {
|
||||||
Parcel fakeReply;
|
Parcel fakeReply;
|
||||||
err = waitForResponse(&fakeReply);
|
err = waitForResponse(&fakeReply);
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
|
if (code == 4) { // relayout
|
||||||
|
LOGI("<<<<<< RETURNING transaction 4");
|
||||||
|
} else {
|
||||||
|
LOGI("<<<<<< RETURNING transaction %d", code);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
IF_LOG_TRANSACTIONS() {
|
IF_LOG_TRANSACTIONS() {
|
||||||
TextOutput::Bundle _b(alog);
|
TextOutput::Bundle _b(alog);
|
||||||
|
@ -5679,9 +5679,12 @@ public class WindowManagerService extends IWindowManager.Stub
|
|||||||
int requestedWidth, int requestedHeight, int viewFlags,
|
int requestedWidth, int requestedHeight, int viewFlags,
|
||||||
boolean insetsPending, Rect outFrame, Rect outContentInsets,
|
boolean insetsPending, Rect outFrame, Rect outContentInsets,
|
||||||
Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
|
Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
|
||||||
return relayoutWindow(this, window, attrs,
|
//Log.d(TAG, ">>>>>> ENTERED relayout from " + Binder.getCallingPid());
|
||||||
|
int res = relayoutWindow(this, window, attrs,
|
||||||
requestedWidth, requestedHeight, viewFlags, insetsPending,
|
requestedWidth, requestedHeight, viewFlags, insetsPending,
|
||||||
outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
|
outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
|
||||||
|
//Log.d(TAG, "<<<<<< EXITING relayout to " + Binder.getCallingPid());
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTransparentRegion(IWindow window, Region region) {
|
public void setTransparentRegion(IWindow window, Region region) {
|
||||||
|
Reference in New Issue
Block a user