OpenCoreと組み合わせてAndroidアプリケーションのクラッシュ問題を解析

コアダンプの構成

public class App extends Application {

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);

        Coredump.getInstance().init();
        Coredump.getInstance().setCoreDir(getExternalFilesDir(null).getAbsolutePath());
        Coredump.getInstance().setCoreMode(Coredump.MODE_COPY | Coredump.MODE_PTRACE);
        //Coredump.getInstance().setCoreMode(Coredump.MODE_COPY);
        //Coredump.getInstance().setCoreMode(Coredump.MODE_PTRACE);
        Coredump.getInstance().enable(Coredump.JAVA);
        Coredump.getInstance().enable(Coredump.NATIVE);
    }
}

Java OOM シナリオをテストする

public class LeakMemory {
    private byte[] data = new byte[65536];

    public LeakMemory() {
        for (int i = 0; i < data.length; i++) {
            data[i] = (byte) 0xaa;
        }
    }
}

void doOOM(View view) {
    ArrayList<LeakMemory> array = new ArrayList<LeakMemory>();
    new Thread(new Runnable() {
        @Override
        public void run() {
            while (true) {
                array.add(new LeakMemory());
            }
        }
    }).start();
}

「doOOM」ボタンをクリックすると、プログラムは OOM クラッシュが発生するまで LeakMemory オブジェクトを作成し続けます。Java クラッシュが発生すると、Opencore によってインターセプトされ、Coredump のキャプチャがトリガーされます。

AndroidRuntime: java.lang.OutOfMemoryError: Failed to allocate a 65552 byte allocation with 63712 free bytes and 62KB until OOM, target footprint 268435456, growth limit 268435456
AndroidRuntime: 	at penguin.opencore.coretester.LeakMemory.<init>(LeakMemory.java:4)
AndroidRuntime: 	at penguin.opencore.coretester.MainActivity$2.run(MainActivity.java:55)
AndroidRuntime: 	at java.lang.Thread.run(Thread.java:1012)

Opencore-arm64: Wait (19990) coredump
Opencore-arm64: Coredump /storage/emulated/0/Android/data/penguin.opencore.coretester/files/core.19935 ...
Opencore-arm64: WriteCoreLoadSegment Mode(3)
Opencore-arm64: [0x5ffff08000] /mali csf (deleted) Not in self.
Opencore-arm64: [0x5ffff1b000] /mali csf (deleted) Not in self.
Opencore-arm64: [0x5ffff2e000] /mali csf (deleted) Not in self.
Opencore-arm64: [0x5ffff41000] /mali csf (deleted) Not in self.
Opencore-arm64: [0x5ffff54000] /mali csf (deleted) Not in self.
Opencore-arm64: [0x7c98a00000] /memfd:jit-cache (deleted) Not in self.
Opencore-arm64: [0x7c9dde0000] /memfd:jit-cache (deleted) Not in self.
Opencore-arm64: Coredump Done.
Opencore: /storage/emulated/0/Android/data/penguin.opencore.coretester/files/core.19935


OOM 問題のメモリ サイトを取得し、オフライン メモリ分析を実行できます。ART 仮想マシンのアプリケーションには、支援する特別な分析ツールがあります。GDB や LLDB でも同様のことができます。

Java スタックを解析して例外タイプを見つけます。

art-parser> bt 19987
"Thread-4" prio=0 tid=2 Waiting
  | group="" sCount=0 ucsCount=0 flags=0 obj=0x12c80f10 self=0x7d57f78400
  | sysTid=19987 nice=<unknown> cgrp=<unknown> sched=<unknown> handle=0x7c9dbdfcb0
  | stack=0x7c9dadc000-0x7c9dade000 stackSize=0x103cb0
  | held mutexes=
  x0  0x0000007c185a5db0  x1  0x0000000000000080  x2  0x0000000000000000  x3  0x0000000000000000  
  x4  0x0000000000000000  x5  0x0000000000000000  x6  0x0000000000000000  x7  0x0000007c9dbddf60  
  x8  0x0000000000000062  x9  0x4a022fd738159c35  x10 0x0000000000000003  x11 0x0000000000000002  
  x12 0x0000007c185ad9fc  x13 0x000000004cec4ec5  x14 0x0000007c9dbde7d0  x15 0x0000000000000004  
  x16 0x0000007cb360f7c8  x17 0x0000007d4a94b200  x18 0x0000007c39c64000  x19 0x0000007c185a5da0  
  x20 0x0000007d57f78400  x21 0x0000007c185a5db0  x22 0x0000000000000000  x23 0x0000000000000000  
  x24 0x0000007c187f1040  x25 0x0000007c9dbe0000  x26 0x0000000000000001  x27 0x0000007d57feec20  
  x28 0x0000007d57feebe0  x29 0x0000007c9dbde5a0  
  lr  0x0000007cb3081f6c  sp  0x0000007c9dbde590  pc  0x0000007d4a94b21c  pst 0x0000000060001000  
  FP[0x7c9dbde5a0] PC[0x7d4a94b21c] native: #00 (syscall+0x1c) /apex/com.android.runtime/lib64/bionic/libc.so
  FP[0x7c9dbde5a0] PC[0x7cb3081f6c] native: #01 (art::ConditionVariable::WaitHoldingLocks(art::Thread*)+0x8c) /apex/com.android.art/lib64/libart.so
  FP[0x7c9dbde630] PC[0x7cb3372eb4] native: #02 (art::Monitor::Wait(art::Thread*, long, int, bool, art::ThreadState)+0x274) /apex/com.android.art/lib64/libart.so
  FP[0x7c9dbde6d0] PC[0x7cb33746ac] native: #03 (art::Monitor::Wait(art::Thread*, art::ObjPtr<art::mirror::Object>, long, int, bool, art::ThreadState)+0x12c) /apex/com.android.art/lib64/libart.so
  QF[0x7c9dbde720] PC[0x0000000000] at dex-pc 0x0000000000 java.lang.Object.wait(Native method)  //AM[0x706f1370]
  - waiting on <0x12e52f78> (java.lang.Object)
  QF[0x7c9dbde7d0] PC[0x7cb300a914] at dex-pc 0x7caeea69f2 java.lang.Object.wait  //AM[0x706f1350]
  QF[0x7c9dbde8c0] PC[0x7cb300a258] at dex-pc 0x7caeea69d8 java.lang.Object.wait  //AM[0x706f1330]
  QF[0x7c9dbde9a0] PC[0x7cb300a258] at dex-pc 0x7c9bac1d1a penguin.opencore.sdk.Coredump.waitCore  //AM[0x7c9c5584e0]
  QF[0x7c9dbdea80] PC[0x7cb300a258] at dex-pc 0x7c9bac1bf4 penguin.opencore.sdk.Coredump.doCoredump  //AM[0x7c9c558400]
  QF[0x7c9dbdeb50] PC[0x7cb300a258] at dex-pc 0x7c9bac1ace penguin.opencore.sdk.Coredump$JavaCrashHandler.uncaughtException  //AM[0x7c9c5585a0]
  QF[0x7c9dbdec30] PC[0x7cb300b078] at dex-pc 0x7caeeb1714 java.lang.ThreadGroup.uncaughtException  //AM[0x70676b78]
  QF[0x7c9dbded30] PC[0x7cb300a258] at dex-pc 0x7caeeb1700 java.lang.ThreadGroup.uncaughtException  //AM[0x70676b78]
  QF[0x7c9dbdee30] PC[0x7cb300b078] at dex-pc 0x7caeeb287e java.lang.Thread.dispatchUncaughtException  //AM[0x707001e0]


レジスタを展開すると、Java 関数呼び出しパラメータが表示されます。

...
  QF[0x7c9dbdee30] PC[0x7cb300b078] at dex-pc 0x7caeeb287e java.lang.Thread.dispatchUncaughtException  //AM[0x707001e0]
  {
      Virtual registers
      {
        v0 = 0x12c811f0    v1 = 0x70517d70    v2 = 0x12c80f10    v3 = 0x12cc0000
      }
      Physical registers
      {
        x19 = 0x7d57f78400    x20 = 0x0    x21 = 0x0    x22 = 0x7caeeb287e    
        x23 = 0x3072    x24 = 0x7cb3000880    x25 = 0x7c9dbdee58    x26 = 0x7064c9a0    
        x27 = 0x8    x28 = 0x7c9dbdee80    x29 = 0x7c9dbdee68    x30 = 0x7cb300b078
      }
  }

バイトコードの逆コンパイルにより、Throwable オブジェクトが存在するレジスタが特定されます。

art-parser> disassemble 0x707001e0 -i 0x7caeeb287e
void java.lang.Thread.dispatchUncaughtException(java.lang.Throwable) [dex_method_idx=3796]
DEX CODE:
  0x7caeeb287e: 3072 0eba 0321           | invoke-interface {v1, v2, v3}, void java.lang.Thread$UncaughtExceptionHandler.uncaughtException(java.lang.Thread, java.lang.Throwable) // method@3770


スロー可能なエラー メッセージを解析します。

art-parser> dumpjava 0x12cc0000
Throwable java.lang.OutOfMemoryError
Failed to allocate a 65552 byte allocation with 63712 free bytes and 62KB until OOM, target footprint 268435456, growth limit 268435456
    penguin.opencore.coretester.LeakMemory.<init>(LeakMemory.java:4)
    penguin.opencore.coretester.MainActivity$2.run(MainActivity.java:55)
    java.lang.Thread.run(Thread.java:1012)
Caused by:
Throwable java.lang.OutOfMemoryError
Failed to allocate a 65552 byte allocation with 63712 free bytes and 62KB until OOM, target footprint 268435456, growth limit 268435456
    penguin.opencore.coretester.LeakMemory.<init>(LeakMemory.java:4)
    penguin.opencore.coretester.MainActivity$2.run(MainActivity.java:55)
    java.lang.Thread.run(Thread.java:1012)

Java ヒープ メモリ オブジェクトが占める ShallowSize サイズと割り当ての数を数えると、byte[] 配列が 200+M のメモリを占有していることがわかります。これは、LeakMemory オブジェクトによって割り当てられた数値と非常に一致しています。

art-parser> top 10 -a -d
Address       Allocations       ShallowSize       NativeSize     ClassName
0x705050f8           3820        249731739                 0     byte[]
0x12c80f88           3805            45660                 0     penguin.opencore.coretester.LeakMemory
0x70566f78           1753           561064                 0     java.lang.String
0x705052b8           1029            60360                 0     java.lang.Object[]
0x705bf568            761            15220                 0     java.util.ArrayList
0x70507aa0            741            26676                 0     sun.misc.Cleaner
0x7079f8e0            736            17664                 0     libcore.util.NativeAllocationRegistry$CleanerThunk
0x70547510            681           608344                 0     int[]
0x70547828            650           162232                 0     long[]
0x70cac990            422            10128                 0     android.graphics.Rect


各 LeakMemory のメモリ分布を分析すると、LeakMemory オブジェクトが byte[] 配列を保持しており、各 byte[] のサイズが 65552 バイトであるため、LeakMemory オブジェクトにリークがあることがわかります。

art-parser> p 0x12f69ec8 -r
Size: 0x10
Padding: 0x4
Object Name: penguin.opencore.coretester.LeakMemory
  iFields of penguin.opencore.coretester.LeakMemory
    [0x8] byte[] data = 0x86907000
  iFields of java.lang.Object
    [0x0] java.lang.Class shadow$_klass_ = 0x12c80f88
    [0x4] int shadow$_monitor_ = 0x0
References:
    >> 0x12f57108 java.lang.Object[]
    
art-parser> p 0x86907000
Size: 0x10010
Padding: 0x4
Array Name: byte[]
    [0] 0xaa
    [1] 0xaa
    [2] 0xaa
    ...
    [65535] 0xaa

LeakMemory はスレッドのローカル変数 java.util.ArrayList によって保持されるため、GC によって回復できず、OOM が発生します。

art-parser> p 0x12f57108
Size: 0x4120
Padding: 0x4
Array Name: java.lang.Object[]
    [0] 0x12f5b228
    [1] 0x12f5b238
    ...
    [4163] 0x0
References:
    >> 0x12c81078 java.util.ArrayList
    
art-parser> p 0x12c81078 -r
Size: 0x18
Padding: 0x4
Object Name: java.util.ArrayList
  iFields of java.util.ArrayList
    [0xc] java.lang.Object[] elementData = 0x12f57108
    [0x10] int size = 0xedd
  iFields of java.util.AbstractList
    [0x8] int modCount = 0xedd
  iFields of java.util.AbstractCollection
  iFields of java.lang.Object
    [0x0] java.lang.Class shadow$_klass_ = 0x705bf568
    [0x4] int shadow$_monitor_ = 0x0
References:
    >> 0x12c81090 penguin.opencore.coretester.MainActivity$2
    
art-parser> p 0x12c81090 -r
Size: 0x10
Object Name: penguin.opencore.coretester.MainActivity$2
  iFields of penguin.opencore.coretester.MainActivity$2
    [0x8] penguin.opencore.coretester.MainActivity this$0 = 0x12cac780
    [0xc] java.util.ArrayList val$array = 0x12c81078
  iFields of java.lang.Object
    [0x0] java.lang.Class shadow$_klass_ = 0x12de6d50
    [0x4] int shadow$_monitor_ = 0x0
References:
    >> 0x12c80f10 java.lang.Thread

ネイティブ クラッシュ シーンをテストする

このテスト ケースは Android12 ~ Android13 の間で使用されます。このネイティブ クラッシュの問題を確認するには、APK をコンパイルし、デバッグ可能の条件に注意してください。デバッグ可能が false の場合、この問題が発生するはずです。

public class NterpTester {

    class Entry {}

    private List<Entry> mList;

    public void setList() {
        mList = new ArrayList<>();
    }

    @Override
    public String toString() {
        return "Penguin." + mList;
    }
}

void doTest(View view) {
    Log.i("Opencore", "test");
    new Thread(new Runnable() {
        @Override
        public void run() {
            while(true) {
                nterpTester.toString();
            }
        }
    }).start();

    new Thread(new Runnable() {
        @Override
        public void run() {
            while (true) {
                nterpTester.setList();
            }
        }
    }).start();
}

debuggable が true の場合、再現するには小さな HOOK 処理が必要となるため、setList の Java 関数の動作モードを Nterp 解析動作に変更する必要があります。

void doHook(View view) {
    Log.i("Opencore", "doHook");
    try {
        Method setListMethod = NterpTester.class.getMethod("setList", null);
        Field artMethodField = Executable.class.getDeclaredField("artMethod");
        artMethodField.setAccessible(true);
        long artMethod = artMethodField.getLong(setListMethod);
        Log.i("Opencore", artMethodField.getName() + " = 0x" + Long.toHexString(artMethod));
        native_call(artMethod);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

関数を ExecuteNterpImpl にジャンプさせるように、entry_point_from_quick_compiled_code_ を強制的に変更します。

extern "C"
JNIEXPORT void JNICALL
Java_penguin_opencore_coretester_MainActivity_native_1call(JNIEnv *env, jobject thiz, jlong art_method_ptr) {
#if defined (__aarch64__) || defined (__arm64__)
    ArtMethod *method = reinterpret_cast<ArtMethod *>(art_method_ptr);
    void *art_load = read_module_address("/apex/com.android.art/lib64/libart.so");
    int nterp_offset = read_symb_offset("/apex/com.android.art/lib64/libart.so", "ExecuteNterpImpl", STT_FUNC);
    void* ExecuteNterpImpl = reinterpret_cast<void *>((uint64_t)art_load + nterp_offset);
    LOGI("%p %p %p", method, art_load, ExecuteNterpImpl);
    method->ptr_sized_fields_.entry_point_from_quick_compiled_code_ = ExecuteNterpImpl;
#endif
}

Opencore-SDK: Init opencore environment..
Opencore: test
Opencore: doHook
Opencore: artMethod = 0x7c9c56ded0
Opencore: 57, 0000000000200090, 000000000005d34f, ExecuteNterpImpl, 0x7c9da1a82a, 0x7c9d10e000
Opencore: 0x7c9c56ded0 0x7cb2e00000 0x7cb3000090
Opencore-arm64: Wait (20399) coredump
Opencore-arm64: Coredump /storage/emulated/0/Android/data/penguin.opencore.coretester/files/core.20356 ...
Opencore-arm64: WriteCoreLoadSegment Mode(3)
Opencore-arm64: [0x5ffff08000] /mali csf (deleted) Not in self.
Opencore-arm64: [0x5ffff1b000] /mali csf (deleted) Not in self.
Opencore-arm64: [0x5ffff2e000] /mali csf (deleted) Not in self.
Opencore-arm64: [0x5ffff41000] /mali csf (deleted) Not in self.
Opencore-arm64: [0x5ffff54000] /mali csf (deleted) Not in self.
Opencore-arm64: [0x7c98a00000] /memfd:jit-cache (deleted) Not in self.
Opencore-arm64: [0x7c9d940000] [anon:dalvik-CompilerMetadata] Not in self.
Opencore-arm64: [0x7c9dde0000] /memfd:jit-cache (deleted) Not in self.
Opencore-arm64: Coredump Done.

スタック上の Java 関数 java.lang.String.valueOf でネイティブ クラッシュが発生していることがわかります。

art-parser> bt 20397 -adj
"Thread-4" prio=0 tid=29 Unknown
  | group="" sCount=0 ucsCount=0 flags=4 obj=0x17200d10 self=0x7c162dac00
  | sysTid=20397 nice=<unknown> cgrp=<unknown> sched=<unknown> handle=0x7c16fcacb0
  | stack=0x7c16ec7000-0x7c16ec9000 stackSize=0x103cb0
  | held mutexes= "mutator lock"
  x0  0x00000000ffffffff  x1  0x0000007d474c9b98  x2  0x0000000000000000  x3  0x0000000000000000  
  x4  0x0000007d474c82a0  x5  0x0000000000b0863a  x6  0x0000007d474c9708  x7  0x706d756465726f63  
  x8  0x0000000000000104  x9  0x4a022fd738159c35  x10 0x0000000000000002  x11 0xfffffffffffffffd  
  x12 0x0000007d474c83c0  x13 0x0000000000000016  x14 0x0000007d474c9708  x15 0x000000ce9c37561b  
  x16 0x0000007d4a9cf298  x17 0x0000007d4a9a9010  x18 0x0000007c123ae000  x19 0x0000007d580029c0  
  x20 0x000000000000000b  x21 0x0000007d474c9da0  x22 0x0000007d474c9e48  x23 0x0000007d572e86f8  
  x24 0x0000007c16fcb000  x25 0x0000007c16fcb000  x26 0x000000000000000b  x27 0x0000007d572e8318  
  x28 0x0000000000000000  x29 0x0000007d474c9ca0  
  lr  0x0000007c9b084f80  sp  0x0000007d474c9b60  pc  0x0000007d4a9a9014  pst 0x0000000060001000  
  FP[0x7d474c9ca0] PC[0x7d4a9a9014] native: #00 (wait4+0x4) /apex/com.android.runtime/lib64/bionic/libc.so
  FP[0x7d474c9ca0] PC[0x7c9b084f80] native: #01 (OpencoreImpl::DoCoreDump()+0x64) /data/app/~~AeyWfgE18eFG7ZKpLRTTqw==/penguin.opencore.coretester-7NCCv5-T4UIf09uA5DJyVA==/base.apk!/lib/arm64-v8a/libopencore.so
  FP[0x7d474c9cf0] PC[0x7c9b082aa8] native: #02 (Opencore::HandleSignal(int)+0x88) /data/app/~~AeyWfgE18eFG7ZKpLRTTqw==/penguin.opencore.coretester-7NCCv5-T4UIf09uA5DJyVA==/base.apk!/lib/arm64-v8a/libopencore.so
  FP[0x7d474c9d40] PC[0x7d572e31fc] native: #03 (art::SignalChain::Handler(int, siginfo*, void*)+0x14c) /apex/com.android.art/lib64/libsigchain.so
  FP[0x7d474caff0] PC[0x7d594dd84c] native: #04 () [vdso]
  <<maybe handle signal>>
  x0  0x0000000000000000  x1  0x000000001409fec0  x2  0x000000001409fec0  x3  0x00000000172012be  
  x4  0x0000000014166e20  x5  0x0000000000000000  x6  0x00000000000011e0  x7  0x0000000000000010  
  x8  0x4a022fd738159c35  x9  0x4a022fd738159c35  x10 0x0000000000000000  x11 0x000000000000000b  
  x12 0x0000000014166d9c  x13 0x0000000000000001  x14 0xfffffffffc000000  x15 0x0000000000000030  
  x16 0x0000007d5802af28  x17 0x0000000000000000  x18 0x0000007c123ae000  x19 0x0000007c162dac00  
  x20 0x0000000000000001  x21 0x0000000000000000  x22 0x000000001409fec0  x23 0x000000001409fec0  
  x24 0x000000001409fec0  x25 0x0000007c16fca940  x26 0x000000007064c218  x27 0x0000000000000004  
  x28 0x0000007c16fca950  x29 0x000000009cb5f9b0  
  lr  0x000000009cb5bd80  sp  0x0000007c16fca7b0  pc  0x000000009cb60ffc  pst 0x0000000040001000  
  QF[0x7c16fca7b0] PC[0x009cb60ffc]  at dex-pc 0x7caeeaebe0 java.lang.String.valueOf  //AM[0x706ff3b8]
  QF[0x7c16fca7e0] PC[0x009cb5bd80]  at dex-pc 0x7caeeacb80 java.lang.StringBuilder.append  //AM[0x706a2198]
  QF[0x7c16fca830] PC[0x009cb6130c]  at dex-pc 0x7c9be8cf22 penguin.opencore.coretester.NterpTester.toString  //AM[0x7c9c56def0]
  QF[0x7c16fca870] PC[0x009cb5f95c]  at dex-pc 0x7c9be8cb94 penguin.opencore.coretester.MainActivity$3.run  //AM[0x7c9c56e118]
  QF[0x7c16fca920] PC[0x7cb300b078]  at dex-pc 0x7caeeb2b60 java.lang.Thread.run  //AM[0x70700400]

マシンコードを解析すると、命令 ldr x0,[x0, #192] でセグメンテーション違反が発生したことがわかります。この時点で、x0 は実際には x1 オブジェクトの klass_ メンバー変数の値になります。

(gdb) x /32i 0x9cb60fb0
   0x9cb60fb0:	sub	x16, sp, #0x2, lsl #12
   0x9cb60fb4:	ldr	wzr, [x16]
   0x9cb60fb8:	str	x0, [sp, #-48]!
   0x9cb60fbc:	stp	x22, x30, [sp, #32]
   0x9cb60fc0:	str	wzr, [sp, #28]
   0x9cb60fc4:	ldr	w16, [x19]
   0x9cb60fc8:	tst	w16, #0x7
   0x9cb60fcc:	b.ne	0x9cb61030  // b.any
   0x9cb60fd0:	mov	x16, #0xaf28                	// #44840
   0x9cb60fd4:	movk	x16, #0x5802, lsl #16
   0x9cb60fd8:	movk	x16, #0x7d, lsl #32
   0x9cb60fdc:	ldrb	w17, [x16]
   0x9cb60fe0:	cbnz	w17, 0x9cb6103c
   0x9cb60fe4:	cbnz	w1, 0x9cb60ff4
   0x9cb60fe8:	ldr	w0, 0x9cb61068
   0x9cb60fec:	mov	x22, x1
   0x9cb60ff0:	b	0x9cb61008
   0x9cb60ff4:	mov	x22, x1
   0x9cb60ff8:	ldr	w0, [x1]
   0x9cb60ffc:	ldr	x0, [x0, #192]
   0x9cb61000:	ldr	x30, [x0, #24]
   0x9cb61004:	blr	x30
   0x9cb61008:	mov	x1, x0


そして、x1 オブジェクトは java.util.ArrayList であり、最後のメモリ ダンプ後の klass_ = 0x705bf568 は null ポインタではありません。

art-parser> p 0x000000001409fec0   
Size: 0x18
Padding: 0x4
Object Name: java.util.ArrayList
  iFields of java.util.ArrayList
    [0xc] java.lang.Object[] elementData = 0x7053e720
    [0x10] int size = 0x0
  iFields of java.util.AbstractList
    [0x8] int modCount = 0x0
  iFields of java.util.AbstractCollection
  iFields of java.lang.Object
    [0x0] java.lang.Class shadow$_klass_ = 0x705bf568
    [0x4] int shadow$_monitor_ = 0x20000000


この質問については、ここでは詳しくはお答えしません。ご興味がございましたら、プライベート メッセージをお送りください。この質問の主な理由は、 mList = new ArrayList<>(); このコードは、Nterp 解釈による新しいインスタンスのバイトコードです。

art-parser> disassemble 0x7c9c56ded0 --full
void penguin.opencore.coretester.NterpTester.setList() [dex_method_idx=325]
DEX CODE:
  0x7c9be8cf5c: 0022 0113                | new-instance v0, java.util.ArrayList // type@TypeIndex[275]
  0x7c9be8cf60: 1070 0127 0000           | invoke-direct {v0}, void java.util.ArrayList.<init>() // method@295
  0x7c9be8cf66: 105b 3261                | iput-object v0, v1, Ljava/util/List; penguin.opencore.coretester.NterpTester.mList // field@12897
  0x7c9be8cf6a: 000e                     | return-void
OatQuickMethodHeader(0x7cb300008c)
  code_offset: 0x7cb3000090
  code_size: 0xf0b4
NterpMethodFrameInfo
  frame_size_in_bytes: 0xd0
  core_spill_mask: 0x7ff80000 (x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30)
  fp_spill_mask: 0xff00 (x8, x9, x10, x11, x12, x13, x14, x15)
OAT CODE:
  [0x7cb3000090-0x7cb300f144]

特定の修復は、mList メンバー オブジェクトに揮発性の変更を追加することで回避でき、Android14 以降でのみ修復されます。

// https://android-review.googlesource.com/c/platform/art/+/2583193

%def op_new_instance():
   EXPORT_PC
   // Fast-path which gets the class from thread-local cache.
%  fetch_from_thread_cache("x0", miss_label="2f")
   TEST_IF_MARKING 3f
4:
   ldr     lr, [xSELF, #THREAD_ALLOC_OBJECT_ENTRYPOINT_OFFSET]
   blr     lr
   dmb     ishst                       // need fence for making object's class visible
1:
   lsr     w1, wINST, #8               // w1 <- A
   SET_VREG_OBJECT w0, w1              // fp[A] <- value
   FETCH_ADVANCE_INST 2
   GET_INST_OPCODE ip
   GOTO_OPCODE ip
2:
   mov     x0, xSELF
   ldr     x1, [sp]
   mov     x2, xPC

やっと

アーキテクトになりたい場合、または 20,000 ~ 30,000 の給与範囲を突破したい場合は、コーディングとビジネスに限定されず、モデルを選択し、拡張し、プログラミング的思考を向上させることができなければなりません。また、しっかりとしたキャリアプランも大切で、学ぶ習慣も大切ですが、一番大切なのは継続力であり、継続的に実行できないプランは絵にかいたもちです。

方向性がわからない場合は、Ali のシニア アーキテクトが書いた一連の「Android の 8 つの主要モジュールに関する上級ノート」をここで共有したいと思います。これは、乱雑で散在し断片化した知識を体系的に整理するのに役立ちます。 Android開発のさまざまな知識を体系的かつ効率的に習得できます。
ここに画像の説明を挿入
私たちが普段読んでいる断片的な内容と比べて、このノートの知識ポイントはより体系的で理解しやすく、覚えやすく、知識体系に従って厳密に配置されています。

ビデオ素材のフルセット:

1. インタビュー集

ここに画像の説明を挿入
2. ソースコード解析集
ここに画像の説明を挿入

3. オープンソース フレームワークのコレクションは、
ここに画像の説明を挿入
ワン クリックと 3 つのリンクで誰でもサポートできるようになっています。記事内の情報が必要な場合は、記事の最後にある CSDN 公式認定 WeChat カードをクリックして無料で入手してください↓↓↓

おすすめ

転載: blog.csdn.net/m0_56255097/article/details/132590423
おすすめ