native-dump-trace.patch 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. From 0ddaddce2d4a7a61f3bf5adf9fb3d2a7a51e28e1 Mon Sep 17 00:00:00 2001
  2. From: sunxiaodong <sunxiaodongme@gmail.com>
  3. Date: Mon, 21 Nov 2022 16:13:12 +0800
  4. Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0nativeDumpTrace?=
  5. MIME-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. ---
  9. .../xcrash_lib/src/main/cpp/xcrash/xc_jni.c | 14 ++++++++
  10. .../xcrash_lib/src/main/cpp/xcrash/xc_trace.c | 22 ++++++++++---
  11. .../xcrash_lib/src/main/cpp/xcrash/xc_trace.h | 1 +
  12. .../main/java/xcrash/DumpTraceManager.java | 33 +++++++++++++++++++
  13. .../src/main/java/xcrash/NativeHandler.java | 24 +++++++++++---
  14. .../src/main/java/xcrash/XCrash.java | 10 +++++-
  15. 6 files changed, 94 insertions(+), 10 deletions(-)
  16. create mode 100644 third-party-libs/xcrash_lib/src/main/java/xcrash/DumpTraceManager.java
  17. diff --git a/third-party-libs/xcrash_lib/src/main/cpp/xcrash/xc_jni.c b/third-party-libs/xcrash_lib/src/main/cpp/xcrash/xc_jni.c
  18. index 697b80caa..db77eb795 100644
  19. --- a/third-party-libs/xcrash_lib/src/main/cpp/xcrash/xc_jni.c
  20. +++ b/third-party-libs/xcrash_lib/src/main/cpp/xcrash/xc_jni.c
  21. @@ -229,6 +229,13 @@ static void xc_jni_test_crash(JNIEnv *env, jobject thiz, jint run_in_new_thread)
  22. xc_test_crash(run_in_new_thread);
  23. }
  24. +static void xc_jni_dump_trace(JNIEnv *env, jobject thiz) {
  25. + (void)env;
  26. + (void)thiz;
  27. +
  28. + xc_trace_handler_dump_trace();
  29. +}
  30. +
  31. static JNINativeMethod xc_jni_methods[] = {
  32. {
  33. "nativeInit",
  34. @@ -281,6 +288,13 @@ static JNINativeMethod xc_jni_methods[] = {
  35. ")"
  36. "V",
  37. (void *)xc_jni_test_crash
  38. + },
  39. + {
  40. + "nativeDumpTrace",
  41. + "("
  42. + ")"
  43. + "V",
  44. + (void *)xc_jni_dump_trace
  45. }
  46. };
  47. diff --git a/third-party-libs/xcrash_lib/src/main/cpp/xcrash/xc_trace.c b/third-party-libs/xcrash_lib/src/main/cpp/xcrash/xc_trace.c
  48. index 6a88003af..631c835bb 100644
  49. --- a/third-party-libs/xcrash_lib/src/main/cpp/xcrash/xc_trace.c
  50. +++ b/third-party-libs/xcrash_lib/src/main/cpp/xcrash/xc_trace.c
  51. @@ -52,9 +52,11 @@
  52. #define XC_TRACE_FAST_CALLBACK_METHOD_NAME "traceCallbackBeforeDump"
  53. #define XC_TRACE_FAST_CALLBACK_METHOD_SIGNATURE "()V"
  54. +#define XC_TRACE_CALLBACK_DUMP_FROM_SIGQUIT (1)
  55. +#define XC_TRACE_CALLBACK_DUMP_FROM_DUMP_TRACE (2)
  56. #define XC_TRACE_CALLBACK_METHOD_NAME "traceCallback"
  57. -#define XC_TRACE_CALLBACK_METHOD_SIGNATURE "(Ljava/lang/String;Ljava/lang/String;)V"
  58. +#define XC_TRACE_CALLBACK_METHOD_SIGNATURE "(Ljava/lang/String;Ljava/lang/String;J)V"
  59. #define XC_TRACE_SIGNAL_CATCHER_TID_UNLOAD (-2)
  60. #define XC_TRACE_SIGNAL_CATCHER_TID_UNKNOWN (-1)
  61. @@ -335,6 +337,7 @@ static void *xc_trace_dumper(void *arg)
  62. //write header info
  63. if(0 != xc_trace_write_header(fd, trace_time)) goto end;
  64. + if(0 != xcc_util_write_format(fd, "Dump From: '%s'\n\n", ((data == XC_TRACE_CALLBACK_DUMP_FROM_SIGQUIT) ? "SIGQUIT": "DUMP_TRACE"))) goto end;
  65. //write trace info from ART runtime
  66. if(0 != xcc_util_write_format(fd, XCC_UTIL_THREAD_SEP"Cmd line: %s\n", xc_common_process_name)) goto end;
  67. @@ -388,14 +391,13 @@ static void *xc_trace_dumper(void *arg)
  68. xc_common_close_trace_log(fd);
  69. //rethrow SIGQUIT to ART Signal Catcher
  70. - if(xc_trace_rethrow && (XC_TRACE_DUMP_ART_CRASH != xc_trace_dump_status)) xc_trace_send_sigquit();
  71. - xc_trace_dump_status = XC_TRACE_DUMP_END;
  72. + if(data == XC_TRACE_CALLBACK_DUMP_FROM_SIGQUIT && xc_trace_rethrow) xc_trace_send_sigquit();
  73. //JNI callback
  74. //Do we need to implement an emergency buffer for disk exhausted?
  75. if(NULL == xc_trace_cb_method) continue;
  76. if(NULL == (j_pathname = (*env)->NewStringUTF(env, pathname))) continue;
  77. - (*env)->CallStaticVoidMethod(env, xc_common_cb_class, xc_trace_cb_method, j_pathname, NULL);
  78. + (*env)->CallStaticVoidMethod(env, xc_common_cb_class, xc_trace_cb_method, j_pathname, NULL, data);
  79. XC_JNI_IGNORE_PENDING_EXCEPTION();
  80. (*env)->DeleteLocalRef(env, j_pathname);
  81. }
  82. @@ -418,11 +420,21 @@ static void xc_trace_handler(int sig, siginfo_t *si, void *uc)
  83. if(xc_trace_notifier >= 0)
  84. {
  85. - data = 1;
  86. + data = XC_TRACE_CALLBACK_DUMP_FROM_SIGQUIT;
  87. XCC_UTIL_TEMP_FAILURE_RETRY(write(xc_trace_notifier, &data, sizeof(data)));
  88. }
  89. }
  90. +//notify fd from java
  91. +void xc_trace_handler_dump_trace(void) {
  92. + uint64_t data;
  93. + if (xc_trace_notifier >= 0)
  94. + {
  95. + data = XC_TRACE_CALLBACK_DUMP_FROM_DUMP_TRACE;
  96. + XCC_UTIL_TEMP_FAILURE_RETRY(write(xc_trace_notifier, &data, sizeof(data)));
  97. + }
  98. +}
  99. +
  100. static void xc_trace_init_callback(JNIEnv *env)
  101. {
  102. if(NULL == xc_common_cb_class) return;
  103. diff --git a/third-party-libs/xcrash_lib/src/main/cpp/xcrash/xc_trace.h b/third-party-libs/xcrash_lib/src/main/cpp/xcrash/xc_trace.h
  104. index a0ec2fd7d..0a732c3eb 100644
  105. --- a/third-party-libs/xcrash_lib/src/main/cpp/xcrash/xc_trace.h
  106. +++ b/third-party-libs/xcrash_lib/src/main/cpp/xcrash/xc_trace.h
  107. @@ -51,6 +51,7 @@ int xc_trace_init(JNIEnv *env,
  108. int dump_fds,
  109. int dump_network_info);
  110. +void xc_trace_handler_dump_trace(void);
  111. #ifdef __cplusplus
  112. }
  113. #endif
  114. diff --git a/third-party-libs/xcrash_lib/src/main/java/xcrash/DumpTraceManager.java b/third-party-libs/xcrash_lib/src/main/java/xcrash/DumpTraceManager.java
  115. new file mode 100644
  116. index 000000000..97c0050af
  117. --- /dev/null
  118. +++ b/third-party-libs/xcrash_lib/src/main/java/xcrash/DumpTraceManager.java
  119. @@ -0,0 +1,33 @@
  120. +package xcrash;
  121. +
  122. +import java.util.Map;
  123. +
  124. +public class DumpTraceManager {
  125. +
  126. + public interface OnDumpTraceCallback{
  127. + void OnDumpTrace(String trace);
  128. + }
  129. +
  130. + public static void dumpTrace(final OnDumpTraceCallback callback) {
  131. + ICrashCallback iCallback = new ICrashCallback() {
  132. + @Override
  133. + public void onCrash(String logPath, String emergency) throws Exception {
  134. + XCrash.getLogger().i(Util.TAG, "xCrash receive dumpCallback callback, path: " + logPath);
  135. +
  136. + Map<String, String> map = TombstoneParser.parse(logPath, emergency);
  137. +
  138. + String trace = map.get(TombstoneParser.keyOtherThreads);
  139. +
  140. + TombstoneManager.deleteTombstone(logPath);
  141. +
  142. + callback.OnDumpTrace(trace);
  143. +
  144. + }
  145. + };
  146. +
  147. + //需要5.0以上而且打开anrenable
  148. + if (!XCrash.dumpTrace(iCallback)) {
  149. + callback.OnDumpTrace("");
  150. + }
  151. + }
  152. +}
  153. diff --git a/third-party-libs/xcrash_lib/src/main/java/xcrash/NativeHandler.java b/third-party-libs/xcrash_lib/src/main/java/xcrash/NativeHandler.java
  154. index f41c68afe..6aca6a2e3 100644
  155. --- a/third-party-libs/xcrash_lib/src/main/java/xcrash/NativeHandler.java
  156. +++ b/third-party-libs/xcrash_lib/src/main/java/xcrash/NativeHandler.java
  157. @@ -37,6 +37,8 @@ class NativeHandler {
  158. private static final String TAG = "xcrash";
  159. private static final NativeHandler instance = new NativeHandler();
  160. private long anrTimeoutMs = 25 * 1000;
  161. + private static final int DUMP_TRACE_FROM_SIGQUIT = 1;
  162. + private static final int DUMP_TRACE_FROM_DUMP_TRACE = 2;
  163. private Context ctx;
  164. private boolean crashRethrow;
  165. @@ -45,6 +47,7 @@ class NativeHandler {
  166. private boolean anrCheckProcessState;
  167. private ICrashCallback anrCallback;
  168. private ICrashCallback anrFastCallback;
  169. + private ICrashCallback dumpTraceCallBack;
  170. private boolean initNativeLibOk = false;
  171. @@ -154,6 +157,15 @@ class NativeHandler {
  172. }
  173. }
  174. + boolean dumpTrace(ICrashCallback dumpCallBack) {
  175. + if (initNativeLibOk && anrEnable) {
  176. + dumpTraceCallBack = dumpCallBack;
  177. + NativeHandler.nativeDumpTrace();
  178. + return true;
  179. + }
  180. + return false;
  181. + }
  182. +
  183. void notifyJavaCrashed() {
  184. if (initNativeLibOk && anrEnable) {
  185. NativeHandler.nativeNotifyJavaCrashed();
  186. @@ -235,7 +247,7 @@ class NativeHandler {
  187. // do NOT obfuscate this method
  188. @SuppressWarnings("unused")
  189. - private static void traceCallback(String logPath, String emergency) {
  190. + private static void traceCallback(String logPath, String emergency, long dumpTrace) {
  191. Log.i(TAG, "trace slow callback time: " + System.currentTimeMillis());
  192. if (TextUtils.isEmpty(logPath)) {
  193. @@ -248,8 +260,8 @@ class NativeHandler {
  194. //append background / foreground
  195. TombstoneManager.appendSection(logPath, "foreground", ActivityMonitor.getInstance().isApplicationForeground() ? "yes" : "no");
  196. - //check process ANR state
  197. - if (NativeHandler.getInstance().anrCheckProcessState) {
  198. + //check process ANR state,dumptrace不需要进行process
  199. + if (dumpTrace != DUMP_TRACE_FROM_DUMP_TRACE && NativeHandler.getInstance().anrCheckProcessState) {
  200. if (!Util.checkProcessAnrState(NativeHandler.getInstance().ctx, NativeHandler.getInstance().anrTimeoutMs)) {
  201. FileManager.getInstance().recycleLogFile(new File(logPath));
  202. return; //not an ANR
  203. @@ -270,7 +282,9 @@ class NativeHandler {
  204. return;
  205. }
  206. - ICrashCallback callback = NativeHandler.getInstance().anrCallback;
  207. + ICrashCallback callback = (dumpTrace == DUMP_TRACE_FROM_SIGQUIT)
  208. + ? NativeHandler.getInstance().anrCallback
  209. + : NativeHandler.getInstance().dumpTraceCallBack;
  210. if (callback != null) {
  211. try {
  212. callback.onCrash(anrLogPath, emergency);
  213. @@ -315,4 +329,6 @@ class NativeHandler {
  214. private static native void nativeNotifyJavaCrashed();
  215. private static native void nativeTestCrash(int runInNewThread);
  216. +
  217. + private static native void nativeDumpTrace();
  218. }
  219. diff --git a/third-party-libs/xcrash_lib/src/main/java/xcrash/XCrash.java b/third-party-libs/xcrash_lib/src/main/java/xcrash/XCrash.java
  220. index 73821b08f..250b849b2 100644
  221. --- a/third-party-libs/xcrash_lib/src/main/java/xcrash/XCrash.java
  222. +++ b/third-party-libs/xcrash_lib/src/main/java/xcrash/XCrash.java
  223. @@ -33,13 +33,17 @@ import android.text.TextUtils;
  224. @SuppressWarnings("unused")
  225. public final class XCrash {
  226. - private static boolean initialized = false;
  227. + public static boolean initialized = false;
  228. private static String appId = null;
  229. private static String appVersion = null;
  230. private static String logDir = null;
  231. private static ILogger logger = new DefaultLogger();
  232. public static String nativeLibDir = null;
  233. + public static boolean initialized(){
  234. + return initialized;
  235. + }
  236. +
  237. private XCrash() {
  238. }
  239. @@ -923,4 +927,8 @@ public final class XCrash {
  240. public static void testNativeCrash(boolean runInNewThread) {
  241. NativeHandler.getInstance().testNativeCrash(runInNewThread);
  242. }
  243. +
  244. + public static boolean dumpTrace(ICrashCallback dumpCallBack) {
  245. + return NativeHandler.getInstance().dumpTrace(dumpCallBack);
  246. + }
  247. }
  248. --
  249. 2.37.1 (Apple Git-137.1)