<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      初階技能:Android 應用異常如何豐富線索

      在我們容器虛擬化產品開發過程中,時長會遇到某些應用無法啟動或運行時異常崩潰的問題;讓應用行為信息豐富,則能還原應用異常發生過程,對我們快速分析問題至關重要。

      image

      在這里需要用到以下幾個開源工具:

      01. 舉個栗子

      我們在做應用容器時,嘗嘗會遇到應用進程崩潰,通過adb抓取的日志,卻只有很少的幾行日志,沒有其他任何信息,因此通過一些簡單的方式讓應用行為的痕跡還原,是我們第一步要做的事情。

      9402  9402 D AndroidRuntime: Shutting down VM
      9402  9402 I Process : Sending signal. PID: 9402 SIG: 9
      

      02. 打印退出痕跡

      通過攔截native函數,打印Java層的異常退出:

      import android.os;
      
      public class Process {
        
          /**
           * Returns the identifier of this process, which can be used with
           * {@link #killProcess} and {@link #sendSignal}.
           */
      		public static final native void sendSignal(int pid, int signal);
      
          /**
           * @hide
           * Private impl for avoiding a log message...  DO NOT USE without doing
           * your own log, or the Android Illuminati will find you some night and
           * beat you up.
           */
      		@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
      		public static final native void sendSignalQuiet(int pid, int signal);
      
      }
      
      public class Runtime {
          private static native void nativeExit(int code);
      }
      

      通過攔截以下函數,打印Native層的異常退出:

      void exit(int status);
      int kill(pid_t pid, int sig);
      

      打印調用棧:

      // 非 JNI 環境獲取從當前線程獲取 JNIEnv(AttachCurrentThread)
      void jni_thread_dump(JNIEnv* env) {
          jclass jcls = env->FindClass("java/lang/Thread");
          if (!jcls) return;
          jmethodID jm = env->GetStaticMethodID(jcls, "dumpStack", "()V");
          if (!jm) return;
          env->CallStaticVoidMethod(jcls, jm);
          env->ExceptionClear();
      }
      

      輸出結果:

      5511  5511 W System.err: java.lang.Exception: Stack trace
      5511  5511 W System.err: 	at java.lang.Thread.dumpStack(Thread.java:1527)
      5511  5511 W System.err: 	at android.os.Process.sendSignal(Native Method)
      5511  5511 W System.err: 	at android.os.Process.killProcess(Process.java:1295)
      5511  5511 W System.err: 	at com.android.internal.os.RuntimeInit$KillApplicationHandler.uncaughtException(RuntimeInit.java:207)
      5511  5511 W System.err: 	at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1073)
      5511  5511 W System.err: 	at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1068)
      5511  5511 W System.err: 	at java.lang.Thread.dispatchUncaughtException(Thread.java:2211)
      

      03. 追蹤Throwable異常調用棧

      在我們常用的try ... catch語句中,異常時打印調用棧是常規操作,在這里可以攔截并打印棧日志信息。

      import java.lang;
      
      public class Throwable implements Serializable {
      
      		private static native StackTraceElement[] nativeGetStackTrace(Object stackState);
          
          private static native Object nativeFillInStackTrace();
          
      }
      

      04. 打印VM異常調用棧

      package dalvik.system;
      
      /**
       * Provides a limited interface to the Dalvik VM stack. This class is mostly
       * used for implementing security checks.
       */
      public final class VMStack {
          /**
           * Retrieves the stack trace from the specified thread.
           *
           * @param t
           *      thread of interest
           * @return an array of stack trace elements, or null if the thread
           *      doesn't have a stack trace (e.g. because it exited)
           */
          native public static StackTraceElement[] getThreadStackTrace(Thread t);
      
          /**
           * Retrieves an annotated stack trace from the specified thread.
           *
           * @param t
           *      thread of interest
           * @return an array of annotated stack frames, or null if the thread
           *      doesn't have a stack trace (e.g. because it exited)
           */
          native public static AnnotatedStackTraceElement[] getAnnotatedThreadStackTrace(Thread t);
      
          /**
           * Retrieves a partial stack trace from the specified thread into
           * the provided array.
           *
           * @param t
           *      thread of interest
           * @param stackTraceElements
           *      preallocated array for use when only the top of stack is
           *      desired. Unused elements will be filled with null values.
           * @return the number of elements filled
           */
          native public static int fillStackTraceElements(Thread t, StackTraceElement[] stackTraceElements);
      }
      

      輸出:

      9402  9402 W stack  : android.app.LoadedApk.makeApplication(LoadedApk.java:1554)
      9402  9402 W stack  : android.app.ActivityThread.handleBindApplication(ActivityThread.java:8522)
      9402  9402 W stack  : android.app.ActivityThread.access$2800(ActivityThread.java:311)
      9402  9402 W stack  : android.app.ActivityThread$H.handleMessage(ActivityThread.java:2889)
      9402  9402 W stack  : android.os.Handler.dispatchMessage(Handler.java:117)
      9402  9402 W stack  : android.os.Looper.loopOnce(Looper.java:205)
      9402  9402 W stack  : android.os.Looper.loop(Looper.java:293)
      9402  9402 W stack  : android.app.ActivityThread.loopProcess(ActivityThread.java:9934)
      9402  9402 W stack  : android.app.ActivityThread.main(ActivityThread.java:9923)
      9402  9402 W stack  : java.lang.reflect.Method.invoke(Native Method)
      9402  9402 W stack  : com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:586)
      9402  9402 W stack  : com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1240)
      9402  9402 W stack  : ohos.abilityshell.HarmonyLoader.tryLoadHarmony(HarmonyLoader.java:130)
      9402  9402 W stack  : ohos.abilityshell.HarmonyApplication.tryLoadHarmony(HarmonyApplication.java:673)
      9402  9402 W stack  : ohos.abilityshell.HarmonyApplication.attachBaseContext(HarmonyApplication.java:168)
      9402  9402 W stack  : com.demo.app.DemoApp.attachBaseContext(SourceFile:1)
      9402  9402 W stack  : android.app.Application.attach(Application.java:338)
      9402  9402 W stack  : android.app.Instrumentation.newApplication(Instrumentation.java:1191)
      9402  9402 W stack  : android.app.LoadedApk.makeApplication(LoadedApk.java:1546)
      9402  9402 W stack  : android.app.ActivityThread.handleBindApplication(ActivityThread.java:8522)
      9402  9402 W stack  : android.app.ActivityThread.access$2800(ActivityThread.java:311)
      9402  9402 W stack  : android.app.ActivityThread$H.handleMessage(ActivityThread.java:2889)
      9402  9402 W stack  : android.os.Handler.dispatchMessage(Handler.java:117)
      9402  9402 W stack  : android.os.Looper.loopOnce(Looper.java:205)
      9402  9402 W stack  : android.os.Looper.loop(Looper.java:293)
      9402  9402 W stack  : android.app.ActivityThread.loopProcess(ActivityThread.java:9934)
      9402  9402 W stack  : android.app.ActivityThread.main(ActivityThread.java:9923)
      9402  9402 W stack  : java.lang.reflect.Method.invoke(Native Method)
      9402  9402 W stack  : com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:586)
      9402  9402 W stack  : com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1240)
      

      05. 打印異常信息

      Android框架默認會為每個應用進程設置一個全局的異常Handler,我們可以替換掉輸出打印更多內容。在這里要考慮應用自身也會設置的情況。

      Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
        	@Override
        	public void uncaughtException(Thread t, Throwable e) {
          	  // TODO
        	}
      });
      

      06. 打印異常傳送

      AndroidAMS服務中增加了一個應用向服務提交異常的接口,我們通過android.reflect.Proxy方式代理IActivityManager的實例,打印輸出。

      package android.app;
      
      // @source code: /frameworks/base/core/java/android/app/IActivityManager.aidl
      interface IActivityManager {
      		void handleApplicationCrash(IBinder app, ApplicationErrorReport.ParcelableCrashInfo crashInfo);
      }
      
      // @source code: /frameworks/base/core/java/android/app/ApplicationErrorReport.java
      public class ApplicationErrorReport implements Parcelable {
          public static class CrashInfo {
              /**
               * Dump a CrashInfo instance to a Printer.
               */
              public void dump(Printer pw, String prefix) {
                  pw.println(prefix + "exceptionHandlerClassName: " + exceptionHandlerClassName);
                  pw.println(prefix + "exceptionClassName: " + exceptionClassName);
                  pw.println(prefix + "exceptionMessage: " + exceptionMessage);
                  pw.println(prefix + "throwFileName: " + throwFileName);
                  pw.println(prefix + "throwClassName: " + throwClassName);
                  pw.println(prefix + "throwMethodName: " + throwMethodName);
                  pw.println(prefix + "throwLineNumber: " + throwLineNumber);
                  pw.println(prefix + "stackTrace: " + stackTrace);
              }
          }
          public static class ParcelableCrashInfo extends CrashInfo implements Parcelable {
      
          }
      }
      

      如輸出結果為:

      9402  9402 W Crash   : exceptionClassName: java.lang.IllegalStateException
      9402  9402 W Crash   : exceptionMessage: failed to attach Application, errorCode=30, errorInfo=bms service error, code is 8519969. 8519797
      9402  9402 W Crash   : throwFileName: HarmonyLoader.java
      9402  9402 W Crash   : throwClassName: ohos.abilityshell.HarmonyLoader
      9402  9402 W Crash   : throwMethodName: tryLoadHarmony
      9402  9402 W Crash   : throwLineNumber: 130
      9402  9402 W Crash   : stackTrace: java.lang.RuntimeException: Unable to instantiate application com.demo.app.DemoApp package com.demo.app: java.lang.IllegalStateException: failed to attach Application, errorCode=30, errorInfo=bms service error, code is 8519969.
      9402  9402 W Crash   : 	at android.app.LoadedApk.makeApplication(LoadedApk.java:1554)
      9402  9402 W Crash   : 	at android.app.ActivityThread.handleBindApplication(ActivityThread.java:8522)
      9402  9402 W Crash   : 	at android.app.ActivityThread.access$2800(ActivityThread.java:311)
      9402  9402 W Crash   : 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2889)
      9402  9402 W Crash   : 	at android.os.Handler.dispatchMessage(Handler.java:117)
      9402  9402 W Crash   : 	at android.os.Looper.loopOnce(Looper.java:205)
      9402  9402 W Crash   : 	at android.os.Looper.loop(Looper.java:293)
      9402  9402 W Crash   : 	at android.app.ActivityThread.loopProcess(ActivityThread.java:9934)
      9402  9402 W Crash   : 	at android.app.ActivityThread.main(ActivityThread.java:9923)
      9402  9402 W Crash   : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:586)
      9402  9402 W Crash   : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1240)
      9402  9402 W Crash   : Caused by: java.lang.IllegalStateException: fail
      

      07. 打印Binder通信信息

      可以打印應用訪問了那些系統服務。可以通過Binderceptor項目來完成。

      9402  9402 W Trace   : Binder::tgt: 0x3887b52, 3, : android.content.pm.IPackageManager
      9402  9402 W Trace   : Binder::tgt: 0xe45f2c2, 2, : android.os.IServiceManager
      9402  9402 W Trace   : Binder::tgt: 0x76c2822, 56, : com.huawei.android.view.IHwWindowManager
      9402  9417 W Trace   : Binder::tgt: 0x3887b52, 20, : android.content.pm.IPackageManager
      9402  9402 W Trace   : Binder::tgt: 0x7db76a2, 30, : android.net.IConnectivityManager
      9402  9402 W Trace   : Binder::tgt: 0x3887b52, 20, : android.content.pm.IPackageManager
      9402  9402 W Trace   : Binder::tgt: 0x3887b52, 9, : android.content.pm.IPackageManager
      9402  9402 W Trace   : Binder::tgt: 0x3887b52, 95, : android.content.pm.IPackageManager
      9402  9402 W Trace   : Binder::tgt: 0x3887b52, 3, : android.content.pm.IPackageManager
      ......
      

      binder codeaidl接口函數的對應關系:

      public static void printStub(String clsName) {
      		android.util.Log.w(TAG, ">>>>>> " + clsName);
      		try {
      			Class<?> nmClassStub = Class.findClass(clsName + "$Stub");
      			Method[] mm = nmClassStub.getMethods();
      
      			ArrayList<TRANSACTION_Item> list = new ArrayList<TRANSACTION_Item>();
      			for (Method m : mm) {
      				if (TextUtils.equals(m.getName(), "asBinder")) continue;
      				try {
      					funcName = m.toGenericString();
      					funcName = funcName.replace("abstract ", "");
      					funcName = funcName.replace(clsName + ".", "");
      
      					fieldName = "TRANSACTION_" + m.getName();
      					Field f = nmClassStub.getDeclaredField(fieldName);
      					f.setAccessible(true);
      					int val = f.getInt(null);
      					// android.util.Log.w(TAG, fieldName + " " + val);
      					list.add(new TRANSACTION_Item(val, funcName, fieldName));
      				} catch (Exception e) {
      					android.util.Log.e(TAG, e.toString());
      				}
      			}
      			Collections.sort(list, new TRANSACTION_Comparator());
      		} catch (Exception e) {
      			android.util.Log.e(TAG, e.toString());
      		}
      		android.util.Log.w(TAG, "<<<<<< " + clsName);
      }
      

      排序后可以得到輸出的結果:

      package android.content.pm;
      
      interface IPackageManager {
          public void checkPackageStartable(java.lang.String,int) throws android.os.RemoteException;// 1
          public boolean isPackageAvailable(java.lang.String,int) throws android.os.RemoteException;// 2
          public android.content.pm.PackageInfo getPackageInfo(java.lang.String,int,int) throws android.os.RemoteException;// 3
          public android.content.pm.PackageInfo getPackageInfoVersioned(android.content.pm.VersionedPackage,int,int) throws android.os.RemoteException;// 4
      }
      

      08. 打印JNI調用軌跡

      通過攔截JNIEnv層提供調用Java層方法的函數,打印調用信息。

      env->FindClass(...);
      env->GetMethodID(...);
      env->GetStaticMethodID(...);
      env->RegisterNatives(...);
      

      09. 打印訪問文件行為

      通過攔截open系列函數(為什么是系列,因為libc.so經過多年迭代,衍生出來很多函數,所以說Android的兼容性讓廣大開發者開發Demo容易,做穩定則難上加難),打印文件訪問記錄。

      int open(const char *fileName, int flags, ...);
      int open2(const char *fileName, int flags, ...);
      int _open(const char *fileName, int flags, ...);
      int openat(int dirfd, const char *fileName, int flags, ...);
      int _openat(int dirfd, const char *fileName, int flags, ...);
      ...
      

      至此,通過以上基本的方法,可以快速的增加應用運行軌跡信息。

      若還不夠,則需要針對應用內部調試,動態庫加載的進階方法深一步剖析,后面會給大家整理進階技能。

      posted @ 2024-07-27 15:55  iofomo  閱讀(383)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产精品国产三级国av| 精品天堂色吊丝一区二区| 亚洲av永久无码精品成人| 99久久亚洲综合精品成人网| 中文字幕日韩一区二区不卡| 国产综合久久久久鬼色| 亚洲综合另类小说色区一| 国产蜜臀av在线一区二区| 少妇熟女久久综合网色欲| 亚洲成av人片无码天堂下载| 国产四虎永久免费观看| 国产成人综合95精品视频| 亚洲自拍偷拍一区二区三区| 亚洲国产日韩在线视频| 国内精品视频区在线2021| 最新国产在线拍揄自揄视频| 国产精一区二区黑人巨大| 西乌珠穆沁旗| 天堂网亚洲综合在线| 蜜臀人妻精品一区二区免费| 亚洲精品一区二区制服| 香蕉影院在线观看| 国产自拍在线一区二区三区| 熟女系列丰满熟妇AV| 久久天天躁狠狠躁夜夜婷| 国产成人一区二区免av| 精品久久久久无码| 精品少妇爆乳无码aⅴ区| 精品国精品国自产在国产| 国产午夜精品久久久久免费视 | a级免费视频| 日本福利一区二区精品| 精品成人免费自拍视频| 亚洲一区二区精品偷拍| 天天爽天天摸天天碰| 亚洲日韩一区二区| 无码国产精品一区二区av| 91福利视频一区二区| 溧水县| 国产精品青草久久久久福利99| 精品久久久无码人妻中文字幕|