This commit is contained in:
LoveSy 2021-08-12 03:56:15 +08:00 committed by GitHub
parent e39ed434bc
commit a5febe8f86
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 53 additions and 56 deletions

View File

@ -63,6 +63,7 @@ jobs:
sudo apt-get install -y ccache sudo apt-get install -y ccache
ccache -o max_size=2G ccache -o max_size=2G
ccache -o hash_dir=false ccache -o hash_dir=false
ccache -o compiler_check=content
- name: Build with Gradle - name: Build with Gradle
env: env:
NDK_CCACHE: ccache NDK_CCACHE: ccache

View File

@ -42,7 +42,7 @@ val androidTargetSdkVersion by extra(31)
val androidMinSdkVersion by extra(27) val androidMinSdkVersion by extra(27)
val androidBuildToolsVersion by extra("31.0.0") val androidBuildToolsVersion by extra("31.0.0")
val androidCompileSdkVersion by extra(31) val androidCompileSdkVersion by extra(31)
val androidCompileNdkVersion by extra("22.1.7171670") val androidCompileNdkVersion by extra("23.0.7599858")
val androidSourceCompatibility by extra(JavaVersion.VERSION_11) val androidSourceCompatibility by extra(JavaVersion.VERSION_11)
val androidTargetCompatibility by extra(JavaVersion.VERSION_11) val androidTargetCompatibility by extra(JavaVersion.VERSION_11)
val apiCode by extra(93) val apiCode by extra(93)

View File

@ -31,9 +31,9 @@
namespace art { namespace art {
namespace art_method { namespace art_method {
CREATE_MEM_FUNC_SYMBOL_ENTRY(std::string, PrettyMethod, void *thiz, bool with_signature) { CREATE_MEM_FUNC_SYMBOL_ENTRY(std::string, PrettyMethod, void *thiz, bool with_signature) {
if (UNLIKELY(thiz == nullptr)) if (thiz == nullptr) [[unlikely]]
return "null"; return "null";
if (LIKELY(PrettyMethodSym)) if (PrettyMethodSym) [[likely]]
return PrettyMethodSym(thiz, with_signature); return PrettyMethodSym(thiz, with_signature);
else return "null sym"; else return "null sym";
} }

View File

@ -40,7 +40,7 @@ namespace art {
CREATE_MEM_FUNC_SYMBOL_ENTRY(void, SetEntryPointsToInterpreter, void *thiz, CREATE_MEM_FUNC_SYMBOL_ENTRY(void, SetEntryPointsToInterpreter, void *thiz,
void *art_method) { void *art_method) {
if (LIKELY(SetEntryPointsToInterpreterSym)) if (SetEntryPointsToInterpreterSym) [[likely]]
SetEntryPointsToInterpreterSym(thiz, art_method); SetEntryPointsToInterpreterSym(thiz, art_method);
} }
@ -49,7 +49,7 @@ namespace art {
art::mirror::Class mirror_class(clazz_ptr); art::mirror::Class mirror_class(clazz_ptr);
auto class_def = mirror_class.GetClassDef(); auto class_def = mirror_class.GetClassDef();
bool should_intercept = class_def && lspd::IsClassPending(class_def); bool should_intercept = class_def && lspd::IsClassPending(class_def);
if (UNLIKELY(should_intercept)) { if (should_intercept) [[unlikely]] {
LOGD("Pending hook for %p (%s)", clazz_ptr, LOGD("Pending hook for %p (%s)", clazz_ptr,
art::mirror::Class(clazz_ptr).GetDescriptor().c_str()); art::mirror::Class(clazz_ptr).GetDescriptor().c_str());
lspd::Context::GetInstance()->CallOnPostFixupStaticTrampolines(clazz_ptr); lspd::Context::GetInstance()->CallOnPostFixupStaticTrampolines(clazz_ptr);
@ -83,7 +83,7 @@ namespace art {
CREATE_MEM_FUNC_SYMBOL_ENTRY(void, MakeInitializedClassesVisiblyInitialized, void *thiz, CREATE_MEM_FUNC_SYMBOL_ENTRY(void, MakeInitializedClassesVisiblyInitialized, void *thiz,
void *self, bool wait) { void *self, bool wait) {
if (LIKELY(MakeInitializedClassesVisiblyInitializedSym)) if (MakeInitializedClassesVisiblyInitializedSym) [[likely]]
MakeInitializedClassesVisiblyInitializedSym(thiz, self, wait); MakeInitializedClassesVisiblyInitializedSym(thiz, self, wait);
} }
@ -93,7 +93,7 @@ namespace art {
bool, ShouldUseInterpreterEntrypoint, (void * art_method, bool, ShouldUseInterpreterEntrypoint, (void * art_method,
const void *quick_code), { const void *quick_code), {
if (quick_code != nullptr && if (quick_code != nullptr &&
UNLIKELY(lspd::isHooked(art_method) || lspd::IsMethodPending(art_method))) { lspd::isHooked(art_method) || lspd::IsMethodPending(art_method)) [[unlikely]] {
return false; return false;
} }
return backup(art_method, quick_code); return backup(art_method, quick_code);
@ -183,14 +183,14 @@ namespace art {
[[gnu::always_inline]] [[gnu::always_inline]]
void MakeInitializedClassesVisiblyInitialized(void *self, bool wait) const { void MakeInitializedClassesVisiblyInitialized(void *self, bool wait) const {
LOGD("MakeInitializedClassesVisiblyInitialized start, thiz=%p, self=%p", thiz_, self); LOGD("MakeInitializedClassesVisiblyInitialized start, thiz=%p, self=%p", thiz_, self);
if (LIKELY(thiz_)) if (thiz_) [[likely]]
MakeInitializedClassesVisiblyInitialized(thiz_, self, wait); MakeInitializedClassesVisiblyInitialized(thiz_, self, wait);
} }
[[gnu::always_inline]] [[gnu::always_inline]]
void SetEntryPointsToInterpreter(void *art_method) const { void SetEntryPointsToInterpreter(void *art_method) const {
LOGD("SetEntryPointsToInterpreter start, thiz=%p, art_method=%p", thiz_, art_method); LOGD("SetEntryPointsToInterpreter start, thiz=%p, art_method=%p", thiz_, art_method);
if (LIKELY(thiz_)) if (thiz_) [[likely]]
SetEntryPointsToInterpreter(thiz_, art_method); SetEntryPointsToInterpreter(thiz_, art_method);
} }

View File

@ -34,13 +34,13 @@ namespace art {
class ScopedGCCriticalSection { class ScopedGCCriticalSection {
CREATE_MEM_FUNC_SYMBOL_ENTRY(void, constructor, void *thiz, void* self, GcCause cause, CollectorType collector_type) { CREATE_MEM_FUNC_SYMBOL_ENTRY(void, constructor, void *thiz, void* self, GcCause cause, CollectorType collector_type) {
if (UNLIKELY(thiz == nullptr)) return; if (thiz == nullptr) [[unlikely]] return;
if (LIKELY(constructorSym)) if (constructorSym) [[likely]]
return constructorSym(thiz, self, cause, collector_type); return constructorSym(thiz, self, cause, collector_type);
} }
CREATE_MEM_FUNC_SYMBOL_ENTRY(void, destructor, void *thiz) { CREATE_MEM_FUNC_SYMBOL_ENTRY(void, destructor, void *thiz) {
if (UNLIKELY(thiz == nullptr)) return; if (thiz == nullptr) [[unlikely]] return;
if (LIKELY(destructorSym)) if (destructorSym) [[likely]]
return destructorSym(thiz); return destructorSym(thiz);
} }
public: public:

View File

@ -31,7 +31,7 @@ namespace art {
CREATE_FUNC_SYMBOL_ENTRY(void, DexFile_setTrusted, JNIEnv *env, jclass clazz, CREATE_FUNC_SYMBOL_ENTRY(void, DexFile_setTrusted, JNIEnv *env, jclass clazz,
jobject j_cookie) { jobject j_cookie) {
if (LIKELY(DexFile_setTrustedSym != nullptr)) { if (DexFile_setTrustedSym != nullptr) [[likely]] {
Runtime::Current()->SetJavaDebuggable(true); Runtime::Current()->SetJavaDebuggable(true);
DexFile_setTrustedSym(env, clazz, j_cookie); DexFile_setTrustedSym(env, clazz, j_cookie);
Runtime::Current()->SetJavaDebuggable(false); Runtime::Current()->SetJavaDebuggable(false);

View File

@ -29,7 +29,7 @@ namespace art {
CREATE_MEM_HOOK_STUB_ENTRIES( CREATE_MEM_HOOK_STUB_ENTRIES(
"_ZN3art15instrumentation15Instrumentation21UpdateMethodsCodeImplEPNS_9ArtMethodEPKv", "_ZN3art15instrumentation15Instrumentation21UpdateMethodsCodeImplEPNS_9ArtMethodEPKv",
void, UpdateMethodsCode, (void * thiz, void * art_method, const void *quick_code), { void, UpdateMethodsCode, (void * thiz, void * art_method, const void *quick_code), {
if (UNLIKELY(lspd::isHooked(art_method))) { if (lspd::isHooked(art_method)) [[unlikely]] {
LOGD("Skip update method code for hooked method %s", LOGD("Skip update method code for hooked method %s",
art_method::PrettyMethod(art_method).c_str()); art_method::PrettyMethod(art_method).c_str());
return; return;

View File

@ -42,7 +42,7 @@ namespace art {
} }
CREATE_MEM_FUNC_SYMBOL_ENTRY(void*, GetClassDef, void* thiz) { CREATE_MEM_FUNC_SYMBOL_ENTRY(void*, GetClassDef, void* thiz) {
if (LIKELY(GetClassDefSym)) if (GetClassDefSym) [[likely]]
return GetClassDefSym(thiz); return GetClassDefSym(thiz);
return nullptr; return nullptr;
} }

View File

@ -28,7 +28,7 @@ namespace art {
private: private:
inline static Runtime *instance_; inline static Runtime *instance_;
CREATE_MEM_FUNC_SYMBOL_ENTRY(void, SetJavaDebuggable, void *thiz, bool value) { CREATE_MEM_FUNC_SYMBOL_ENTRY(void, SetJavaDebuggable, void *thiz, bool value) {
if (LIKELY(SetJavaDebuggableSym)) { if (SetJavaDebuggableSym) [[likely]] {
SetJavaDebuggableSym(thiz, value); SetJavaDebuggableSym(thiz, value);
} }
} }

View File

@ -34,7 +34,7 @@ namespace art {
} }
CREATE_FUNC_SYMBOL_ENTRY(void *, CurrentFromGdb) { CREATE_FUNC_SYMBOL_ENTRY(void *, CurrentFromGdb) {
if (LIKELY(CurrentFromGdbSym)) if (CurrentFromGdbSym) [[likely]]
return CurrentFromGdbSym(); return CurrentFromGdbSym();
else else
return nullptr; return nullptr;
@ -55,7 +55,7 @@ namespace art {
} }
void *DecodeJObject(jobject obj) { void *DecodeJObject(jobject obj) {
if (LIKELY(thiz_ && DecodeJObjectSym)) { if (thiz_ && DecodeJObjectSym) [[likely]] {
return DecodeJObject(thiz_, obj).data; return DecodeJObject(thiz_, obj).data;
} }
return nullptr; return nullptr;

View File

@ -25,13 +25,13 @@ namespace art {
class ScopedSuspendAll { class ScopedSuspendAll {
CREATE_MEM_FUNC_SYMBOL_ENTRY(void, constructor, void *thiz, const char * cause, bool long_suspend) { CREATE_MEM_FUNC_SYMBOL_ENTRY(void, constructor, void *thiz, const char * cause, bool long_suspend) {
if (UNLIKELY(thiz == nullptr)) return; if (thiz == nullptr) [[unlikely]] return;
if (LIKELY(constructorSym)) if (constructorSym) [[likely]]
return constructorSym(thiz, cause, long_suspend); return constructorSym(thiz, cause, long_suspend);
} }
CREATE_MEM_FUNC_SYMBOL_ENTRY(void, destructor, void *thiz) { CREATE_MEM_FUNC_SYMBOL_ENTRY(void, destructor, void *thiz) {
if (UNLIKELY(thiz == nullptr)) return; if (thiz == nullptr) [[unlikely]] return;
if (LIKELY(destructorSym)) if (destructorSym) [[likely]]
return destructorSym(thiz); return destructorSym(thiz);
} }
public: public:

View File

@ -20,14 +20,9 @@
// used in defining new arrays, for example. If you use arraysize on // used in defining new arrays, for example. If you use arraysize on
// a pointer by mistake, you will get a compile-time error. // a pointer by mistake, you will get a compile-time error.
template<typename T, size_t N> template<typename T, size_t N>
[[gnu::always_inline]] constexpr size_t arraysize(T(&)[N]) { [[gnu::always_inline]] constexpr inline size_t arraysize(T(&)[N]) {
return N; return N;
} }
// Changing this definition will cause you a lot of pain. A majority of
// vendor code defines LIKELY and UNLIKELY this way, and includes
// this header through an indirect path.
#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
// Current ABI string // Current ABI string
#if defined(__arm__) #if defined(__arm__)
#define ABI_STRING "arm" #define ABI_STRING "arm"

View File

@ -42,7 +42,7 @@ namespace lspd {
constexpr int PER_USER_RANGE = 100000; constexpr int PER_USER_RANGE = 100000;
void Context::CallOnPostFixupStaticTrampolines(void *class_ptr) { void Context::CallOnPostFixupStaticTrampolines(void *class_ptr) {
if (UNLIKELY(!class_ptr || !class_linker_class_ || !post_fixup_static_mid_)) { if (!class_ptr || !class_linker_class_ || !post_fixup_static_mid_) [[unlikely]] {
return; return;
} }
@ -56,7 +56,7 @@ namespace lspd {
} }
void Context::PreLoadDex(std::string_view dex_path) { void Context::PreLoadDex(std::string_view dex_path) {
if (LIKELY(!dex.empty())) return; if (!dex.empty()) [[unlikely]] return;
FILE *f = fopen(dex_path.data(), "rb"); FILE *f = fopen(dex_path.data(), "rb");
if (!f) { if (!f) {
@ -80,7 +80,7 @@ namespace lspd {
auto getsyscl_mid = JNI_GetStaticMethodID( auto getsyscl_mid = JNI_GetStaticMethodID(
env, classloader, "getSystemClassLoader", "()Ljava/lang/ClassLoader;"); env, classloader, "getSystemClassLoader", "()Ljava/lang/ClassLoader;");
auto sys_classloader = JNI_CallStaticObjectMethod(env, classloader, getsyscl_mid); auto sys_classloader = JNI_CallStaticObjectMethod(env, classloader, getsyscl_mid);
if (UNLIKELY(!sys_classloader)) { if (!sys_classloader) [[unlikely]] {
LOGE("getSystemClassLoader failed!!!"); LOGE("getSystemClassLoader failed!!!");
return; return;
} }
@ -130,7 +130,7 @@ namespace lspd {
if (!mid) { if (!mid) {
mid = JNI_GetMethodID(env, clz, "findClass", "(Ljava/lang/String;)Ljava/lang/Class;"); mid = JNI_GetMethodID(env, clz, "findClass", "(Ljava/lang/String;)Ljava/lang/Class;");
} }
if (LIKELY(mid)) { if (mid) [[likely]] {
auto target = JNI_CallObjectMethod(env, class_loader, mid, auto target = JNI_CallObjectMethod(env, class_loader, mid,
env->NewStringUTF(class_name.data())); env->NewStringUTF(class_name.data()));
if (target) { if (target) {
@ -147,12 +147,12 @@ namespace lspd {
void void
Context::FindAndCall(JNIEnv *env, std::string_view method_name, std::string_view method_sig, Context::FindAndCall(JNIEnv *env, std::string_view method_name, std::string_view method_sig,
Args &&... args) const { Args &&... args) const {
if (UNLIKELY(!entry_class_)) { if (!entry_class_) [[unlikely]] {
LOGE("cannot call method %s, entry class is null", method_name.data()); LOGE("cannot call method %s, entry class is null", method_name.data());
return; return;
} }
jmethodID mid = JNI_GetStaticMethodID(env, entry_class_, method_name, method_sig); jmethodID mid = JNI_GetStaticMethodID(env, entry_class_, method_name, method_sig);
if (LIKELY(mid)) { if (mid) [[likely]] {
JNI_CallStaticVoidMethod(env, entry_class_, mid, std::forward<Args>(args)...); JNI_CallStaticVoidMethod(env, entry_class_, mid, std::forward<Args>(args)...);
} else { } else {
LOGE("method %s id is null", method_name.data()); LOGE("method %s id is null", method_name.data());

View File

@ -67,7 +67,7 @@ namespace lspd {
auto *class_ptr = art::Thread::Current().DecodeJObject(class_ref); auto *class_ptr = art::Thread::Current().DecodeJObject(class_ref);
auto *method = yahfa::getArtMethod(env, method_ref); auto *method = yahfa::getArtMethod(env, method_ref);
art::mirror::Class mirror_class(class_ptr); art::mirror::Class mirror_class(class_ptr);
if (auto def = mirror_class.GetClassDef(); LIKELY(def)) { if (auto def = mirror_class.GetClassDef(); def) [[likely]] {
LOGD("record pending: %p (%s) with %p", class_ptr, mirror_class.GetDescriptor().c_str(), LOGD("record pending: %p (%s) with %p", class_ptr, mirror_class.GetDescriptor().c_str(),
method); method);
// Add it for ShouldUseInterpreterEntrypoint // Add it for ShouldUseInterpreterEntrypoint

View File

@ -63,10 +63,9 @@ namespace lspd {
void RegisterNativeLib(const std::string &library_name) { void RegisterNativeLib(const std::string &library_name) {
static bool initialized = []() { static bool initialized = []() {
InstallNativeAPI(); return InstallNativeAPI();
return true;
}(); }();
if (UNLIKELY(!initialized)) return; if (!initialized) [[unlikely]] return;
LOGD("native_api: Registered %s", library_name.c_str()); LOGD("native_api: Registered %s", library_name.c_str());
moduleNativeLibs.push_back(library_name); moduleNativeLibs.push_back(library_name);
} }
@ -97,10 +96,10 @@ namespace lspd {
} }
for (std::string_view module_lib: moduleNativeLibs) { for (std::string_view module_lib: moduleNativeLibs) {
// the so is a module so // the so is a module so
if (UNLIKELY(hasEnding(ns, module_lib))) { if (hasEnding(ns, module_lib)) [[unlikely]] {
LOGD("Loading module native library %s", module_lib.data()); LOGD("Loading module native library %s", module_lib.data());
void *native_init_sym = dlsym(handle, "native_init"); void *native_init_sym = dlsym(handle, "native_init");
if (UNLIKELY(native_init_sym == nullptr)) { if (native_init_sym == nullptr) [[unlikely]] {
LOGD("Failed to get symbol \"native_init\" from library %s", LOGD("Failed to get symbol \"native_init\" from library %s",
module_lib.data()); module_lib.data());
break; break;
@ -122,9 +121,12 @@ namespace lspd {
return handle; return handle;
}); });
void InstallNativeAPI() { bool InstallNativeAPI() {
LOGD("InstallNativeAPI: %p", sym_do_dlopen); LOGD("InstallNativeAPI: %p", sym_do_dlopen);
if (sym_do_dlopen) if (sym_do_dlopen) [[likely]] {
HookSymNoHandle(sym_do_dlopen, do_dlopen); HookSymNoHandle(sym_do_dlopen, do_dlopen);
return true;
}
return false;
} }
} }

View File

@ -44,7 +44,7 @@ typedef struct {
typedef NativeOnModuleLoaded (*NativeInit)(const NativeAPIEntries *entries); typedef NativeOnModuleLoaded (*NativeInit)(const NativeAPIEntries *entries);
namespace lspd { namespace lspd {
void InstallNativeAPI(); bool InstallNativeAPI();
void RegisterNativeLib(const std::string &library_name); void RegisterNativeLib(const std::string &library_name);
} }

View File

@ -41,7 +41,7 @@ namespace lspd {
static std::atomic_bool installed = false; static std::atomic_bool installed = false;
void InstallInlineHooks() { void InstallInlineHooks() {
if (installed.exchange(true)) { if (installed.exchange(true)) [[unlikely]] {
LOGD("Inline hooks have been installed, skip"); LOGD("Inline hooks have been installed, skip");
return; return;
} }

View File

@ -39,7 +39,7 @@ namespace lspd {
code = va_arg(copy, jint); code = va_arg(copy, jint);
va_end(copy); va_end(copy);
if (UNLIKELY(code == BRIDGE_TRANSACTION_CODE)) { if (code == BRIDGE_TRANSACTION_CODE) [[unlikely]] {
*res = env->CallStaticBooleanMethodV(instance()->bridge_service_class_, *res = env->CallStaticBooleanMethodV(instance()->bridge_service_class_,
instance()->exec_transact_replace_methodID_, instance()->exec_transact_replace_methodID_,
args); args);
@ -52,16 +52,16 @@ namespace lspd {
jboolean jboolean
Service::call_boolean_method_va_replace(JNIEnv *env, jobject obj, jmethodID methodId, Service::call_boolean_method_va_replace(JNIEnv *env, jobject obj, jmethodID methodId,
va_list args) { va_list args) {
if (UNLIKELY(methodId == instance()->exec_transact_backup_methodID_)) { if (methodId == instance()->exec_transact_backup_methodID_) [[unlikely]] {
jboolean res = false; jboolean res = false;
if (LIKELY(exec_transact_replace(&res, env, obj, args))) return res; if (exec_transact_replace(&res, env, obj, args)) [[unlikely]] return res;
// else fallback to backup // else fallback to backup
} }
return instance()->call_boolean_method_va_backup_(env, obj, methodId, args); return instance()->call_boolean_method_va_backup_(env, obj, methodId, args);
} }
void Service::InitService(JNIEnv *env) { void Service::InitService(JNIEnv *env) {
if (LIKELY(initialized_)) return; if (initialized_) [[unlikely]] return;
// ServiceManager // ServiceManager
if (auto service_manager_class = JNI_FindClass(env, "android/os/ServiceManager")) if (auto service_manager_class = JNI_FindClass(env, "android/os/ServiceManager"))
@ -110,8 +110,8 @@ namespace lspd {
void Service::HookBridge(const Context &context, JNIEnv *env) { void Service::HookBridge(const Context &context, JNIEnv *env) {
static bool hooked = false; static bool hooked = false;
// This should only be ran once, so unlikely // This should only be ran once, so unlikely
if (UNLIKELY(hooked)) return; if (hooked) [[unlikely]] return;
if (UNLIKELY(!initialized_)) return; if (!initialized_) [[unlikely]] return;
hooked = true; hooked = true;
if (auto bridge_service_class = context.FindClassFromCurrentLoader(env, if (auto bridge_service_class = context.FindClassFromCurrentLoader(env,
kBridgeServiceClassName)) kBridgeServiceClassName))
@ -148,7 +148,7 @@ namespace lspd {
} }
ScopedLocalRef<jobject> Service::RequestBinder(JNIEnv *env, jstring nice_name) { ScopedLocalRef<jobject> Service::RequestBinder(JNIEnv *env, jstring nice_name) {
if (UNLIKELY(!initialized_)) { if (!initialized_) [[unlikely]] {
LOGE("Service not initialized"); LOGE("Service not initialized");
return {env, nullptr}; return {env, nullptr};
} }
@ -192,7 +192,7 @@ namespace lspd {
} }
ScopedLocalRef<jobject> Service::RequestBinderForSystemServer(JNIEnv *env) { ScopedLocalRef<jobject> Service::RequestBinderForSystemServer(JNIEnv *env) {
if (UNLIKELY(!initialized_ || !bridge_service_class_)) { if (!initialized_ || !bridge_service_class_) [[unlikely]] {
LOGE("Service not initialized"); LOGE("Service not initialized");
return {env, nullptr}; return {env, nullptr};
} }

View File

@ -65,12 +65,11 @@ namespace lspd {
} }
void InitSymbolCache() { void InitSymbolCache() {
if (UNLIKELY(sym_initialized)) return;
LOGD("InitSymbolCache"); LOGD("InitSymbolCache");
sym_initialized = FindLibArt(); sym_initialized = FindLibArt();
sym_do_dlopen = SandHook::ElfImg("linker").getSymbAddress<void *>( sym_do_dlopen = SandHook::ElfImg("linker").getSymbAddress<void *>(
"__dl__Z9do_dlopenPKciPK17android_dlextinfoPKv"); "__dl__Z9do_dlopenPKciPK17android_dlextinfoPKv");
if (UNLIKELY(!sym_initialized)) { if (!sym_initialized) [[unlikely]] {
sym_initialized = false; sym_initialized = false;
art_img.reset(); art_img.reset();
LOGE("Init symbol cache failed"); LOGE("Init symbol cache failed");