Android coredump generation and APK debugging

I have been struggling with the debugging of Android's underlying C++ code. I used to debug it by logging, which was extremely inefficient. But you can use gdb to debug coredump under Linux, so Android should also be able to do it.
For Coredump debugging under Linux, you can refer to this article:
Linux coredump debugging

Then I set the ulimit -c and coredump generation location according to the Linux method. As a result, no coredump file is generated at all.

1. Pure C\C++ generates Coredump

================================================
Then after investigation, it was found that Need to add a record under setrlimit 13 40 40 in init.rc: setrlimit 4 -1 -1.
As a result, it is still not generated.
It was found later that this method is only suitable for pure C/C++ program operation. The APK launched by Zygote still cannot be generated.

2. The APK started by Zygote generates Coredump

==================================================== ==
Continue to research
Android APK is launched by Zygote. Then you need to modify the code related to Zygote.

If coredump is turned on all the time, a lot of coredump files may be generated, which takes up a lot of space. So make a control switch.
When persist.debug.trace is 0, it is turned off, and when it is set to 1, it is turned on.

1. Modify the core dump size of the Zygote subprocess,
open art/runtime/native/dalvik_system_ZygoteHooks.cc, and add the following code:

diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc
index 891cdfa..caea8c0 100644
--- a/[runtime/native/dalvik_system_ZygoteHooks.cc]
+++ b/[runtime/native/dalvik_system_ZygoteHooks.cc]
@@ -46,7 +46,9 @@
#if defined(__linux__)
#include <sys/prctl.h>
#endif
-
+#ifdef __ANDROID__
+#include <cutils/properties.h>
+#endif
#include <sys/resource.h>
namespace art {
    
    
@@ -78,7 +80,18 @@ static void EnableDebugger() {
    
    
#endif
  // We don't want core dumps, though, so set the core dump size to 0.
  rlimit rl;
+#ifdef __ANDROID__
+  char prop_value[PROPERTY_VALUE_MAX];
+  property_get("persist.debug.trace", prop_value, "0");
+  if (prop_value[0] == '1') {
    
    
+      LOG(INFO) << "setting RLIM to infinity for process " << getpid();
+      rl.rlim_cur = RLIM_INFINITY;
+  } else {
    
    
+      rl.rlim_cur = 0;
+  }
+#else
  rl.rlim_cur = 0;
+#endif
  rl.rlim_max = RLIM_INFINITY;
  if (setrlimit(RLIMIT_CORE, &rl) == -1) {
    
    
    PLOG(ERROR) << "setrlimit(RLIMIT_CORE) failed for pid " << getpid();

2. Modify the core dump size of the Native process
, open system/core/init/property_service.cpp, and add the processing with the system property "persist.debug.trace".

diff --git a/init/property_service.cpp b/init/property_service.cpp
index 4172ba7..cdc5998 100644
--- a/[init/property_service.cpp]
+++ b/[init/property_service.cpp]
@@ -698,6 +698,20 @@ static void load_override_properties() {
    
    
    }
}
+static int check_rlim_action() {
    
    
+    struct rlimit rl;
+    std::string value  = android::base::GetProperty("persist.debug.trace", "");
+
+    if(value == "1") {
    
    
+        rl.rlim_cur = RLIM_INFINITY;
+        rl.rlim_max = RLIM_INFINITY;
+        if (setrlimit(RLIMIT_CORE, &rl) < 0) {
    
    
+            PLOG(ERROR) << "could not enable core file generation";
+        }
+    }
+    return 0;
+}
+
/* When booting an encrypted system, /data is not mounted when the
  * property service is started, so any properties stored there are
  * not loaded.  Vold triggers init to load these properties once it
@@ -723,6 +737,8 @@ void load_persist_props(void) {
    }
    persistent_properties_loaded = true;
    property_set("ro.persistent_properties.ready", "true");
+    /*check for coredump*/
+    check_rlim_action();
}
void load_recovery_id_prop() {
    
    

3. Set the coredump file name format and save path
in the system/core/rootdir/init.rc file

diff --git a/rootdir/init.rc b/rootdir/init.rc
index f95d58e..7d0fdfb 100644
--- a/[rootdir/init.rc]
+++ b/[rootdir/init.rc]
@@ -700,6 +700,11 @@ on property:vold.decrypt=trigger_load_persist_props
    start logd
    start logd-reinit
+# corefile limit
+on property:persist.debug.trace=1
+  mkdir /data/core 0777 root root
+  write /proc/sys/kernel/core_pattern "/data/core/%E.%p.%e"
+
on property:vold.decrypt=trigger_post_fs_data
    trigger post-fs-data
    trigger zygote-start

In this way, if you want to generate a coredump file, execute it setprop persist.debug.trace 1; otherwise, set it to 0.
Of course, you need to restart the system after each setting.

2. APK debugging Coredump

Finally generated a coredump file, very happy. But when I was about to debug, I was dumbfounded.
There is no executable program, what to do.
Fortunately, there is almighty Google.

Zygote's executable program is app_process. Now that the APK is launched by Zygote, let's debug it.

1. Start the gdb command (you don’t need to use ndk’s gdb, just use linux’s gdb directly)

ubuntu@ubuntu:~/imgs/system$ gdb 
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "aarch64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word".

2. Set the dynamic library search and loading path:
This path can be the library path after the system source code is compiled. I made a mirror image and mounted it on linux (/home/ubuntu/imgs).

(gdb)  set solib-search-path /home/ubuntu/imgs/system/system/lib64/

3. Load the startup program:

(gdb) file /home/ubuntu/zyp/imgs/system/system/bin/app_process64                      
Reading symbols from /home/ubuntu/zyp/imgs/system/system/bin/app_process64...
Reading symbols from .gnu_debugdata for /home/ubuntu/zyp/imgs/system/system/bin/app_process64...
(No debugging symbols found in .gnu_debugdata for /home/ubuntu/zyp/imgs/system/system/bin/app_process64)

4. Load corefile

(gdb) corefile /home/ubuntu/zyp/core***



Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x0000f7cad281f7d4 in VCEncGetAsicConfig () from /home/ubuntu/zyp/imgs/system/system/lib64/libh2enc.so
[Current thread is 1 (LWP 1552)]
(gdb) bt
#0  0x0000f7cad281f7d4 in VCEncGetAsicConfig () from /home/ubuntu/imgs/system/system/lib64/libh2enc.so
#1  0x0000f7cad2828894 in VCEncSetCodingCtrl () from /home/ubuntu/imgs/system/system/lib64/libh2enc.so
#2  0x0000f7cad27a5fc0 in ?? () from /home/ubuntu/imgs/system/system/lib64/libinsvid.so
#3  0x0000f7cad27a9ac4 in insvid_h26xe_init () from /home/ubuntu/imgs/system/system/lib64/libinsvid.so

You're done!

Reference:
The method of generating core dump under Android
Android P enables the function of grabbing Coredump
Android - coredump analysis

Guess you like

Origin blog.csdn.net/qq_36383272/article/details/123875319