のねのBlog

パソコンの問題や、ソフトウェアの開発で起きた問題など書いていきます。よろしくお願いします^^。

アクティビティのスタックのダンプ(dump activity stack)

>adb shell dumpsys activity > activity.log

# ダンプログ出力元クラスは下記
# com.android.server.am.ActivityManagerService.dumpHistoryList
# (FileDescriptor, PrintWriter, List, String, String, boolean, boolean, boolean, String)

 >adb shell dumpsys activity -h
 Activity manager dump options:
  [-a] [-c] [-h] [cmd] ...
  cmd may be one of:
    a[ctivities]: activity stack state
    b[roadcasts] [PACKAGE_NAME]: broadcast state
    i[ntents] [PACKAGE_NAME]: pending intent state
    p[rocesses] [PACKAGE_NAME]: process state
    o[om]: out of memory management
    prov[iders] [COMP_SPEC ...]: content provider state
    provider [COMP_SPEC]: provider client-side state
    s[ervices] [COMP_SPEC ...]: service state
    service [COMP_SPEC]: service client-side state
    package [PACKAGE_NAME]: all state related to given package
    all: dump all activities
    top: dump the top activity
  cmd may also be a COMP_SPEC to dump activities.
  COMP_SPEC may be a component name (com.foo/.myApp),
    a partial substring in a component name, a
    hex object identifier.
  -a: include all available server state.
  -c: include client state.
   8565     @Override
   8566     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   8567         if (checkCallingPermission(android.Manifest.permission.DUMP)
   8568                 != PackageManager.PERMISSION_GRANTED) {
   8569             pw.println("Permission Denial: can't dump ActivityManager from from pid="
   8570                     + Binder.getCallingPid()
   8571                     + ", uid=" + Binder.getCallingUid()
   8572                     + " without permission "
   8573                     + android.Manifest.permission.DUMP);
   8574             return;
   8575         }
   8576 
   8577         boolean dumpAll = false;
   8578         boolean dumpClient = false;
   8579         String dumpPackage = null;
   8580 
   8581         int opti = 0;
   8582         while (opti < args.length) {
   8583             String opt = args[opti];
   8584             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   8585                 break;
   8586             }
   8587             opti++;
   8588             if ("-a".equals(opt)) {
   8589                 dumpAll = true;
   8590             } else if ("-c".equals(opt)) {
   8591                 dumpClient = true;
   8592             } else if ("-h".equals(opt)) {
   8593                 pw.println("Activity manager dump options:");
   8594                 pw.println("  [-a] [-c] [-h] [cmd] ...");
   8595                 pw.println("  cmd may be one of:");
   8596                 pw.println("    a[ctivities]: activity stack state");
   8597                 pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
   8598                 pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
   8599                 pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
   8600                 pw.println("    o[om]: out of memory management");
   8601                 pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
   8602                 pw.println("    provider [COMP_SPEC]: provider client-side state");
   8603                 pw.println("    s[ervices] [COMP_SPEC ...]: service state");
   8604                 pw.println("    service [COMP_SPEC]: service client-side state");
   8605                 pw.println("    package [PACKAGE_NAME]: all state related to given package");
   8606                 pw.println("    all: dump all activities");
   8607                 pw.println("    top: dump the top activity");
   8608                 pw.println("  cmd may also be a COMP_SPEC to dump activities.");
   8609                 pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
   8610                 pw.println("    a partial substring in a component name, a");
   8611                 pw.println("    hex object identifier.");
   8612                 pw.println("  -a: include all available server state.");
   8613                 pw.println("  -c: include client state.");
   8614                 return;
   8615             } else {
   8616                 pw.println("Unknown argument: " + opt + "; use -h for help");
   8617             }
   8618         }
   8619 
   8620         long origId = Binder.clearCallingIdentity();
   8621         boolean more = false;
   8622         // Is the caller requesting to dump a particular piece of data?
   8623         if (opti < args.length) {
   8624             String cmd = args[opti];
   8625             opti++;
   8626             if ("activities".equals(cmd) || "a".equals(cmd)) {
   8627                 synchronized (this) {
   8628                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); <====== ここ
   8629                 }
   8630             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {

 ActivityManagerServiceのmMainStackにアクセスできるのかな?

    160 public final class ActivityManagerService extends ActivityManagerNative
    161         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {

    279     public ActivityStack mMainStack;
  8794     boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   8795             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
   8796         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
   8797         pw.println("  Main stack:");
   8798         dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
   8799                 dumpPackage);
   8800         pw.println(" ");
   8801         pw.println("  Running activities (most recent first):");
   8802         dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
   8803                 dumpPackage);
   8804         if (mMainStack.mWaitingVisibleActivities.size() > 0) {
   8805             pw.println(" ");
   8806             pw.println("  Activities waiting for another to become visible:");
   8807             dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
   8808                     !dumpAll, false, dumpPackage);
   8809         }
   8810         if (mMainStack.mStoppingActivities.size() > 0) {
   8811             pw.println(" ");
   8812             pw.println("  Activities waiting to stop:");
   8813             dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
   8814                     !dumpAll, false, dumpPackage);
   8815         }
   8816         if (mMainStack.mGoingToSleepActivities.size() > 0) {
   8817             pw.println(" ");
   8818             pw.println("  Activities waiting to sleep:");
   8819             dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
   8820                     !dumpAll, false, dumpPackage);
   8821         }
   8822         if (mMainStack.mFinishingActivities.size() > 0) {
   8823             pw.println(" ");
   8824             pw.println("  Activities waiting to finish:");
   8825             dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
   8826                     !dumpAll, false, dumpPackage);
   8827         }
   8828 
   8829         pw.println(" ");
   8830         if (mMainStack.mPausingActivity != null) {
   8831             pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
   8832         }
   8833         pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
   8834         pw.println("  mFocusedActivity: " + mFocusedActivity);
   8835         if (dumpAll) {
   8836             pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
   8837             pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
   8838             pw.println("  mDismissKeyguardOnNextActivity: "
   8839                     + mMainStack.mDismissKeyguardOnNextActivity);
   8840         }
   8841 
   8842         if (mRecentTasks.size() > 0) {
   8843             pw.println();
   8844             pw.println("  Recent tasks:");
   8845 
   8846             final int N = mRecentTasks.size();
   8847             for (int i=0; i<N; i++) {
   8848                 TaskRecord tr = mRecentTasks.get(i);
   8849                 if (dumpPackage != null) {
   8850                     if (tr.realActivity == null ||
   8851                             !dumpPackage.equals(tr.realActivity)) {
   8852                         continue;
   8853                     }
   8854                 }
   8855                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
   8856                         pw.println(tr);
   8857                 if (dumpAll) {
   8858                     mRecentTasks.get(i).dump(pw, "    ");
   8859                 }
   8860             }
   8861         }
   8862 
   8863         if (dumpAll) {
   8864             pw.println(" ");
   8865             pw.println("  mCurTask: " + mCurTask);
   8866         }
   8867 
   8868         return true;
   8869     }
   9879     private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
   9880             String prefix, String label, boolean complete, boolean brief, boolean client,
   9881             String dumpPackage) {
   9882         TaskRecord lastTask = null;
   9883         boolean needNL = false;
   9884         final String innerPrefix = prefix + "      ";
   9885         final String[] args = new String[0];
   9886         for (int i=list.size()-1; i>=0; i--) {
   9887             final ActivityRecord r = (ActivityRecord)list.get(i);
   9888             if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
   9889                 continue;
   9890             }
   9891             final boolean full = !brief && (complete || !r.isInHistory());
   9892             if (needNL) {
   9893                 pw.println(" ");
   9894                 needNL = false;
   9895             }
   9896             if (lastTask != r.task) {
   9897                 lastTask = r.task;
   9898                 pw.print(prefix);
   9899                 pw.print(full ? "* " : "  ");
   9900                 pw.println(lastTask);
   9901                 if (full) {
   9902                     lastTask.dump(pw, prefix + "  ");
   9903                 } else if (complete) {
   9904                     // Complete + brief == give a summary.  Isn't that obvious?!?
   9905                     if (lastTask.intent != null) {
   9906                         pw.print(prefix); pw.print("  ");
   9907                                 pw.println(lastTask.intent.toInsecureStringWithClip());
   9908                     }
   9909                 }
   9910             }
   9911             pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
   9912             pw.print(" #"); pw.print(i); pw.print(": ");
   9913             pw.println(r);
   9914             if (full) {
   9915                 r.dump(pw, innerPrefix);
   9916             } else if (complete) {
   9917                 // Complete + brief == give a summary.  Isn't that obvious?!?
   9918                 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
   9919                 if (r.app != null) {
   9920                     pw.print(innerPrefix); pw.println(r.app);
   9921                 }
   9922             }
   9923             if (client && r.app != null && r.app.thread != null) {
   9924                 // flush anything that is already in the PrintWriter since the thread is going
   9925                 // to write to the file descriptor directly
   9926                 pw.flush();
   9927                 try {
   9928                     TransferPipe tp = new TransferPipe();
   9929                     try {
   9930                         r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
   9931                                 r.appToken, innerPrefix, args);
   9932                         // Short timeout, since blocking here can
   9933                         // deadlock with the application.
   9934                         tp.go(fd, 2000);
   9935                     } finally {
   9936                         tp.kill();
   9937                     }
   9938                 } catch (IOException e) {
   9939                     pw.println(innerPrefix + "Failure while dumping the activity: " + e);
   9940                 } catch (RemoteException e) {
   9941                     pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
   9942                 }
   9943                 needNL = true;
   9944             }
   9945         }
   9946     }
    821         public void dumpActivity(FileDescriptor fd, IBinder activitytoken,
    822                 String prefix, String[] args) {
    823             DumpComponentInfo data = new DumpComponentInfo();
    824             try {
    825                 data.fd = ParcelFileDescriptor.dup(fd);
    826                 data.token = activitytoken;
    827                 data.prefix = prefix;
    828                 data.args = args;
    829                 queueOrSendMessage(H.DUMP_ACTIVITY, data);
    830             } catch (IOException e) {
    831                 Slog.w(TAG, "dumpActivity failed", e);
    832             }
    833         }
   1186         public void handleMessage(Message msg) {
   1187             if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
   1188             switch (msg.what) {
 
   1365                 case DUMP_ACTIVITY:
   1366                     handleDumpActivity((DumpComponentInfo)msg.obj);
   1367                     break;
   2451     private void handleDumpActivity(DumpComponentInfo info) {
   2452         final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
   2453         try {
   2454             ActivityClientRecord r = mActivities.get(info.token);
   2455             if (r != null && r.activity != null) {
   2456                 PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd.getFileDescriptor()));
   2457                 r.activity.dump(info.prefix, info.fd.getFileDescriptor(), pw, info.args);
   2458                 pw.flush();
   2459             }
   2460         } finally {
   2461             IoUtils.closeQuietly(info.fd);
   2462             StrictMode.setThreadPolicy(oldPolicy);
   2463         }
   2464     }
   4709     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
   4710         writer.print(prefix); writer.print("Local Activity ");
   4711                 writer.print(Integer.toHexString(System.identityHashCode(this)));
   4712                 writer.println(" State:");
   4713         String innerPrefix = prefix + "  ";
   4714         writer.print(innerPrefix); writer.print("mResumed=");
   4715                 writer.print(mResumed); writer.print(" mStopped=");
   4716                 writer.print(mStopped); writer.print(" mFinished=");
   4717                 writer.println(mFinished);
   4718         writer.print(innerPrefix); writer.print("mLoadersStarted=");
   4719                 writer.println(mLoadersStarted);
   4720         writer.print(innerPrefix); writer.print("mChangingConfigurations=");
   4721                 writer.println(mChangingConfigurations);
   4722         writer.print(innerPrefix); writer.print("mCurrentConfig=");
   4723                 writer.println(mCurrentConfig);
   4724         if (mLoaderManager != null) {
   4725             writer.print(prefix); writer.print("Loader Manager ");
   4726                     writer.print(Integer.toHexString(System.identityHashCode(mLoaderManager)));
   4727                     writer.println(":");
   4728             mLoaderManager.dump(prefix + "  ", fd, writer, args);
   4729         }
   4730         mFragments.dump(prefix, fd, writer, args);
   4731     }