Skip to content

Commit

Permalink
Merge pull request #9 from SYGObject/bugfix_unwind64_and_dlclose
Browse files Browse the repository at this point in the history
修复Crash&64位unwind效率
  • Loading branch information
shentianzhou authored and shentianzhou committed Jun 18, 2021
2 parents 8b22c4f + fd981b8 commit 19488c1
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 13 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ allprojects {
Step 2: Add the dependency
```gradle
dependencies {
implementation 'com.github.bytedance:memory-leak-detector:0.1.1'
implementation 'com.github.bytedance:memory-leak-detector:0.1.3'
}
```

Expand Down
2 changes: 1 addition & 1 deletion README_cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ allprojects {
Step 2: Add the dependency
```gradle
dependencies {
implementation 'com.github.bytedance:memory-leak-detector:0.1.1'
implementation 'com.github.bytedance:memory-leak-detector:0.1.3'
}
```

Expand Down
2 changes: 1 addition & 1 deletion demo/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
api project(':library')
implementation 'com.android.support:appcompat-v7:28.0.0'
// implementation 'com.github.bytedance:memory-leak-detector:0.1.1'
// implementation 'com.github.bytedance:memory-leak-detector:0.1.2'
}
1 change: 1 addition & 0 deletions library/src/main/cpp/HookProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ void registerInlineProxy(JNIEnv *env) {
}
inlineHookAll();
#else
init_arm64_unwind();
for (int i = 0; i < PROXY_MAPPING_LENGTH; i++) {
A64HookFunction((void *) sInline[i][1], (void *) sInline[i][2], (void **) sInline[i][3]);
}
Expand Down
10 changes: 4 additions & 6 deletions library/src/main/cpp/PltGotHookProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,8 @@ static const void *sSoLoad[][3] = {
};

static void tryHookAllFunc(xh_elf_t elf) {
if (isPss) {
for (int i = 0; i < sizeof(sPltGot) / sizeof(sPltGot[0]); i++) {
xh_elf_hook(&elf, (const char *) sPltGot[i][0], (void *) sPltGot[i][1], NULL);
}
for (int i = 0; i < sizeof(sPltGot) / sizeof(sPltGot[0]); i++) {
xh_elf_hook(&elf, (const char *) sPltGot[i][0], (void *) sPltGot[i][1], NULL);
}
}

Expand Down Expand Up @@ -257,7 +255,7 @@ int default_callback(const char *name, uintptr_t base) {
if (0 != xh_elf_init(&elf, base, name)) {
return 0;
}
if (use_regex || (regexec(&focused_regex, name, 0, NULL, 0) == 0)) {
if (!use_regex || (regexec(&focused_regex, name, 0, NULL, 0) == 0)) {
tryHookAllFunc(elf);
}
tryHookSoLoadFunc(elf, true);
Expand Down Expand Up @@ -334,8 +332,8 @@ int registerSoLoadProxy(JNIEnv *env, jstring focused) {
dlopen_ext_N = (void *(*)(const char *, int, const void *, const void *)) (xdl_sym(dl,
DLOPEN_EXT_SYMBOL_N));
g_dl_mutex = (pthread_mutex_t *) (xdl_sym(dl, DLOPEN_MUTEX_SYMBOL_N));
xdl_close(dl);
}
xdl_close(&dl);
}

xdl_iterate_phdr(dl_iterate_callback, NULL, XDL_FULL_PATHNAME);
Expand Down
1 change: 0 additions & 1 deletion library/src/main/cpp/Raphael.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ void Raphael::start(JNIEnv *env, jobject obj, jint configs, jstring space, jstri

if (regex != nullptr) {
registerSoLoadProxy(env, regex);
//registerPltGotProxy(env, regex);
} else {
registerInlineProxy(env);
}
Expand Down
52 changes: 49 additions & 3 deletions library/src/main/unwind64/backtrace_64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,70 @@
*/

#include "backtrace_64.h"
#include <sys/resource.h>
#include <cinttypes>
#include <cstring>
#include <unistd.h>

static uintptr_t fp_main_thread_stack_low = 0;
static uintptr_t fp_main_thread_stack_high = 0;

static pthread_key_t thread_t_key;
static pthread_key_t thread_b_key;
static bool use_thread_local = false;

void init_arm64_unwind() {
if (pthread_key_create(&thread_t_key, nullptr) != 0) {
return;
}
if (pthread_key_create(&thread_b_key, nullptr) != 0) {
pthread_key_delete(thread_t_key);
return;
}
use_thread_local = true;
}

size_t unwind_backtrace(uintptr_t *stack, size_t max_depth) {
uintptr_t st; // stack top
uintptr_t sb; // stack bottom
GetStackRange(&st, &sb);
if (use_thread_local) {
if ((st = (uintptr_t) pthread_getspecific(thread_t_key)) == 0 ||
(sb = (uintptr_t) pthread_getspecific(thread_b_key)) == 0) {
GetStackRange(&st, &sb);
pthread_setspecific(thread_t_key, (void *) st);
pthread_setspecific(thread_b_key, (void *) sb);
}
} else {
if (gettid() == getpid()) {
if (fp_main_thread_stack_low == 0 || fp_main_thread_stack_high == 0) {
GetStackRange(&st, &sb);
fp_main_thread_stack_high = st;
fp_main_thread_stack_low = sb;
} else {
st = fp_main_thread_stack_high;
sb = fp_main_thread_stack_low;
}
} else {
GetStackRange(&st, &sb);
}
}

uintptr_t fp = (uintptr_t) __builtin_frame_address(0);
auto fp = (uintptr_t) __builtin_frame_address(0);

size_t depth = 0;
uintptr_t pc = 0;
while (isValid(fp, st, sb) && depth < max_depth) {
uintptr_t tt = *((uintptr_t *) fp + 1);
uintptr_t pre = *((uintptr_t *) fp);
if (pre & 0xfu || pre < fp + kFrameSize) {
break;
}
if (tt != pc) {
stack[depth++] = tt;
}
pc = tt;
sb = fp;
fp = *((uintptr_t *) fp);
fp = pre;
}
return depth;
}
2 changes: 2 additions & 0 deletions library/src/main/unwind64/backtrace_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ static inline void GetStackRange(uintptr_t *st, uintptr_t *sb) {
__attribute__((visibility("default")))
size_t unwind_backtrace(uintptr_t *stack, size_t max_depth);

void init_arm64_unwind();

#ifdef __cplusplus
}
#endif
Expand Down

0 comments on commit 19488c1

Please sign in to comment.