Skip to content

Commit 6a81584

Browse files
authored
Merge pull request #623 from Tencent/feature/dev-2.0.0-beta
Fix several bugs
2 parents 683ce12 + ca1a10a commit 6a81584

File tree

15 files changed

+352
-151
lines changed

15 files changed

+352
-151
lines changed

README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ At this point, Matrix has been integrated into the app and is beginning to colle
127127

128128
- **Trace Canary:**
129129

130-
FPS Monitor, Startup Performance, UI-Block / Slow Method Detection
130+
FPS Monitor, Startup Performance, ANR, UI-Block / Slow Method Detection
131131

132132
- **SQLite Lint:**
133133

@@ -161,6 +161,7 @@ At this point, Matrix has been integrated into the app and is beginning to colle
161161
- **Accurate call stack of ui-block.** Provide informations such as call stack, function cost, execution times to solve the problem of ui-block quickly.
162162
- **Non-hack.** High compatibility to Android versions.
163163
- **More features.** Automatically covers multiple fluency indicators such as ui-block, startup time, activity switching, slow function detection.
164+
- **High-accuracy ANR detector.** Detect ANRs accurately and give ANR trace file with high compatibility and high stability.
164165

165166
#### SQLite Lint
166167

@@ -520,7 +521,7 @@ curBuilder.pluginListener = <一个遵循 MatrixPluginListenerDelegate 的对象
520521

521522
## Demo
522523

523-
至此,Matrix 已经集成到应用中并且开始收集崩溃、卡顿和爆内存数据,如仍有疑问,请查看示例:`samples/sample-apple/MatrixDemo`
524+
至此,Matrix 已经集成到应用中并且开始收集崩溃、ANR、卡顿和爆内存数据,如仍有疑问,请查看示例:`samples/sample-apple/MatrixDemo`
524525

525526

526527
# <a name='matrix_android_cn'>Matrix for Android </a>
@@ -531,7 +532,7 @@ Matrix-android 当前监控范围包括:应用安装包大小,帧率变化
531532
- Resource Canary:
532533
基于 WeakReference 的特性和 [Square Haha](https://github.com/square/haha) 库开发的 Activity 泄漏和 Bitmap 重复创建检测工具
533534
- Trace Canary:
534-
监控界面流畅性、启动耗时、页面切换耗时、慢函数及卡顿等问题
535+
监控ANR、界面流畅性、启动耗时、页面切换耗时、慢函数及卡顿等问题
535536
- SQLite Lint:
536537
按官方最佳实践自动化检测 SQLite 语句的使用质量
537538
- IO Canary:
@@ -560,6 +561,7 @@ Matrix-android 当前监控范围包括:应用安装包大小,帧率变化
560561
- 编译期动态修改字节码, 高性能记录执行耗时与调用堆栈
561562
- 准确的定位到发生卡顿的函数,提供执行堆栈、执行耗时、执行次数等信息,帮助快速解决卡顿问题
562563
- 自动涵盖卡顿、启动耗时、页面切换、慢函数检测等多个流畅性指标
564+
- 准确监控ANR,并且能够高兼容性和稳定性地保存系统产生的ANR Trace文件
563565

564566
#### SQLite Lint
565567

@@ -701,7 +703,7 @@ Matrix-android 当前监控范围包括:应用安装包大小,帧率变化
701703
6. 选择程序启动的位置对 Matrix 进行初始化,如在 Application 的继承类中, Init 核心逻辑如下:
702704
``` java
703705
Matrix.Builder builder = new Matrix.Builder(application); // build matrix
704-
builder.patchListener(new TestPluginListener(this)); // add general pluginListener
706+
builder.pluginListener(new TestPluginListener(this)); // add general pluginListener
705707
DynamicConfigImplDemo dynamicConfig = new DynamicConfigImplDemo(); // dynamic config
706708
707709
// init plugin

matrix/matrix-android/matrix-android-commons/src/main/cpp/libxhook/xh_core.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,52 @@ static int xh_check_loaded_so(void *addr) {
312312
return dladdr(addr, &stack_info);
313313
}
314314

315+
struct {
316+
const char* reversed_suffix;
317+
size_t reversed_suffix_len;
318+
} s_reversed_candidate_suffixes[] = {
319+
{"os.", sizeof("os.") - 1},
320+
#ifdef __LP64__
321+
{"46reknil/", sizeof("46reknil/") - 1},
322+
#else
323+
{"reknil/", sizeof("reknil/") - 1},
324+
#endif
325+
};
326+
327+
/**
328+
* Judge if specified path is ** NOT ** ends with '.so' and '/linker', '/linker64'
329+
* return 1 if such path should not be considered to do further parsing.
330+
*/
331+
static int xh_is_not_candidate_path(const char* pathname) {
332+
if (pathname == NULL) {
333+
return 1;
334+
}
335+
size_t pathname_len = strlen(pathname);
336+
size_t reversed_suffix_count = sizeof(s_reversed_candidate_suffixes) / sizeof(s_reversed_candidate_suffixes[0]);
337+
338+
int idx = 0;
339+
int not_match_all_suffixes = 1;
340+
for (const char* ch = pathname + pathname_len - 1; ch != pathname; --ch, ++idx) {
341+
not_match_all_suffixes = 1;
342+
for (int suffix_idx = 0; suffix_idx < reversed_suffix_count; ++suffix_idx) {
343+
size_t reversed_suffix_len = s_reversed_candidate_suffixes[suffix_idx].reversed_suffix_len;
344+
if (idx >= reversed_suffix_len) {
345+
not_match_all_suffixes = 0;
346+
break;
347+
}
348+
const char* reversed_suffix = s_reversed_candidate_suffixes[suffix_idx].reversed_suffix;
349+
if (reversed_suffix[idx] == *ch) {
350+
not_match_all_suffixes = 0;
351+
break;
352+
}
353+
}
354+
if (not_match_all_suffixes) {
355+
break;
356+
}
357+
}
358+
return not_match_all_suffixes;
359+
}
360+
315361
static void xh_core_refresh_impl()
316362
{
317363
char line[512];
@@ -364,6 +410,7 @@ static void xh_core_refresh_impl()
364410
}
365411
if(0 == pathname_len) continue;
366412
if('[' == pathname[0]) continue;
413+
if (xh_is_not_candidate_path(pathname)) continue;
367414

368415
//check pathname
369416
//if we need to hook this elf?

matrix/matrix-android/matrix-android-commons/src/main/cpp/libxhook/xh_elf.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -365,9 +365,12 @@ static int xh_elf_hash_lookup(xh_elf_t *self, const char *symbol, uint32_t *symi
365365

366366
if(0 == strcmp(symbol, symbol_cur))
367367
{
368-
*symidx = i;
369-
XH_LOG_INFO("found %s at symidx: %u (ELF_HASH)\n", symbol, *symidx);
370-
return 0;
368+
ElfW(Sym)* sym = self->symtab + i;
369+
if (ELF_ST_TYPE(sym->st_info) == STT_FUNC) {
370+
*symidx = i;
371+
XH_LOG_INFO("found %s at symidx: %u (ELF_HASH)\n", symbol, *symidx);
372+
return 0;
373+
}
371374
}
372375
}
373376

@@ -399,9 +402,12 @@ static int xh_elf_gnu_hash_lookup_def(xh_elf_t *self, const char *symbol, uint32
399402

400403
if((hash | (uint32_t)1) == (symhash | (uint32_t)1) && 0 == strcmp(symbol, symname))
401404
{
402-
*symidx = i;
403-
XH_LOG_INFO("found %s at symidx: %u (GNU_HASH DEF)\n", symbol, *symidx);
404-
return 0;
405+
ElfW(Sym)* sym = self->symtab + i;
406+
if (ELF_ST_TYPE(sym->st_info) == STT_FUNC) {
407+
*symidx = i;
408+
XH_LOG_INFO("found %s at symidx: %u (GNU_HASH DEF)\n", symbol, *symidx);
409+
return 0;
410+
}
405411
}
406412

407413
//chain ends with an element with the lowest bit set to 1
@@ -422,9 +428,12 @@ static int xh_elf_gnu_hash_lookup_undef(xh_elf_t *self, const char *symbol, uint
422428
const char *symname = self->strtab + self->symtab[i].st_name;
423429
if(0 == strcmp(symname, symbol))
424430
{
425-
*symidx = i;
426-
XH_LOG_INFO("found %s at symidx: %u (GNU_HASH UNDEF)\n", symbol, *symidx);
427-
return 0;
431+
ElfW(Sym)* sym = self->symtab + i;
432+
if (ELF_ST_TYPE(sym->st_info) == STT_FUNC) {
433+
*symidx = i;
434+
XH_LOG_INFO("found %s at symidx: %u (GNU_HASH UNDEF)\n", symbol, *symidx);
435+
return 0;
436+
}
428437
}
429438
}
430439
return XH_ERRNO_NOTFND;

matrix/matrix-android/matrix-hooks/src/main/cpp/common/HookCommon.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
xhook_ignore(".*/libmatrix-hookcommon\\.so$", nullptr); \
9090
xhook_ignore(".*/libmatrix-memoryhook\\.so$", nullptr); \
9191
xhook_ignore(".*/libmatrix-pthreadhook\\.so$", nullptr); \
92+
xhook_ignore(".*/libmatrix-opengl-leak\\.so$", nullptr); \
9293
} while (0)
9394

9495
#include <vector>

matrix/matrix-android/matrix-hooks/src/main/cpp/common/JNICommon.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,10 @@ extern "C" {
3737

3838
JavaVM *m_java_vm;
3939

40-
static std::atomic_flag s_prehook_initialized(false);
41-
static std::atomic_flag s_finalhook_initialized(false);
40+
static volatile bool s_prehook_initialized = false;
41+
static std::mutex s_prehook_init_mutex;
42+
static volatile bool s_finalook_initialized = false;
43+
static std::mutex s_finalhook_init_mutex;
4244
jclass m_class_HookManager;
4345
jmethodID m_method_getStack;
4446

@@ -72,8 +74,10 @@ static jmethodID GetStaticMethodID(JNIEnv* env, jclass clazz, const char* name,
7274
return mid;
7375
}
7476

75-
JNIEXPORT jboolean Java_com_tencent_matrix_hook_HookManager_doPreHookInitializeNative(JNIEnv *env, jobject) {
76-
if (s_prehook_initialized.test_and_set()) {
77+
JNIEXPORT jboolean Java_com_tencent_matrix_hook_HookManager_doPreHookInitializeNative(JNIEnv *env, jobject, jboolean /* debug */) {
78+
std::lock_guard prehookInitLock(s_prehook_init_mutex);
79+
80+
if (s_prehook_initialized) {
7781
LOGE(TAG, "doPreHookInitializeNative was already called.");
7882
return true;
7983
}
@@ -107,22 +111,32 @@ JNIEXPORT jboolean Java_com_tencent_matrix_hook_HookManager_doPreHookInitializeN
107111

108112
getStackMethodCleaner.Omit();
109113
jHookMgrCleaner.Omit();
114+
115+
s_prehook_initialized = true;
110116
return true;
111117
}
112118

113119
JNIEXPORT void JNICALL
114-
Java_com_tencent_matrix_hook_HookManager_doFinalInitializeNative(JNIEnv *env, jobject thiz) {
115-
if (s_finalhook_initialized.test_and_set()) {
120+
Java_com_tencent_matrix_hook_HookManager_doFinalInitializeNative(JNIEnv *env, jobject thiz, jboolean debug) {
121+
std::lock_guard finalInitLock(s_finalhook_init_mutex);
122+
123+
if (s_finalook_initialized) {
116124
LOGE(TAG, "doFinalInitializeNative was already called.");
117125
return;
118126
}
119127

120128
wechat_backtrace::notify_maps_changed();
129+
130+
xhook_enable_debug(debug ? 1 : 0);
131+
xhook_enable_sigsegv_protection(debug ? 0 : 1);
132+
121133
// This line only refresh xhook in matrix-hookcommon library now.
122134
int ret = xhook_refresh(0);
123135
if (ret != 0) {
124136
LOGE(TAG, "Fail to call xhook_refresh, ret: %d", ret);
125137
}
138+
139+
s_finalook_initialized = true;
126140
}
127141

128142
#ifdef __cplusplus

0 commit comments

Comments
 (0)