Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AAB] Feature: Support AAB And extractNativeLibs=false #140

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ ext {

POM_GROUP_ID = "com.iqiyi.xcrash"
POM_ARTIFACT_ID = "xcrash-android-lib"
POM_VERSION_NAME = "3.1.0"
POM_VERSION_NAME = "3.1.1"

POM_NAME = "xCrash Android Lib"
POM_DESCRIPTION = "xCrash provides the Android app with the ability to capture java crash, native crash and ANR."
Expand Down
8 changes: 8 additions & 0 deletions xcrash_lib/src/main/cpp/common/xcc_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@ extern "C" {
#define XCC_UTIL_SYSCALL_GETDENTS SYS_getdents64
#endif

#if defined(__LP64__)
#define LINKER_PATH "/system/bin/linker64"
#define LINKER_NAME "linker64"
#else
#define LINKER_PATH "/system/bin/linker"
#define LINKER_NAME "linker"
#endif

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpadded"
typedef struct
Expand Down
2 changes: 1 addition & 1 deletion xcrash_lib/src/main/cpp/common/xcc_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@
#ifndef XCC_VERSION_H
#define XCC_VERSION_H 1

#define XCC_VERSION_STR "xCrash 3.1.0"
#define XCC_VERSION_STR "xCrash 3.1.1"

#endif
4 changes: 4 additions & 0 deletions xcrash_lib/src/main/cpp/xcrash/xc_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ char *xc_common_app_id = NULL;
char *xc_common_app_version = NULL;
char *xc_common_app_lib_dir = NULL;
char *xc_common_log_dir = NULL;
int xc_use_linker = 0;

//process info
pid_t xc_common_process_id = 0;
Expand Down Expand Up @@ -130,6 +131,7 @@ int xc_common_init(int api_level,
const char *app_id,
const char *app_version,
const char *app_lib_dir,
int use_linker,
const char *log_dir)
{
int r = 0;
Expand Down Expand Up @@ -179,6 +181,8 @@ int xc_common_init(int api_level,
XC_COMMON_DUP_STR(app_version);
XC_COMMON_DUP_STR(app_lib_dir);
XC_COMMON_DUP_STR(log_dir);

xc_use_linker = use_linker;

//save kernel version
xc_util_get_kernel_version(buf, sizeof(buf));
Expand Down
2 changes: 2 additions & 0 deletions xcrash_lib/src/main/cpp/xcrash/xc_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ extern char *xc_common_app_id;
extern char *xc_common_app_version;
extern char *xc_common_app_lib_dir;
extern char *xc_common_log_dir;
extern int xc_use_linker;

//process info
extern pid_t xc_common_process_id;
Expand All @@ -86,6 +87,7 @@ int xc_common_init(int api_level,
const char *app_id,
const char *app_version,
const char *app_lib_dir,
int use_linker,
const char *log_dir);

int xc_common_open_crash_log(char *pathname, size_t pathname_len, int *from_placeholder);
Expand Down
6 changes: 5 additions & 1 deletion xcrash_lib/src/main/cpp/xcrash/xc_crash.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,11 @@ static int xc_crash_exec_dumper(void *arg)

//escape to the dumper process
errno = 0;
execl(xc_crash_dumper_pathname, XCC_UTIL_XCRASH_DUMPER_FILENAME, NULL);
if (xc_use_linker) {
execl(LINKER_PATH, LINKER_NAME, xc_crash_dumper_pathname, NULL);
} else {
execl(xc_crash_dumper_pathname, XCC_UTIL_XCRASH_DUMPER_FILENAME, NULL);
}
return 100 + errno;
}

Expand Down
3 changes: 3 additions & 0 deletions xcrash_lib/src/main/cpp/xcrash/xc_jni.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ static jint xc_jni_init(JNIEnv *env,
jstring app_id,
jstring app_version,
jstring app_lib_dir,
jboolean use_linker,
jstring log_dir,
jboolean crash_enable,
jboolean crash_rethrow,
Expand Down Expand Up @@ -133,6 +134,7 @@ static jint xc_jni_init(JNIEnv *env,
c_app_id,
c_app_version,
c_app_lib_dir,
use_linker ? 1 : 0,
c_log_dir)) goto clean;

r_crash = 0;
Expand Down Expand Up @@ -243,6 +245,7 @@ static JNINativeMethod xc_jni_methods[] = {
"Ljava/lang/String;"
"Ljava/lang/String;"
"Ljava/lang/String;"
"Z"
"Ljava/lang/String;"
"Z"
"Z"
Expand Down
134 changes: 134 additions & 0 deletions xcrash_lib/src/main/java/xcrash/AbiPathProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package xcrash;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;

import java.io.File;

import dalvik.system.PathClassLoader;

public class AbiPathProvider {

private static final String TAG = "AbiPathProvider";

public static final String XCRASH_DUMPER_LIB_NAME = "xcrash_dumper";

public static void test(Context context, String libName) {
Log.d(TAG, "getAbiPathFromDefault: " + getAbiPathFromDefault(context, libName));
Log.d(TAG, "getAbiPathFromClassloader: " + getAbiPathFromClassloader(context, libName));
Log.d(TAG, "getAbiPathFromSplit: " + getAbiPathFromSplit(context));
}

public static Pair<String, Boolean> getAbiPath(Context context, String libName) {
String abiPathFromDefault = getAbiPathFromDefault(context, libName);
if (!TextUtils.isEmpty(abiPathFromDefault) && isSoExist(abiPathFromDefault, libName)) {
return new Pair<>(abiPathFromDefault, false);
}

String abiPathFromClassloader = getAbiPathFromClassloader(context, libName);
if (!TextUtils.isEmpty(abiPathFromClassloader)) {
return new Pair<>(abiPathFromClassloader, true);
}

String abiPathFromSplit = getAbiPathFromSplit(context);
if (!TextUtils.isEmpty(abiPathFromSplit)) {
return new Pair<>(abiPathFromSplit, true);
}

return new Pair<>(context.getApplicationInfo().nativeLibraryDir, false);
}

private static String getAbiPathFromDefault(Context context, String libName) {
return context.getApplicationInfo().nativeLibraryDir;
}

private static boolean isSoExist(String nativeLibDir, String libName) {
File file = new File(nativeLibDir);
if (file.exists() && file.isDirectory()) {
File libFile = new File(file, System.mapLibraryName(libName));
return libFile.exists();
}
return false;
}

private static String getAbiPathFromClassloader(Context context, String libName) {
ClassLoader classLoader = context.getClassLoader();

Log.d(TAG, "classLoader: " + classLoader);

if (classLoader instanceof PathClassLoader) {
String libPath = ((PathClassLoader) classLoader).findLibrary(libName);
if (!TextUtils.isEmpty(libPath)) {
File parentFile = new File(libPath).getParentFile();
if (parentFile != null) {
return parentFile.getAbsolutePath();
}
}
}

return "";
}

private static String getAbiPathFromSplit(Context context) {
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
return "";
}

String[] splitSourceDirs = context.getApplicationInfo().splitSourceDirs;
AbiName currentAbi = AbiName.ARM64_V8A;
String path = null;
for (String splitSourceDir : splitSourceDirs) {
for (AbiName abiName : AbiName.values()) {
if (splitSourceDir.contains(abiName.getBundleAbi())) {
path = splitSourceDir;
break;
}
}
if (path != null) {
break;
}
}

if (!TextUtils.isEmpty(path)) {
return path + "!/lib/" + currentAbi.platformName;
}

return "";
}

enum AbiName {
ARM64_V8A("arm64-v8a", 64),
ARMEABI_V7A("armeabi-v7a", 32),
X86_64("x86_64", 64),
X86("x86", 32);

private final String platformName;
private final int bitSize;
private final String bundleAbi;

// Constructor for enum fields
AbiName(String platformName, int bitSize) {
this.platformName = platformName;
this.bitSize = bitSize;
this.bundleAbi = platformName.replace("-", "_");
}

// Getter for platformName
public String getPlatformName() {
return platformName;
}

// Getter for bitSize
public int getBitSize() {
return bitSize;
}

// Getter for bundleAbi
public String getBundleAbi() {
return bundleAbi;
}
}

}
20 changes: 18 additions & 2 deletions xcrash_lib/src/main/java/xcrash/NativeHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import android.os.Build;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;

import java.io.File;
import java.util.Map;
Expand Down Expand Up @@ -82,7 +83,9 @@ int initialize(Context ctx,
boolean anrDumpFds,
boolean anrDumpNetworkInfo,
ICrashCallback anrCallback,
ICrashCallback anrFastCallback) {
ICrashCallback anrFastCallback,
String nativeLibPath,
boolean loadNativeWithLinker) {
//load lib
if (libLoader == null) {
try {
Expand All @@ -109,6 +112,17 @@ int initialize(Context ctx,
this.anrFastCallback = anrFastCallback;
this.anrTimeoutMs = anrRethrow ? 25 * 1000 : 45 * 1000; //setting rethrow to "false" is NOT recommended

String nativeLibraryDir;
boolean useLinker;
if (!TextUtils.isEmpty(nativeLibPath)) {
nativeLibraryDir = nativeLibPath;
useLinker = loadNativeWithLinker;
} else {
Pair<String, Boolean> abiPath = AbiPathProvider.getAbiPath(ctx, AbiPathProvider.XCRASH_DUMPER_LIB_NAME);
nativeLibraryDir = abiPath.first;
useLinker = abiPath.second;
}

//init native lib
try {
int r = nativeInit(
Expand All @@ -121,7 +135,8 @@ int initialize(Context ctx,
Build.FINGERPRINT,
appId,
appVersion,
ctx.getApplicationInfo().nativeLibraryDir,
nativeLibraryDir,
useLinker,
logDir,
crashEnable,
crashRethrow,
Expand Down Expand Up @@ -291,6 +306,7 @@ private static native int nativeInit(
String appId,
String appVersion,
String appLibDir,
boolean useLinker,
String logDir,
boolean crashEnable,
boolean crashRethrow,
Expand Down
2 changes: 1 addition & 1 deletion xcrash_lib/src/main/java/xcrash/Version.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ class Version {
private Version() {
}

static final String version = "3.1.0";
static final String version = "3.1.1";
static final String fullVersion = "xCrash " + version;
}
25 changes: 24 additions & 1 deletion xcrash_lib/src/main/java/xcrash/XCrash.java
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,9 @@ public static synchronized int init(Context ctx, InitParameters params) {
params.anrDumpFds,
params.anrDumpNetworkInfo,
params.anrCallback,
params.anrFastCallback);
params.anrFastCallback,
params.nativeLibPath,
params.loadNativeWithLinker);
}

//maintain tombstone and placeholder files in a background thread with some delay
Expand Down Expand Up @@ -517,6 +519,9 @@ public InitParameters setJavaCallback(ICrashCallback callback) {
String[] nativeDumpAllThreadsWhiteList = null;
ICrashCallback nativeCallback = null;

String nativeLibPath = null;
boolean loadNativeWithLinker = false;

/**
* Enable the native crash capture feature. (Default: enable)
*
Expand Down Expand Up @@ -707,6 +712,24 @@ public InitParameters setNativeCallback(ICrashCallback callback) {
return this;
}

/**
* Set native library path
* @param nativeLibPath native library path
*/
public InitParameters setNativeLibPath(String nativeLibPath) {
this.nativeLibPath = nativeLibPath;
return this;
}

/**
* Set whether load native library with linker
* @param loadNativeWithLinker load native library with linker
*/
public InitParameters setLoadNativeWithLinker(boolean loadNativeWithLinker) {
this.loadNativeWithLinker = loadNativeWithLinker;
return this;
}

//anr
boolean enableAnrHandler = true;
boolean anrRethrow = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@
import android.app.Application;
import android.content.Context;
import android.util.Log;
import android.util.Pair;

import org.json.JSONObject;

import java.io.File;
import java.io.FileWriter;

import xcrash.AbiPathProvider;
import xcrash.TombstoneManager;
import xcrash.TombstoneParser;
import xcrash.XCrash;
Expand Down Expand Up @@ -78,6 +80,10 @@ public void onCrash(String logPath, String emergency) throws Exception {

Log.d(TAG, "xCrash SDK init: start");

Pair<String, Boolean> abiPath = AbiPathProvider.getAbiPath(this, AbiPathProvider.XCRASH_DUMPER_LIB_NAME);
String nativeLibraryDir = abiPath.first;
boolean loadNativeWithLinker = abiPath.second;

// Initialize xCrash.
XCrash.init(this, new XCrash.InitParameters()
.setAppVersion("1.2.3-beta456-patch789")
Expand All @@ -91,6 +97,8 @@ public void onCrash(String logPath, String emergency) throws Exception {
.setNativeDumpAllThreadsWhiteList(new String[]{"^xcrash\\.sample$", "^Signal Catcher$", "^Jit thread pool$", ".*(R|r)ender.*", ".*Chrome.*"})
.setNativeDumpAllThreadsCountMax(10)
.setNativeCallback(callback)
// .setNativeLibPath(nativeLibraryDir)
// .setLoadNativeWithLinker(loadNativeWithLinker)
// .setAnrCheckProcessState(false)
.setAnrRethrow(true)
.setAnrLogCountMax(10)
Expand Down