Android coredump生成与APK调试

一直苦于Android底层C++代码的调试,以前都是通过打日志的方法调试的,效率极低。但是Linux下就可以用gdb 来调试coredump,那么Android应该也可以才对。
关于Linux下Coredump调试可以参考这篇文章:
Linux coredump 调试

然后我按照Linux的方法设置了ulimit -c 和 coredump生成位置。结果,根本就不生成coredump文件。

一、纯C\C++生成Coredump

=============================================
然后经过调研发现,需要在init.rc中setrlimit 13 40 40下增加一条记录: setrlimit 4 -1 -1。
结果,依然没有生成。
后面发现,这种方法只适用于纯C/C++程序运行。而由Zygote启动的APK还是不能生成。

二、Zygote启动的APK生成Coredump

====================================================
继续调研
Android的APK是由Zygote启动的。那么需要修改Zygote相关的代码。

如果一直打开coredump,可能会产生很多的coredump文件,极其占用空间。所以做个控制开关。
persist.debug.trace为0时关闭,设置为1时打开。

1.修改Zygote子进程的core dump size
打开art/runtime/native/dalvik_system_ZygoteHooks.cc,加入以下代码:

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.修改Native进程的core dump size
打开system/core/init/property_service.cpp,添加随系统属性“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.设置coredump文件名称格式及保存路径
在system/core/rootdir/init.rc文件

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

这样,如果想生成coredump文件,就执行setprop persist.debug.trace 1;否则就设置为0.
当然,每次设置后要重启系统。

二、APK调试Coredump

终于生成了coredump文件了,很开心。但是准备调试的时候,傻眼了。
没有可执行程序啊,咋玩。
好在有万能的谷歌。

Zygote的可执行程序是app_process。既然APK是由Zygote启动的,那就调试它。

1、启动gdb命令(不必用ndk的gdb,直接用linux的gdb就可以)

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、设置动态库搜索加载路径:
这个路径可以是系统源码编译后的库路径,我是做成了镜像然后挂载在linux上的(/home/ubuntu/imgs)。

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

3、加载启动程序:

(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、加载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

大功告成!

参考:
Android下生成core dump的方法
Android P 开启抓取Coredump功能
Android——coredump解析

猜你喜欢

转载自blog.csdn.net/qq_36383272/article/details/123875319