diff --git a/.gitignore b/.gitignore index ec815e8..82b1a68 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,11 @@ .DS_Store -libs/ -obj/ - build/ +.cxx/ .gradle/ .idea/ *.iml *.log *.so +wrap.sh local.properties diff --git a/README.md b/README.md index 6c46590..f54bc95 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,19 @@ +

xCrash Logo

+ # xCrash ![](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat) ![](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat) -![](https://img.shields.io/badge/release-2.4.8-red.svg?style=flat) -![](https://img.shields.io/badge/Android-4.0%20--%2010-blue.svg?style=flat) -![](https://img.shields.io/badge/arch-armeabi%20%7C%20armeabi--v7a%20%7C%20arm64--v8a%20%7C%20x86%20%7C%20x86__64-blue.svg?style=flat) +![](https://img.shields.io/badge/release-3.0.0-red.svg?style=flat) +![](https://img.shields.io/badge/Android-4.1%20--%2011-blue.svg?style=flat) +![](https://img.shields.io/badge/armeabi--v7a%20%7C%20arm64--v8a%20%7C%20x86%20%7C%20x86__64-blue.svg?style=flat) xCrash provides the Android app with the ability to capture java crash, native crash and ANR. No root permission or any system permissions are required. -xCrash can generate a tombstone file (similar format as Android system's tombstone file) in the directory you specified when the app process crashes or ANRs. -

intro

+xCrash can generate a tombstone file (similar format as Android system's tombstone file) in the directory you specified when the app process crashes or ANRs. + xCrash has been used in many Android apps (including iQIYI video) on different platforms (mobile, tablet, TV) of [iQIYI](http://www.iqiyi.com/) for many years. [README 中文版](README.zh-CN.md) @@ -19,8 +21,8 @@ xCrash has been used in many Android apps (including iQIYI video) on different p ## Features -* Support Android 4.0 - 10 (API level 14 - 29). -* Support armeabi, armeabi-v7a, arm64-v8a, x86 and x86_64. +* Support Android 4.1 - 11 (API level 16 - 30). +* Support armeabi-v7a, arm64-v8a, x86 and x86_64. * Capturing java crash, native crash and ANR. * Dumping detailed statistics about process, threads, memory, FD and network. * Setting which thread's info should be dumped via regular expressions. @@ -30,12 +32,10 @@ xCrash has been used in many Android apps (including iQIYI video) on different p ## Tombstone File Previews * [java crash](doc/tombstone_java.txt) -* [native crash (armeabi)](doc/tombstone_native_armeabi.txt) * [native crash (armeabi-v7a)](doc/tombstone_native_armeabi-v7a.txt) * [native crash (arm64-v8a)](doc/tombstone_native_arm64-v8a.txt) * [native crash (x86)](doc/tombstone_native_x86.txt) * [native crash (x86_64)](doc/tombstone_native_x86_64.txt) -* [ANR (armeabi)](doc/tombstone_anr_armeabi.txt) * [ANR (armeabi-v7a)](doc/tombstone_anr_armeabi-v7a.txt) * [ANR (arm64-v8a)](doc/tombstone_anr_arm64-v8a.txt) * [ANR (x86)](doc/tombstone_anr_x86.txt) @@ -62,7 +62,7 @@ xCrash has been used in many Android apps (including iQIYI video) on different p ```Gradle dependencies { - implementation 'com.iqiyi.xcrash:xcrash-android-lib:2.4.8' + implementation 'com.iqiyi.xcrash:xcrash-android-lib:3.0.0' } ``` @@ -72,7 +72,7 @@ dependencies { android { defaultConfig { ndk { - abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64' + abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64' } } } @@ -109,39 +109,26 @@ class MyCustomApplication : Application() { Tombstone files will be written to `Context#getFilesDir() + "/tombstones"` directory by default. (usually in: `/data/data/PACKAGE_NAME/files/tombstones`) -There is a more practical and complex sample app in the [src/java/xcrash/xcrash_sample](src/java/xcrash/xcrash_sample) folder. +There is a more practical and complex sample app in the [xcrash_sample](xcrash_sample) folder. ## Build If you want to build xCrash from source code. Follow this guide: -#### 1. Download [Android NDK r16b](https://developer.android.com/ndk/downloads/revision_history.html), set PATH environment. -#### 2. Build and copy the native libraries. +#### Build AAR library. ``` -cd ./src/native/ -./build.sh -./install.sh -``` - -#### 3. Build AAR library. - -``` -cd ./src/java/xcrash/ ./gradlew :xcrash_lib:build ``` ## Support -1. Check the [xcrash-sample](src/java/xcrash/xcrash_sample). -2. Communicate on [GitHub issues](https://github.com/iqiyi/xCrash/issues). -3. Email: caikelun@gmail.com -4. QQ group: 603635869. QR code: - -

qq group

+* [GitHub Issues](https://github.com/iqiyi/xCrash/issues) +* [GitHub Discussions](https://github.com/iqiyi/xCrash/discussions) +* Email: caikelun@gmail.com, xuqnqn@qq.com ## Contributing diff --git a/README.zh-CN.md b/README.zh-CN.md index 39fdd62..69d8521 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -1,17 +1,19 @@ +

xCrash Logo

+ # xCrash ![](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat) ![](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat) -![](https://img.shields.io/badge/release-2.4.8-red.svg?style=flat) -![](https://img.shields.io/badge/Android-4.0%20--%2010-blue.svg?style=flat) -![](https://img.shields.io/badge/arch-armeabi%20%7C%20armeabi--v7a%20%7C%20arm64--v8a%20%7C%20x86%20%7C%20x86__64-blue.svg?style=flat) +![](https://img.shields.io/badge/release-3.0.0-red.svg?style=flat) +![](https://img.shields.io/badge/Android-4.1%20--%2011-blue.svg?style=flat) +![](https://img.shields.io/badge/armeabi--v7a%20%7C%20arm64--v8a%20%7C%20x86%20%7C%20x86__64-blue.svg?style=flat) xCrash 能为安卓 app 提供捕获 java 崩溃,native 崩溃和 ANR 的能力。不需要 root 权限或任何系统权限。 -xCrash 能在 app 进程崩溃或 ANR 时,在你指定的目录中生成一个 tombstone 文件(格式与安卓系统的 tombstone 文件类似)。 -

intro

+xCrash 能在 app 进程崩溃或 ANR 时,在你指定的目录中生成一个 tombstone 文件(格式与安卓系统的 tombstone 文件类似)。 + xCrash 已经在 [爱奇艺](http://www.iqiyi.com/) 的不同平台(手机,平板,电视)的很多安卓 app(包括爱奇艺视频)中被使用了很多年。 [README English Version](README.md) @@ -19,8 +21,8 @@ xCrash 已经在 [爱奇艺](http://www.iqiyi.com/) 的不同平台(手机, ## 特征 -* 支持 Android 4.0 - 10(API level 14 - 29)。 -* 支持 armeabi,armeabi-v7a,arm64-v8a,x86 和 x86_64。 +* 支持 Android 4.1 - 11(API level 16 - 30)。 +* 支持 armeabi-v7a,arm64-v8a,x86 和 x86_64。 * 捕获 java 崩溃,native 崩溃和 ANR。 * 获取详细的进程、线程、内存、FD、网络统计信息。 * 通过正则表达式设置需要获取哪些线程的信息。 @@ -30,12 +32,10 @@ xCrash 已经在 [爱奇艺](http://www.iqiyi.com/) 的不同平台(手机, ## Tombstone 文件预览 * [java 崩溃](doc/tombstone_java.txt) -* [native 崩溃 (armeabi)](doc/tombstone_native_armeabi.txt) * [native 崩溃 (armeabi-v7a)](doc/tombstone_native_armeabi-v7a.txt) * [native 崩溃 (arm64-v8a)](doc/tombstone_native_arm64-v8a.txt) * [native 崩溃 (x86)](doc/tombstone_native_x86.txt) * [native 崩溃 (x86_64)](doc/tombstone_native_x86_64.txt) -* [ANR (armeabi)](doc/tombstone_anr_armeabi.txt) * [ANR (armeabi-v7a)](doc/tombstone_anr_armeabi-v7a.txt) * [ANR (arm64-v8a)](doc/tombstone_anr_arm64-v8a.txt) * [ANR (x86)](doc/tombstone_anr_x86.txt) @@ -62,7 +62,7 @@ xCrash 已经在 [爱奇艺](http://www.iqiyi.com/) 的不同平台(手机, ```Gradle dependencies { - implementation 'com.iqiyi.xcrash:xcrash-android-lib:2.4.8' + implementation 'com.iqiyi.xcrash:xcrash-android-lib:3.0.0' } ``` @@ -72,7 +72,7 @@ dependencies { android { defaultConfig { ndk { - abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64' + abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64' } } } @@ -109,39 +109,23 @@ class MyCustomApplication : Application() { Tombstone 文件默认将被写入到 `Context#getFilesDir() + "/tombstones"` 目录。(通常在: `/data/data/PACKAGE_NAME/files/tombstones`) -在 [src/java/xcrash/xcrash_sample](src/java/xcrash/xcrash_sample) 文件夹中,有一个更实际和复杂的示例 app。 +在 [xcrash_sample](xcrash_sample) 文件夹中,有一个更实际和复杂的示例 app。 ## 构建 -如果你想编译 xCrash 的源码。请按以下步骤进行: - -#### 1. 下载 [Android NDK r16b](https://developer.android.com/ndk/downloads/revision_history.html),设置 PATH 环境变量。 - -#### 2. 编译和复制 native 库。 - -``` -cd ./src/native/ -./build.sh -./install.sh -``` - -#### 3. 编译 AAR 库。 +#### 编译 xCrash AAR 库: ``` -cd ./src/java/xcrash/ ./gradlew :xcrash_lib:build ``` ## 技术支持 -1. 查看 [xcrash-sample](src/java/xcrash/xcrash_sample)。 -2. 在 [GitHub issues](https://github.com/iqiyi/xCrash/issues) 交流。 -3. 邮件: caikelun@gmail.com -4. QQ 群: 603635869。二维码: - -

qq group

+* [GitHub Issues](https://github.com/iqiyi/xCrash/issues) +* [GitHub Discussions](https://github.com/iqiyi/xCrash/discussions) +* Email: caikelun@gmail.com, xuqnqn@qq.com ## 贡献 diff --git a/src/java/xcrash/build.gradle b/build.gradle similarity index 58% rename from src/java/xcrash/build.gradle rename to build.gradle index f68141c..d7bfef5 100644 --- a/src/java/xcrash/build.gradle +++ b/build.gradle @@ -1,19 +1,21 @@ buildscript { repositories { google() - jcenter() + mavenCentral() } + dependencies { - classpath 'com.android.tools.build:gradle:3.5.2' - classpath 'digital.wup:android-maven-publish:3.6.2' - classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4' + classpath 'com.android.tools.build:gradle:4.1.0' } } allprojects { repositories { google() - jcenter() +// mavenLocal() + mavenCentral() + maven {url "https://s01.oss.sonatype.org/content/groups/public"} + maven {url "https://s01.oss.sonatype.org/content/repositories/releases"} } } @@ -22,20 +24,24 @@ task clean(type: Delete) { } ext { - minSdkVersion = 14 - compileSdkVersion = 29 - targetSdkVersion = 29 - buildToolsVersion = '29.0.2' - javaVersion = JavaVersion.VERSION_1_6 + minSdkVersion = 16 + compileSdkVersion = 31 + targetSdkVersion = 31 + buildToolsVersion = '30.0.2' + javaVersion = JavaVersion.VERSION_1_8 + ndkVersion = "21.3.6528147" + cmakeVersion = "3.10.2" + abiFilters = "armeabi-v7a,arm64-v8a,x86,x86_64" + useASAN = false POM_GROUP_ID = "com.iqiyi.xcrash" POM_ARTIFACT_ID = "xcrash-android-lib" - POM_VERSION_NAME = "2.4.8" + POM_VERSION_NAME = "3.1.0" POM_NAME = "xCrash Android Lib" POM_DESCRIPTION = "xCrash provides the Android app with the ability to capture java crash, native crash and ANR." POM_URL = "https://github.com/iqiyi/xCrash" - POM_INCEPTION_YEAR = "2019" + POM_INCEPTION_YEAR = "2020" POM_PACKAGING = "aar" POM_SCM_CONNECTION = "https://github.com/iqiyi/xCrash.git" @@ -49,8 +55,4 @@ ext { POM_DEVELOPER_ID = "iQIYI" POM_DEVELOPER_NAME = "iQIYI, Inc." - - BINTRAY_REPO = "maven" - BINTRAY_ORGANIZATION = "xcrash" - BINTRAY_LICENCE = ['MIT'] } diff --git a/src/java/xcrash/checkstyle.xml b/checkstyle.xml similarity index 100% rename from src/java/xcrash/checkstyle.xml rename to checkstyle.xml diff --git a/doc/intro.png b/doc/intro.png index b60bad0..36f561d 100644 Binary files a/doc/intro.png and b/doc/intro.png differ diff --git a/doc/qq_group.jpg b/doc/qq_group.jpg deleted file mode 100644 index 0b9ccbb..0000000 Binary files a/doc/qq_group.jpg and /dev/null differ diff --git a/doc/xcrash_logo.png b/doc/xcrash_logo.png new file mode 100644 index 0000000..96e53b9 Binary files /dev/null and b/doc/xcrash_logo.png differ diff --git a/doc/xcrash_logo.svg b/doc/xcrash_logo.svg new file mode 100644 index 0000000..b41f605 --- /dev/null +++ b/doc/xcrash_logo.svg @@ -0,0 +1,165 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + xCrash + + + + + + xCrash + + diff --git a/doc/xcrash_logo2.png b/doc/xcrash_logo2.png new file mode 100644 index 0000000..edc10cc Binary files /dev/null and b/doc/xcrash_logo2.png differ diff --git a/src/java/xcrash/gradle.properties b/gradle.properties similarity index 67% rename from src/java/xcrash/gradle.properties rename to gradle.properties index 743d692..c73d239 100644 --- a/src/java/xcrash/gradle.properties +++ b/gradle.properties @@ -11,3 +11,9 @@ org.gradle.jvmargs=-Xmx1536m # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app's APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true +# Automatically convert third-party libraries to use AndroidX +android.enableJetifier=true diff --git a/src/java/xcrash/gradle/check.gradle b/gradle/check.gradle similarity index 100% rename from src/java/xcrash/gradle/check.gradle rename to gradle/check.gradle diff --git a/gradle/publish.gradle b/gradle/publish.gradle new file mode 100644 index 0000000..aad8282 --- /dev/null +++ b/gradle/publish.gradle @@ -0,0 +1,102 @@ +apply plugin: 'maven-publish' +apply plugin: 'signing' + +ext["signing.keyId"] = '' +ext["signing.password"] = '' +ext["signing.secretKeyRingFile"] = '' +ext["ossrhUsername"] = '' +ext["ossrhPassword"] = '' + +File secretPropsFile = project.rootProject.file('local.properties') +if (secretPropsFile.exists()) { + Properties p = new Properties() + p.load(new FileInputStream(secretPropsFile)) + p.each { name, value -> + ext[name] = value + } +} else { + ext["signing.keyId"] = System.getenv('SIGNING_KEY_ID') + ext["signing.password"] = System.getenv('SIGNING_PASSWORD') + ext["signing.secretKeyRingFile"] = System.getenv('SIGNING_SECRET_KEY_RING_FILE') + ext["ossrhUsername"] = System.getenv('OSSRH_USERNAME') + ext["ossrhPassword"] = System.getenv('OSSRH_PASSWORD') +} + +task sourcesJar(type: Jar) { + archiveClassifier.set("sources") + from android.sourceSets.main.java.srcDirs +} + +task javadoc(type: Javadoc) { + source = android.sourceSets.main.java.sourceFiles + classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) +} + +task javadocJar(type: Jar, dependsOn: javadoc) { + archiveClassifier.set("javadoc") + from javadoc.destinationDir +} + +project.afterEvaluate { + publishing { + publications { + release(MavenPublication) { + from components.release + + artifact sourcesJar + artifact javadocJar + + artifactId POM_ARTIFACT_ID + groupId POM_GROUP_ID + version POM_VERSION_NAME + + pom { + name = POM_NAME + description = POM_DESCRIPTION + url = POM_URL + inceptionYear = POM_INCEPTION_YEAR + packaging = POM_PACKAGING + scm { + connection = POM_SCM_CONNECTION + url = POM_URL + } + issueManagement { + system = POM_ISSUE_SYSTEM + url = POM_ISSUE_URL + } + licenses { + license { + name = POM_LICENCE_NAME + url = POM_LICENCE_URL + distribution = POM_LICENCE_DIST + } + } + developers { + developer { + id = POM_DEVELOPER_ID + name = POM_DEVELOPER_NAME + } + } + } + } + } + repositories { + maven { + name = "sonatype" + + def releasesRepoUrl = "https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/" + def snapshotsRepoUrl = "https://s01.oss.sonatype.org/content/repositories/snapshots/" + url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl + + credentials { + username ossrhUsername + password ossrhPassword + } + } + } + } +} + +signing { + sign publishing.publications +} diff --git a/gradle/sanitizer.gradle b/gradle/sanitizer.gradle new file mode 100644 index 0000000..2867a56 --- /dev/null +++ b/gradle/sanitizer.gradle @@ -0,0 +1,63 @@ +project.afterEvaluate { + + preBuild.doFirst { + def projectDir = project.projectDir.toString() + + if (rootProject.ext.useASAN) { + def ndkLibDir = android.ndkDirectory.absolutePath + "/toolchains/llvm/prebuilt/" + def ABIs = rootProject.ext.abiFilters.split(",") + + for (String abi : ABIs) { + def arch = abi + if (abi == 'armeabi-v7a') { + arch = "arm" + } else if (abi == "arm64-v8a") { + arch = "aarch64" + } else if (abi == "x86") { + arch = "i686" + } else if (abi == "x86_64") { + arch = "x86_64" + } + + // create ASAN wrap.sh + def resDir = new File(projectDir + "/src/main/resources/lib/" + abi) + resDir.mkdirs() + def wrapFile = new File(resDir, "wrap.sh") + wrapFile.withWriter { writer -> + writer.write('#!/system/bin/sh\n') + writer.write('HERE="$(cd "$(dirname "$0")" && pwd)"\n') + writer.write('export ASAN_OPTIONS=log_to_syslog=false,allow_user_segv_handler=1,detect_stack_use_after_return=1,check_initialization_order=true,quarantine_size_mb=64,color=never,new_delete_type_mismatch=0,sleep_before_dying=5,use_sigaltstack=0\n') + writer.write("ASAN_LIB=\$(ls \$HERE/libclang_rt.asan-${arch}-android.so)\n") + writer.write('if [ -f "$HERE/libc++_shared.so" ]; then\n') + writer.write(' export LD_PRELOAD="$ASAN_LIB $HERE/libc++_shared.so"\n') + writer.write('else\n') + writer.write(' export LD_PRELOAD="$ASAN_LIB"\n') + writer.write('fi\n') + writer.write('"\$@"\n') + } + println "sanitizer: [${abi}] create wrap.sh: " + wrapFile.absolutePath + + // copy ASAN libs + def libDir = new File(projectDir + "/src/main/jniLibs/" + abi) + libDir.mkdirs() + FileTree tree = fileTree(dir: ndkLibDir).include("**/libclang_rt.asan-${arch}-android.so") + tree.each { File file -> + copy { + from file + into libDir.absolutePath + } + println "sanitizer: [${abi}] copy lib: ${file.absolutePath} -> ${libDir.absolutePath}" + } + } + } else { + delete projectDir + '/src/main/resources/' + delete projectDir + '/src/main/jniLibs/' + } + } +} + +clean.doFirst { + def projectDir = project.projectDir.toString() + delete projectDir + '/src/main/resources/' + delete projectDir + '/src/main/jniLibs/' +} diff --git a/src/java/xcrash/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from src/java/xcrash/gradle/wrapper/gradle-wrapper.jar rename to gradle/wrapper/gradle-wrapper.jar diff --git a/src/java/xcrash/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties similarity index 80% rename from src/java/xcrash/gradle/wrapper/gradle-wrapper.properties rename to gradle/wrapper/gradle-wrapper.properties index 75cc802..fc3b162 100644 --- a/src/java/xcrash/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu Jun 20 18:09:11 CST 2019 +#Fri Oct 23 17:17:57 CST 2020 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip diff --git a/src/java/xcrash/gradlew b/gradlew similarity index 100% rename from src/java/xcrash/gradlew rename to gradlew diff --git a/src/java/xcrash/gradlew.bat b/gradlew.bat similarity index 100% rename from src/java/xcrash/gradlew.bat rename to gradlew.bat diff --git a/src/java/xcrash/settings.gradle b/settings.gradle similarity index 100% rename from src/java/xcrash/settings.gradle rename to settings.gradle diff --git a/src/java/xcrash/.gitignore b/src/java/xcrash/.gitignore deleted file mode 100644 index fd45b12..0000000 --- a/src/java/xcrash/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -*.iml -.gradle -/local.properties -/.idea/caches/build_file_checksums.ser -/.idea/libraries -/.idea/modules.xml -/.idea/workspace.xml -.DS_Store -/build -/captures -.externalNativeBuild diff --git a/src/java/xcrash/gradle/publish.gradle b/src/java/xcrash/gradle/publish.gradle deleted file mode 100644 index d837cc3..0000000 --- a/src/java/xcrash/gradle/publish.gradle +++ /dev/null @@ -1,129 +0,0 @@ -apply plugin: 'digital.wup.android-maven-publish' -apply plugin: 'com.jfrog.bintray' - -def readPropertyFromLocalProperties(String key) { - Properties properties = new Properties() - try { - properties.load(project.rootProject.file('local.properties').newDataInputStream()) - } catch (Exception e) { - println("load local.properties failed. msg: ${e.message}") - } - return properties.getProperty(key) -} - -def getCustomMavenRepo() { - return readPropertyFromLocalProperties('CUSTOM_MAVEN_REPO') -} - -def getCustomMavenUsername() { - return readPropertyFromLocalProperties('CUSTOM_MAVEN_USERNAME') -} - -def getCustomMavenPassword() { - return readPropertyFromLocalProperties('CUSTOM_MAVEN_PASSWORD') -} - -def getBintrayUser() { - return readPropertyFromLocalProperties('BINTRAY_USER') -} - -def getBintrayApikey() { - return readPropertyFromLocalProperties('BINTRAY_APIKEY') -} - -task sourcesJar(type: Jar) { - classifier = 'sources' - from android.sourceSets.main.java.srcDirs -} - -task javadoc(type: Javadoc) { - source = android.sourceSets.main.java.sourceFiles - classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) -} - -task javadocJar(type: Jar, dependsOn: javadoc) { - classifier = 'javadoc' - from javadoc.destinationDir -} - -publishing.publications { - mavenAar(MavenPublication) { - from components.android - - artifact sourcesJar - artifact javadocJar - - artifactId POM_ARTIFACT_ID - groupId POM_GROUP_ID - version POM_VERSION_NAME - - pom { - name = POM_NAME - description = POM_DESCRIPTION - url = POM_URL - inceptionYear = POM_INCEPTION_YEAR - packaging = POM_PACKAGING - scm { - connection = POM_SCM_CONNECTION - url = POM_URL - } - issueManagement { - system = POM_ISSUE_SYSTEM - url = POM_ISSUE_URL - } - licenses { - license { - name = POM_LICENCE_NAME - url = POM_LICENCE_URL - distribution = POM_LICENCE_DIST - } - } - developers { - developer { - id = POM_DEVELOPER_ID - name = POM_DEVELOPER_NAME - } - } - } - } -} - -// custom maven repo -publishing.repositories { - maven { - url getCustomMavenRepo() - credentials { - username getCustomMavenUsername() - password getCustomMavenPassword() - } - } -} - -// bintray maven repo -bintray { - user = getBintrayUser() - key = getBintrayApikey() - publications = ['mavenAar'] - pkg { - repo = BINTRAY_REPO - name = "${POM_GROUP_ID}:${POM_ARTIFACT_ID}" - userOrg = BINTRAY_ORGANIZATION - desc = POM_DESCRIPTION - websiteUrl = POM_URL - issueTrackerUrl = POM_ISSUE_URL - vcsUrl = POM_SCM_CONNECTION - licenses = BINTRAY_LICENCE - publicDownloadNumbers = true - publish = true - dryRun = false - - version { - name = POM_VERSION_NAME - released = new Date() - vcsTag = POM_VERSION_NAME - gpg { - sign = true - } - } - } -} diff --git a/src/native/build.sh b/src/native/build.sh deleted file mode 100755 index b34a836..0000000 --- a/src/native/build.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -ndk-build -C ./libxcrash/jni -ndk-build -C ./libxcrash_dumper/jni diff --git a/src/native/clean.sh b/src/native/clean.sh deleted file mode 100755 index 7e78205..0000000 --- a/src/native/clean.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -ndk-build -C ./libxcrash/jni clean -ndk-build -C ./libxcrash_dumper/jni clean diff --git a/src/native/install.sh b/src/native/install.sh deleted file mode 100755 index dedd136..0000000 --- a/src/native/install.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -mkdir -p ../java/xcrash/xcrash_lib/src/main/jniLibs/armeabi -mkdir -p ../java/xcrash/xcrash_lib/src/main/jniLibs/armeabi-v7a -mkdir -p ../java/xcrash/xcrash_lib/src/main/jniLibs/arm64-v8a -mkdir -p ../java/xcrash/xcrash_lib/src/main/jniLibs/x86 -mkdir -p ../java/xcrash/xcrash_lib/src/main/jniLibs/x86_64 - -cp -f ./libxcrash/libs/armeabi/libxcrash.so ../java/xcrash/xcrash_lib/src/main/jniLibs/armeabi/libxcrash.so -cp -f ./libxcrash/libs/armeabi-v7a/libxcrash.so ../java/xcrash/xcrash_lib/src/main/jniLibs/armeabi-v7a/libxcrash.so -cp -f ./libxcrash/libs/arm64-v8a/libxcrash.so ../java/xcrash/xcrash_lib/src/main/jniLibs/arm64-v8a/libxcrash.so -cp -f ./libxcrash/libs/x86/libxcrash.so ../java/xcrash/xcrash_lib/src/main/jniLibs/x86/libxcrash.so -cp -f ./libxcrash/libs/x86_64/libxcrash.so ../java/xcrash/xcrash_lib/src/main/jniLibs/x86_64/libxcrash.so - -cp -f ./libxcrash_dumper/libs/armeabi/xcrash_dumper ../java/xcrash/xcrash_lib/src/main/jniLibs/armeabi/libxcrash_dumper.so -cp -f ./libxcrash_dumper/libs/armeabi-v7a/xcrash_dumper ../java/xcrash/xcrash_lib/src/main/jniLibs/armeabi-v7a/libxcrash_dumper.so -cp -f ./libxcrash_dumper/libs/arm64-v8a/xcrash_dumper ../java/xcrash/xcrash_lib/src/main/jniLibs/arm64-v8a/libxcrash_dumper.so -cp -f ./libxcrash_dumper/libs/x86/xcrash_dumper ../java/xcrash/xcrash_lib/src/main/jniLibs/x86/libxcrash_dumper.so -cp -f ./libxcrash_dumper/libs/x86_64/xcrash_dumper ../java/xcrash/xcrash_lib/src/main/jniLibs/x86_64/libxcrash_dumper.so diff --git a/src/native/libxcrash/jni/Android.mk b/src/native/libxcrash/jni/Android.mk deleted file mode 100644 index 7666bf0..0000000 --- a/src/native/libxcrash/jni/Android.mk +++ /dev/null @@ -1,24 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE := test -LOCAL_CFLAGS := -std=c11 -Weverything -Werror -O0 -LOCAL_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/../../common -LOCAL_SRC_FILES := xc_test.c -include $(BUILD_STATIC_LIBRARY) - -include $(CLEAR_VARS) -LOCAL_MODULE := xcrash -LOCAL_CFLAGS := -std=c11 -Weverything -Werror -fvisibility=hidden -LOCAL_LDLIBS := -ldl -llog -LOCAL_STATIC_LIBRARIES := test -LOCAL_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/../../common -LOCAL_SRC_FILES := xc_jni.c \ - xc_common.c \ - xc_crash.c \ - xc_trace.c \ - xc_dl.c \ - xc_fallback.c \ - xc_util.c \ - $(wildcard $(LOCAL_PATH)/../../common/*.c) -include $(BUILD_SHARED_LIBRARY) diff --git a/src/native/libxcrash/jni/Application.mk b/src/native/libxcrash/jni/Application.mk deleted file mode 100644 index f93f05a..0000000 --- a/src/native/libxcrash/jni/Application.mk +++ /dev/null @@ -1,2 +0,0 @@ -APP_ABI := armeabi armeabi-v7a arm64-v8a x86 x86_64 -APP_PLATFORM := android-14 diff --git a/src/native/libxcrash_dumper/jni/Android.mk b/src/native/libxcrash_dumper/jni/Android.mk deleted file mode 100644 index ebc44c2..0000000 --- a/src/native/libxcrash_dumper/jni/Android.mk +++ /dev/null @@ -1,12 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE := xcrash_dumper -LOCAL_CFLAGS := -std=c11 -Weverything -Werror -fvisibility=hidden -fPIE -LOCAL_LDFLAGS := -pie -LOCAL_LDLIBS := -ldl -llog -LOCAL_STATIC_LIBRARIES := lzma -LOCAL_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/../../common -LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.c) $(wildcard $(LOCAL_PATH)/../../common/*.c) -include $(BUILD_EXECUTABLE) -include $(LOCAL_PATH)/lzma/Android.mk diff --git a/src/native/libxcrash_dumper/jni/Application.mk b/src/native/libxcrash_dumper/jni/Application.mk deleted file mode 100644 index f93f05a..0000000 --- a/src/native/libxcrash_dumper/jni/Application.mk +++ /dev/null @@ -1,2 +0,0 @@ -APP_ABI := armeabi armeabi-v7a arm64-v8a x86 x86_64 -APP_PLATFORM := android-14 diff --git a/src/native/libxcrash_dumper/jni/lzma/Android.mk b/src/native/libxcrash_dumper/jni/lzma/Android.mk deleted file mode 100644 index 3f07649..0000000 --- a/src/native/libxcrash_dumper/jni/lzma/Android.mk +++ /dev/null @@ -1,36 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE := lzma -LOCAL_CFLAGS := -std=c11 -Weverything -Werror \ - -Wno-enum-conversion \ - -Wno-reserved-id-macro \ - -Wno-undef \ - -Wno-missing-prototypes \ - -Wno-missing-variable-declarations \ - -Wno-cast-align \ - -Wno-sign-conversion \ - -Wno-assign-enum \ - -Wno-unused-macros \ - -Wno-padded \ - -Wno-cast-qual \ - -Wno-strict-prototypes \ - -fPIE \ - -D_7ZIP_ST -LOCAL_C_INCLUDES := $(LOCAL_PATH) -LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) -LOCAL_SRC_FILES := 7zCrc.c \ - 7zCrcOpt.c \ - CpuArch.c \ - Bra.c \ - Bra86.c \ - BraIA64.c \ - Delta.c \ - Lzma2Dec.c \ - LzmaDec.c \ - Sha256.c \ - Xz.c \ - XzCrc64.c \ - XzCrc64Opt.c \ - XzDec.c -include $(BUILD_STATIC_LIBRARY) diff --git a/src/java/xcrash/xcrash_lib/.gitignore b/xcrash_lib/.gitignore similarity index 100% rename from src/java/xcrash/xcrash_lib/.gitignore rename to xcrash_lib/.gitignore diff --git a/src/java/xcrash/xcrash_lib/build.gradle b/xcrash_lib/build.gradle similarity index 59% rename from src/java/xcrash/xcrash_lib/build.gradle rename to xcrash_lib/build.gradle index 9e37287..f2405d1 100644 --- a/src/java/xcrash/xcrash_lib/build.gradle +++ b/xcrash_lib/build.gradle @@ -3,10 +3,26 @@ apply plugin: 'com.android.library' android { compileSdkVersion rootProject.ext.compileSdkVersion buildToolsVersion rootProject.ext.buildToolsVersion + ndkVersion rootProject.ext.ndkVersion defaultConfig { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion consumerProguardFiles 'proguard-rules.pro' + externalNativeBuild { + cmake { + abiFilters rootProject.ext.abiFilters.split(",") + if(rootProject.ext.useASAN) { + arguments "-DANDROID_ARM_MODE=arm" + arguments "-DUSEASAN=ON" + } + } + } + } + externalNativeBuild { + cmake { + path "src/main/cpp/CMakeLists.txt" + version rootProject.ext.cmakeVersion + } } compileOptions { sourceCompatibility rootProject.ext.javaVersion diff --git a/src/java/xcrash/xcrash_lib/proguard-rules.pro b/xcrash_lib/proguard-rules.pro similarity index 75% rename from src/java/xcrash/xcrash_lib/proguard-rules.pro rename to xcrash_lib/proguard-rules.pro index f001c9f..aed903f 100644 --- a/src/java/xcrash/xcrash_lib/proguard-rules.pro +++ b/xcrash_lib/proguard-rules.pro @@ -2,4 +2,5 @@ native ; void crashCallback(...); void traceCallback(...); + void traceCallbackBeforeDump(...); } diff --git a/src/java/xcrash/xcrash_lib/src/main/AndroidManifest.xml b/xcrash_lib/src/main/AndroidManifest.xml similarity index 100% rename from src/java/xcrash/xcrash_lib/src/main/AndroidManifest.xml rename to xcrash_lib/src/main/AndroidManifest.xml diff --git a/xcrash_lib/src/main/cpp/CMakeLists.txt b/xcrash_lib/src/main/cpp/CMakeLists.txt new file mode 100644 index 0000000..602a7dc --- /dev/null +++ b/xcrash_lib/src/main/cpp/CMakeLists.txt @@ -0,0 +1,145 @@ +cmake_minimum_required(VERSION 3.4.1) + +####################################### +# global +####################################### + +add_compile_options( + -std=c11 + -Weverything + -Werror) + +####################################### +# libxcrash.so +####################################### + +file(GLOB XCRASH_SRC + xcrash/*.c + common/*.c + dl/*.c) + +add_library(xcrash SHARED + ${XCRASH_SRC}) + +target_include_directories(xcrash PUBLIC + xcrash + xcrash_dumper + common + dl) + +target_link_libraries(xcrash + log + dl) + +if(USEASAN) + +target_compile_options(xcrash PUBLIC + -fsanitize=address + -fno-omit-frame-pointer) + +set_target_properties(xcrash PROPERTIES + LINK_FLAGS " \ + -fsanitize=address") + +else() + +target_compile_options(xcrash PUBLIC + -Oz + -flto + -ffunction-sections + -fdata-sections) + +set_target_properties(xcrash PROPERTIES + LINK_FLAGS " \ + -O3 \ + -flto \ + -Wl,--exclude-libs,ALL \ + -Wl,--gc-sections \ + -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/xcrash.exports") + +endif() + +####################################### +# libxcrash_dumper.so +####################################### + +file(GLOB XCRASH_DUMPER_SRC + xcrash_dumper/*.c + common/*.c) + +set(LZME_SRC + lzma/7zCrc.c + lzma/7zCrcOpt.c + lzma/CpuArch.c + lzma/Bra.c + lzma/Bra86.c + lzma/BraIA64.c + lzma/Delta.c + lzma/Lzma2Dec.c + lzma/LzmaDec.c + lzma/Sha256.c + lzma/Xz.c + lzma/XzCrc64.c + lzma/XzCrc64Opt.c + lzma/XzDec.c) + +set_source_files_properties(${LZME_SRC} PROPERTIES + COMPILE_FLAGS " \ + -D_7ZIP_ST \ + -Wno-enum-conversion \ + -Wno-reserved-id-macro \ + -Wno-undef \ + -Wno-missing-prototypes \ + -Wno-missing-variable-declarations \ + -Wno-cast-align \ + -Wno-sign-conversion \ + -Wno-assign-enum \ + -Wno-unused-macros \ + -Wno-padded \ + -Wno-cast-qual \ + -Wno-strict-prototypes \ + -Wno-extra-semi-stmt") + +add_executable(xcrash_dumper + ${XCRASH_DUMPER_SRC} + ${LZME_SRC}) + +target_include_directories(xcrash_dumper PUBLIC + xcrash_dumper + common + lzma) + +target_link_libraries(xcrash_dumper + log + dl) + +if(USEASAN) + +target_compile_options(xcrash_dumper PUBLIC + -fsanitize=address + -fno-omit-frame-pointer) + +set_target_properties(xcrash_dumper PROPERTIES + LINK_FLAGS " \ + -fsanitize=address") + +else() + +target_compile_options(xcrash_dumper PUBLIC + -Oz + -flto + -ffunction-sections + -fdata-sections) + +set_target_properties(xcrash_dumper PROPERTIES + LINK_FLAGS " \ + -O3 \ + -flto \ + -Wl,--exclude-libs,ALL \ + -Wl,--gc-sections") + +endif() + +set_target_properties(xcrash_dumper PROPERTIES + PREFIX "lib" + SUFFIX ".so") diff --git a/src/native/common/queue.h b/xcrash_lib/src/main/cpp/common/queue.h similarity index 100% rename from src/native/common/queue.h rename to xcrash_lib/src/main/cpp/common/queue.h diff --git a/src/native/common/tree.h b/xcrash_lib/src/main/cpp/common/tree.h similarity index 100% rename from src/native/common/tree.h rename to xcrash_lib/src/main/cpp/common/tree.h diff --git a/src/native/common/xcc_b64.c b/xcrash_lib/src/main/cpp/common/xcc_b64.c similarity index 100% rename from src/native/common/xcc_b64.c rename to xcrash_lib/src/main/cpp/common/xcc_b64.c diff --git a/src/native/common/xcc_b64.h b/xcrash_lib/src/main/cpp/common/xcc_b64.h similarity index 100% rename from src/native/common/xcc_b64.h rename to xcrash_lib/src/main/cpp/common/xcc_b64.h diff --git a/src/native/common/xcc_errno.h b/xcrash_lib/src/main/cpp/common/xcc_errno.h similarity index 100% rename from src/native/common/xcc_errno.h rename to xcrash_lib/src/main/cpp/common/xcc_errno.h diff --git a/src/native/common/xcc_fmt.c b/xcrash_lib/src/main/cpp/common/xcc_fmt.c similarity index 100% rename from src/native/common/xcc_fmt.c rename to xcrash_lib/src/main/cpp/common/xcc_fmt.c diff --git a/src/native/common/xcc_fmt.h b/xcrash_lib/src/main/cpp/common/xcc_fmt.h similarity index 100% rename from src/native/common/xcc_fmt.h rename to xcrash_lib/src/main/cpp/common/xcc_fmt.h diff --git a/src/native/common/xcc_libc_support.c b/xcrash_lib/src/main/cpp/common/xcc_libc_support.c similarity index 100% rename from src/native/common/xcc_libc_support.c rename to xcrash_lib/src/main/cpp/common/xcc_libc_support.c diff --git a/src/native/common/xcc_libc_support.h b/xcrash_lib/src/main/cpp/common/xcc_libc_support.h similarity index 100% rename from src/native/common/xcc_libc_support.h rename to xcrash_lib/src/main/cpp/common/xcc_libc_support.h diff --git a/src/native/common/xcc_meminfo.c b/xcrash_lib/src/main/cpp/common/xcc_meminfo.c similarity index 100% rename from src/native/common/xcc_meminfo.c rename to xcrash_lib/src/main/cpp/common/xcc_meminfo.c diff --git a/src/native/common/xcc_meminfo.h b/xcrash_lib/src/main/cpp/common/xcc_meminfo.h similarity index 100% rename from src/native/common/xcc_meminfo.h rename to xcrash_lib/src/main/cpp/common/xcc_meminfo.h diff --git a/src/native/common/xcc_signal.c b/xcrash_lib/src/main/cpp/common/xcc_signal.c similarity index 100% rename from src/native/common/xcc_signal.c rename to xcrash_lib/src/main/cpp/common/xcc_signal.c diff --git a/src/native/common/xcc_signal.h b/xcrash_lib/src/main/cpp/common/xcc_signal.h similarity index 100% rename from src/native/common/xcc_signal.h rename to xcrash_lib/src/main/cpp/common/xcc_signal.h diff --git a/src/native/common/xcc_spot.h b/xcrash_lib/src/main/cpp/common/xcc_spot.h similarity index 95% rename from src/native/common/xcc_spot.h rename to xcrash_lib/src/main/cpp/common/xcc_spot.h index 1954c0d..d2ec61b 100644 --- a/src/native/common/xcc_spot.h +++ b/xcrash_lib/src/main/cpp/common/xcc_spot.h @@ -59,10 +59,10 @@ typedef struct int dump_all_threads; unsigned int dump_all_threads_count_max; - //set when crashed (content lenghts after this struct) + //set when crashed (content lengths after this struct) size_t log_pathname_len; - //set when inited (content lenghts after this struct) + //set when inited (content lengths after this struct) size_t os_version_len; size_t kernel_version_len; size_t abi_list_len; diff --git a/src/native/common/xcc_unwind.c b/xcrash_lib/src/main/cpp/common/xcc_unwind.c similarity index 100% rename from src/native/common/xcc_unwind.c rename to xcrash_lib/src/main/cpp/common/xcc_unwind.c diff --git a/src/native/common/xcc_unwind.h b/xcrash_lib/src/main/cpp/common/xcc_unwind.h similarity index 100% rename from src/native/common/xcc_unwind.h rename to xcrash_lib/src/main/cpp/common/xcc_unwind.h diff --git a/src/native/common/xcc_unwind_clang.c b/xcrash_lib/src/main/cpp/common/xcc_unwind_clang.c similarity index 100% rename from src/native/common/xcc_unwind_clang.c rename to xcrash_lib/src/main/cpp/common/xcc_unwind_clang.c diff --git a/src/native/common/xcc_unwind_clang.h b/xcrash_lib/src/main/cpp/common/xcc_unwind_clang.h similarity index 100% rename from src/native/common/xcc_unwind_clang.h rename to xcrash_lib/src/main/cpp/common/xcc_unwind_clang.h diff --git a/src/native/common/xcc_unwind_libcorkscrew.c b/xcrash_lib/src/main/cpp/common/xcc_unwind_libcorkscrew.c similarity index 100% rename from src/native/common/xcc_unwind_libcorkscrew.c rename to xcrash_lib/src/main/cpp/common/xcc_unwind_libcorkscrew.c diff --git a/src/native/common/xcc_unwind_libcorkscrew.h b/xcrash_lib/src/main/cpp/common/xcc_unwind_libcorkscrew.h similarity index 100% rename from src/native/common/xcc_unwind_libcorkscrew.h rename to xcrash_lib/src/main/cpp/common/xcc_unwind_libcorkscrew.h diff --git a/src/native/common/xcc_unwind_libunwind.c b/xcrash_lib/src/main/cpp/common/xcc_unwind_libunwind.c similarity index 100% rename from src/native/common/xcc_unwind_libunwind.c rename to xcrash_lib/src/main/cpp/common/xcc_unwind_libunwind.c diff --git a/src/native/common/xcc_unwind_libunwind.h b/xcrash_lib/src/main/cpp/common/xcc_unwind_libunwind.h similarity index 100% rename from src/native/common/xcc_unwind_libunwind.h rename to xcrash_lib/src/main/cpp/common/xcc_unwind_libunwind.h diff --git a/src/native/common/xcc_util.c b/xcrash_lib/src/main/cpp/common/xcc_util.c similarity index 99% rename from src/native/common/xcc_util.c rename to xcrash_lib/src/main/cpp/common/xcc_util.c index 9cd8c00..e758c4c 100644 --- a/src/native/common/xcc_util.c +++ b/xcrash_lib/src/main/cpp/common/xcc_util.c @@ -660,7 +660,7 @@ int xcc_util_record_fds(int fd, pid_t pid) xcc_fmt_snprintf(path, sizeof(path), "/proc/%d/fd/%d", pid, fd_num); len = readlink(path, fd_path, sizeof(fd_path) - 1); if(len <= 0 || len > (ssize_t)(sizeof(fd_path) - 1)) - strncpy(path, "???", sizeof(path)); + strncpy(fd_path, "???", sizeof(fd_path)); else fd_path[len] = '\0'; diff --git a/src/native/common/xcc_util.h b/xcrash_lib/src/main/cpp/common/xcc_util.h similarity index 96% rename from src/native/common/xcc_util.h rename to xcrash_lib/src/main/cpp/common/xcc_util.h index 38975d4..792ba82 100644 --- a/src/native/common/xcc_util.h +++ b/xcrash_lib/src/main/cpp/common/xcc_util.h @@ -109,14 +109,16 @@ typedef struct #define XCC_UTIL_LIBART "/system/lib/libart.so" #define XCC_UTIL_LIBC_APEX "/apex/com.android.runtime/lib/bionic/libc.so" #define XCC_UTIL_LIBCPP_APEX "/apex/com.android.runtime/lib/libc++.so" -#define XCC_UTIL_LIBART_APEX "/apex/com.android.runtime/lib/libart.so" +#define XCC_UTIL_LIBART_APEX_29 "/apex/com.android.runtime/lib/libart.so" +#define XCC_UTIL_LIBART_APEX_30 "/apex/com.android.art/lib/libart.so" #else #define XCC_UTIL_LIBC "/system/lib64/libc.so" #define XCC_UTIL_LIBCPP "/system/lib64/libc++.so" #define XCC_UTIL_LIBART "/system/lib64/libart.so" #define XCC_UTIL_LIBC_APEX "/apex/com.android.runtime/lib64/bionic/libc.so" #define XCC_UTIL_LIBCPP_APEX "/apex/com.android.runtime/lib64/libc++.so" -#define XCC_UTIL_LIBART_APEX "/apex/com.android.runtime/lib64/libart.so" +#define XCC_UTIL_LIBART_APEX_29 "/apex/com.android.runtime/lib64/libart.so" +#define XCC_UTIL_LIBART_APEX_30 "/apex/com.android.art/lib64/libart.so" #endif #define XCC_UTIL_LIBC_ABORT_MSG_PTR "__abort_message_ptr" diff --git a/src/native/common/xcc_version.h b/xcrash_lib/src/main/cpp/common/xcc_version.h similarity index 96% rename from src/native/common/xcc_version.h rename to xcrash_lib/src/main/cpp/common/xcc_version.h index 9127531..7791bf5 100644 --- a/src/native/common/xcc_version.h +++ b/xcrash_lib/src/main/cpp/common/xcc_version.h @@ -24,6 +24,6 @@ #ifndef XCC_VERSION_H #define XCC_VERSION_H 1 -#define XCC_VERSION_STR "xCrash 2.4.8" +#define XCC_VERSION_STR "xCrash 3.1.0" #endif diff --git a/xcrash_lib/src/main/cpp/dl/README.md b/xcrash_lib/src/main/cpp/dl/README.md new file mode 100644 index 0000000..540b184 --- /dev/null +++ b/xcrash_lib/src/main/cpp/dl/README.md @@ -0,0 +1,117 @@ +# xCrash DL + +## Problem + +All the time, Android's DL series functions have some compatibility and ability issues: + +### `dl_iterate_phdr()` + +1. On arm32 arch, only available when Android >= 5.0. +2. It does not hold the linker's global lock in Android 5.x and 4.x, this may cause a crash during iterating. +3. In some Android 4.x and 5.x devices, it returns basename instead of full pathname. +4. In some Android 4.x and 5.x devices, it returns package name for `app_process` instead of `/system/bin/app_process32` or `/system/bin/app_process64`. +5. linker/linker64 is only included since Android 8.1. (AOSP has included linker/linker64 since 8.0, but a large number of devices from other manufacturers have included linker/linker64 since Android 8.1) + +### `dlopen()` & `dlsym()` + +1. Since Android 7.0, `dlopen()` and `dlsym()` cannot operate system libraries. (Although in most cases, we don’t really need to load the dynamic library from the disk, but just need to get the address of a function to call it.) +2. `dlsym()` can only obtain symbols in `.dynsym`, but we sometimes need to obtain internal symbols in `.symtab` and "`.symtab` in `.gnu_debugdata`". +3. `dlsym()` does not distinguish between functions and objects when searching for symbols. In ELF files with a lot of symbols, this will reduce search efficiency, especially for `.symtab`. + +## Solution + +xCrash DL tries to make up the above problems. Enjoy the code ~ + +In addition, the source code of this module (in the current directory) does not depend on any other source code of xCrash, so you can easily use them in your own projects. + +## Usage + +### `xc_dl_iterate()` + +```c +#define XC_DL_DEFAULT 0x00 +#define XC_DL_WITH_LINKER 0x01 + +typedef int (*xc_dl_iterate_cb_t)(struct dl_phdr_info *info, size_t size, void *arg); +int xc_dl_iterate(xc_dl_iterate_cb_t cb, void *cb_arg, int flags); +``` + +Similar to `dl_iterate_phdr()`. + +Difference from the original `dl_iterate_phdr()`, xCrach DL's `xc_dl_iterate()` has an additional "flags" parameter. If you confirm that you need to iterate to the linker/linker64, pass `XC_DL_WITH_LINKER` to the "flags" parameter, otherwise pass `XC_DL_DEFAULT`. + +The reason for this is that in Android < 8.1, we need to find the linker/linker64 from `/proc/self/maps`, which has additional overhead. + +### `xc_dl_open()` and `xc_dl_close()` + +```c +#define XC_DL_DYNSYM 0x01 +#define XC_DL_SYMTAB 0x02 +#define XC_DL_ALL (XC_DL_DYNSYM | XC_DL_SYMTAB) + +typedef struct xc_dl xc_dl_t; + +xc_dl_t *xc_dl_open(const char *pathname, int flags); +void xc_dl_close(xc_dl_t **self); +``` + +`xc_dl_close()` and `dlclose()` have the same usage. + +`xc_dl_open()` and `dlopen()` are similar. But you need to specify whether you need to "open" `.dynsym` (`XC_DL_DYNSYM`), `.symtab` (`XC_DL_SYMTAB`), or both (`XC_DL_ALL`) through the "flags" parameter. + +You can “open” ELF by basename or full pathname. However, Android has used the namespace mechanism since 8.0. If you use basename, you need to make sure that no duplicate ELF is loaded into the current process. `xc_dl_open()` will only return the first matching ELF. + +This is part of the `/proc/self/maps` of a certain process on Android 10: + +``` +...... +756fc2c000-756fc7c000 r--p 00000000 fd:03 2985 /system/lib64/vndk-sp-29/libc++.so +756fc7c000-756fcee000 --xp 00050000 fd:03 2985 /system/lib64/vndk-sp-29/libc++.so +756fcee000-756fcef000 rw-p 000c2000 fd:03 2985 /system/lib64/vndk-sp-29/libc++.so +756fcef000-756fcf7000 r--p 000c3000 fd:03 2985 /system/lib64/vndk-sp-29/libc++.so +...... +7571fdd000-757202d000 r--p 00000000 07:38 20 /apex/com.android.conscrypt/lib64/libc++.so +757202d000-757209f000 --xp 00050000 07:38 20 /apex/com.android.conscrypt/lib64/libc++.so +757209f000-75720a0000 rw-p 000c2000 07:38 20 /apex/com.android.conscrypt/lib64/libc++.so +75720a0000-75720a8000 r--p 000c3000 07:38 20 /apex/com.android.conscrypt/lib64/libc++.so +...... +760b9df000-760ba2f000 r--p 00000000 fd:03 2441 /system/lib64/libc++.so +760ba2f000-760baa1000 --xp 00050000 fd:03 2441 /system/lib64/libc++.so +760baa1000-760baa2000 rw-p 000c2000 fd:03 2441 /system/lib64/libc++.so +760baa2000-760baaa000 r--p 000c3000 fd:03 2441 /system/lib64/libc++.so +...... +756fb2f000-756fb31000 r--p 00000000 fd:03 2983 /system/lib64/vndk-sp-29/libbinderthreadstate.so +756fb31000-756fb33000 --xp 00002000 fd:03 2983 /system/lib64/vndk-sp-29/libbinderthreadstate.so +756fb33000-756fb34000 rw-p 00004000 fd:03 2983 /system/lib64/vndk-sp-29/libbinderthreadstate.so +756fb34000-756fb35000 r--p 00005000 fd:03 2983 /system/lib64/vndk-sp-29/libbinderthreadstate.so +...... +76090f9000-76090fb000 r--p 00000000 fd:03 2424 /system/lib64/libbinderthreadstate.so +76090fb000-76090fd000 --xp 00002000 fd:03 2424 /system/lib64/libbinderthreadstate.so +76090fd000-76090fe000 rw-p 00004000 fd:03 2424 /system/lib64/libbinderthreadstate.so +76090fe000-76090ff000 r--p 00005000 fd:03 2424 /system/lib64/libbinderthreadstate.so +...... +``` + +### `xc_dl_dynsym_func()` and `xc_dl_dynsym_object()` + +```c +void *xc_dl_dynsym_func(xc_dl_t *self, const char *sym_name); +void *xc_dl_dynsym_object(xc_dl_t *self, const char *sym_name); +``` + +Used to find functions and objects in `.dynsym`. + +### `xc_dl_symtab_func()` and `xc_dl_symtab_object()` + +```c +void *xc_dl_symtab_func(xc_dl_t *self, const char *sym_name); +void *xc_dl_symtab_object(xc_dl_t *self, const char *sym_name); +``` + +Used to find functions and objects in `.symtab` and "`.symtab` in `.gnu_debugdata`". + +## History + +xCrash 2.x contains a very rudimentary module "xc_dl" for searching system library symbols, which has many problems in performance and compatibility. xCrash uses it to search a few symbols from libart, libc and libc++. + +Later, some other projects began to use the "xc_dl" module alone, including in some performance-sensitive usage scenarios. At this time, we began to realize that we need to rewrite this module, and we need a better implementation. diff --git a/src/native/libxcrash/jni/xc_dl.c b/xcrash_lib/src/main/cpp/dl/xc_dl.c similarity index 100% rename from src/native/libxcrash/jni/xc_dl.c rename to xcrash_lib/src/main/cpp/dl/xc_dl.c diff --git a/src/native/libxcrash/jni/xc_dl.h b/xcrash_lib/src/main/cpp/dl/xc_dl.h similarity index 100% rename from src/native/libxcrash/jni/xc_dl.h rename to xcrash_lib/src/main/cpp/dl/xc_dl.h diff --git a/src/native/libxcrash_dumper/jni/lzma/7z.h b/xcrash_lib/src/main/cpp/lzma/7z.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/7z.h rename to xcrash_lib/src/main/cpp/lzma/7z.h diff --git a/src/native/libxcrash_dumper/jni/lzma/7zAlloc.c b/xcrash_lib/src/main/cpp/lzma/7zAlloc.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/7zAlloc.c rename to xcrash_lib/src/main/cpp/lzma/7zAlloc.c diff --git a/src/native/libxcrash_dumper/jni/lzma/7zAlloc.h b/xcrash_lib/src/main/cpp/lzma/7zAlloc.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/7zAlloc.h rename to xcrash_lib/src/main/cpp/lzma/7zAlloc.h diff --git a/src/native/libxcrash_dumper/jni/lzma/7zArcIn.c b/xcrash_lib/src/main/cpp/lzma/7zArcIn.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/7zArcIn.c rename to xcrash_lib/src/main/cpp/lzma/7zArcIn.c diff --git a/src/native/libxcrash_dumper/jni/lzma/7zBuf.c b/xcrash_lib/src/main/cpp/lzma/7zBuf.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/7zBuf.c rename to xcrash_lib/src/main/cpp/lzma/7zBuf.c diff --git a/src/native/libxcrash_dumper/jni/lzma/7zBuf.h b/xcrash_lib/src/main/cpp/lzma/7zBuf.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/7zBuf.h rename to xcrash_lib/src/main/cpp/lzma/7zBuf.h diff --git a/src/native/libxcrash_dumper/jni/lzma/7zBuf2.c b/xcrash_lib/src/main/cpp/lzma/7zBuf2.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/7zBuf2.c rename to xcrash_lib/src/main/cpp/lzma/7zBuf2.c diff --git a/src/native/libxcrash_dumper/jni/lzma/7zCrc.c b/xcrash_lib/src/main/cpp/lzma/7zCrc.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/7zCrc.c rename to xcrash_lib/src/main/cpp/lzma/7zCrc.c diff --git a/src/native/libxcrash_dumper/jni/lzma/7zCrc.h b/xcrash_lib/src/main/cpp/lzma/7zCrc.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/7zCrc.h rename to xcrash_lib/src/main/cpp/lzma/7zCrc.h diff --git a/src/native/libxcrash_dumper/jni/lzma/7zCrcOpt.c b/xcrash_lib/src/main/cpp/lzma/7zCrcOpt.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/7zCrcOpt.c rename to xcrash_lib/src/main/cpp/lzma/7zCrcOpt.c diff --git a/src/native/libxcrash_dumper/jni/lzma/7zDec.c b/xcrash_lib/src/main/cpp/lzma/7zDec.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/7zDec.c rename to xcrash_lib/src/main/cpp/lzma/7zDec.c diff --git a/src/native/libxcrash_dumper/jni/lzma/7zFile.c b/xcrash_lib/src/main/cpp/lzma/7zFile.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/7zFile.c rename to xcrash_lib/src/main/cpp/lzma/7zFile.c diff --git a/src/native/libxcrash_dumper/jni/lzma/7zFile.h b/xcrash_lib/src/main/cpp/lzma/7zFile.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/7zFile.h rename to xcrash_lib/src/main/cpp/lzma/7zFile.h diff --git a/src/native/libxcrash_dumper/jni/lzma/7zStream.c b/xcrash_lib/src/main/cpp/lzma/7zStream.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/7zStream.c rename to xcrash_lib/src/main/cpp/lzma/7zStream.c diff --git a/src/native/libxcrash_dumper/jni/lzma/7zTypes.h b/xcrash_lib/src/main/cpp/lzma/7zTypes.h similarity index 94% rename from src/native/libxcrash_dumper/jni/lzma/7zTypes.h rename to xcrash_lib/src/main/cpp/lzma/7zTypes.h index 4977cda..0a3cd1f 100644 --- a/src/native/libxcrash_dumper/jni/lzma/7zTypes.h +++ b/xcrash_lib/src/main/cpp/lzma/7zTypes.h @@ -60,7 +60,7 @@ typedef int WRes; #ifndef RINOK -#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } +#define RINOK(x) do { int __result__ = (x); if (__result__ != 0) return __result__; } while(0) #endif typedef unsigned char Byte; diff --git a/src/native/libxcrash_dumper/jni/lzma/7zVersion.h b/xcrash_lib/src/main/cpp/lzma/7zVersion.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/7zVersion.h rename to xcrash_lib/src/main/cpp/lzma/7zVersion.h diff --git a/src/native/libxcrash_dumper/jni/lzma/7zVersion.rc b/xcrash_lib/src/main/cpp/lzma/7zVersion.rc similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/7zVersion.rc rename to xcrash_lib/src/main/cpp/lzma/7zVersion.rc diff --git a/src/native/libxcrash_dumper/jni/lzma/Aes.c b/xcrash_lib/src/main/cpp/lzma/Aes.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Aes.c rename to xcrash_lib/src/main/cpp/lzma/Aes.c diff --git a/src/native/libxcrash_dumper/jni/lzma/Aes.h b/xcrash_lib/src/main/cpp/lzma/Aes.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Aes.h rename to xcrash_lib/src/main/cpp/lzma/Aes.h diff --git a/src/native/libxcrash_dumper/jni/lzma/AesOpt.c b/xcrash_lib/src/main/cpp/lzma/AesOpt.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/AesOpt.c rename to xcrash_lib/src/main/cpp/lzma/AesOpt.c diff --git a/src/native/libxcrash_dumper/jni/lzma/Alloc.c b/xcrash_lib/src/main/cpp/lzma/Alloc.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Alloc.c rename to xcrash_lib/src/main/cpp/lzma/Alloc.c diff --git a/src/native/libxcrash_dumper/jni/lzma/Alloc.h b/xcrash_lib/src/main/cpp/lzma/Alloc.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Alloc.h rename to xcrash_lib/src/main/cpp/lzma/Alloc.h diff --git a/src/native/libxcrash_dumper/jni/lzma/Bcj2.c b/xcrash_lib/src/main/cpp/lzma/Bcj2.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Bcj2.c rename to xcrash_lib/src/main/cpp/lzma/Bcj2.c diff --git a/src/native/libxcrash_dumper/jni/lzma/Bcj2.h b/xcrash_lib/src/main/cpp/lzma/Bcj2.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Bcj2.h rename to xcrash_lib/src/main/cpp/lzma/Bcj2.h diff --git a/src/native/libxcrash_dumper/jni/lzma/Bcj2Enc.c b/xcrash_lib/src/main/cpp/lzma/Bcj2Enc.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Bcj2Enc.c rename to xcrash_lib/src/main/cpp/lzma/Bcj2Enc.c diff --git a/src/native/libxcrash_dumper/jni/lzma/Bra.c b/xcrash_lib/src/main/cpp/lzma/Bra.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Bra.c rename to xcrash_lib/src/main/cpp/lzma/Bra.c diff --git a/src/native/libxcrash_dumper/jni/lzma/Bra.h b/xcrash_lib/src/main/cpp/lzma/Bra.h similarity index 93% rename from src/native/libxcrash_dumper/jni/lzma/Bra.h rename to xcrash_lib/src/main/cpp/lzma/Bra.h index aba8dce..1e7d3ea 100644 --- a/src/native/libxcrash_dumper/jni/lzma/Bra.h +++ b/xcrash_lib/src/main/cpp/lzma/Bra.h @@ -51,7 +51,7 @@ in CALL instructions to increase the compression ratio. } */ -#define x86_Convert_Init(state) { state = 0; } +#define x86_Convert_Init(state) do { state = 0; } while(0) SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding); SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); diff --git a/src/native/libxcrash_dumper/jni/lzma/Bra86.c b/xcrash_lib/src/main/cpp/lzma/Bra86.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Bra86.c rename to xcrash_lib/src/main/cpp/lzma/Bra86.c diff --git a/src/native/libxcrash_dumper/jni/lzma/BraIA64.c b/xcrash_lib/src/main/cpp/lzma/BraIA64.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/BraIA64.c rename to xcrash_lib/src/main/cpp/lzma/BraIA64.c diff --git a/src/native/libxcrash_dumper/jni/lzma/Compiler.h b/xcrash_lib/src/main/cpp/lzma/Compiler.h similarity index 94% rename from src/native/libxcrash_dumper/jni/lzma/Compiler.h rename to xcrash_lib/src/main/cpp/lzma/Compiler.h index c788648..71606ad 100644 --- a/src/native/libxcrash_dumper/jni/lzma/Compiler.h +++ b/xcrash_lib/src/main/cpp/lzma/Compiler.h @@ -27,7 +27,7 @@ #endif -#define UNUSED_VAR(x) (void)x; +#define UNUSED_VAR(x) (void)x /* #define UNUSED_VAR(x) x=x; */ #endif diff --git a/src/native/libxcrash_dumper/jni/lzma/CpuArch.c b/xcrash_lib/src/main/cpp/lzma/CpuArch.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/CpuArch.c rename to xcrash_lib/src/main/cpp/lzma/CpuArch.c diff --git a/src/native/libxcrash_dumper/jni/lzma/CpuArch.h b/xcrash_lib/src/main/cpp/lzma/CpuArch.h similarity index 93% rename from src/native/libxcrash_dumper/jni/lzma/CpuArch.h rename to xcrash_lib/src/main/cpp/lzma/CpuArch.h index 7fb2728..743a210 100644 --- a/src/native/libxcrash_dumper/jni/lzma/CpuArch.h +++ b/xcrash_lib/src/main/cpp/lzma/CpuArch.h @@ -203,7 +203,7 @@ MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned mem #define GetUi64(p) (*(const UInt64 *)(const void *)(p)) #define SetUi16(p, v) { *(UInt16 *)(p) = (v); } -#define SetUi32(p, v) { *(UInt32 *)(p) = (v); } +#define SetUi32(p, v) do { *(UInt32 *)(p) = (v); } while(0) #define SetUi64(p, v) { *(UInt64 *)(p) = (v); } #else @@ -224,11 +224,11 @@ MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned mem _ppp_[0] = (Byte)_vvv_; \ _ppp_[1] = (Byte)(_vvv_ >> 8); } -#define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \ +#define SetUi32(p, v) do { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \ _ppp_[0] = (Byte)_vvv_; \ _ppp_[1] = (Byte)(_vvv_ >> 8); \ _ppp_[2] = (Byte)(_vvv_ >> 16); \ - _ppp_[3] = (Byte)(_vvv_ >> 24); } + _ppp_[3] = (Byte)(_vvv_ >> 24); } while(0); #define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \ SetUi32(_ppp2_ , (UInt32)_vvv2_); \ diff --git a/src/native/libxcrash_dumper/jni/lzma/Delta.c b/xcrash_lib/src/main/cpp/lzma/Delta.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Delta.c rename to xcrash_lib/src/main/cpp/lzma/Delta.c diff --git a/src/native/libxcrash_dumper/jni/lzma/Delta.h b/xcrash_lib/src/main/cpp/lzma/Delta.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Delta.h rename to xcrash_lib/src/main/cpp/lzma/Delta.h diff --git a/src/native/libxcrash_dumper/jni/lzma/DllSecur.c b/xcrash_lib/src/main/cpp/lzma/DllSecur.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/DllSecur.c rename to xcrash_lib/src/main/cpp/lzma/DllSecur.c diff --git a/src/native/libxcrash_dumper/jni/lzma/DllSecur.h b/xcrash_lib/src/main/cpp/lzma/DllSecur.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/DllSecur.h rename to xcrash_lib/src/main/cpp/lzma/DllSecur.h diff --git a/src/native/libxcrash_dumper/jni/lzma/LICENSE b/xcrash_lib/src/main/cpp/lzma/LICENSE similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/LICENSE rename to xcrash_lib/src/main/cpp/lzma/LICENSE diff --git a/src/native/libxcrash_dumper/jni/lzma/LzFind.c b/xcrash_lib/src/main/cpp/lzma/LzFind.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/LzFind.c rename to xcrash_lib/src/main/cpp/lzma/LzFind.c diff --git a/src/native/libxcrash_dumper/jni/lzma/LzFind.h b/xcrash_lib/src/main/cpp/lzma/LzFind.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/LzFind.h rename to xcrash_lib/src/main/cpp/lzma/LzFind.h diff --git a/src/native/libxcrash_dumper/jni/lzma/LzFindMt.c b/xcrash_lib/src/main/cpp/lzma/LzFindMt.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/LzFindMt.c rename to xcrash_lib/src/main/cpp/lzma/LzFindMt.c diff --git a/src/native/libxcrash_dumper/jni/lzma/LzFindMt.h b/xcrash_lib/src/main/cpp/lzma/LzFindMt.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/LzFindMt.h rename to xcrash_lib/src/main/cpp/lzma/LzFindMt.h diff --git a/src/native/libxcrash_dumper/jni/lzma/LzHash.h b/xcrash_lib/src/main/cpp/lzma/LzHash.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/LzHash.h rename to xcrash_lib/src/main/cpp/lzma/LzHash.h diff --git a/src/native/libxcrash_dumper/jni/lzma/Lzma2Dec.c b/xcrash_lib/src/main/cpp/lzma/Lzma2Dec.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Lzma2Dec.c rename to xcrash_lib/src/main/cpp/lzma/Lzma2Dec.c diff --git a/src/native/libxcrash_dumper/jni/lzma/Lzma2Dec.h b/xcrash_lib/src/main/cpp/lzma/Lzma2Dec.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Lzma2Dec.h rename to xcrash_lib/src/main/cpp/lzma/Lzma2Dec.h diff --git a/src/native/libxcrash_dumper/jni/lzma/Lzma2DecMt.c b/xcrash_lib/src/main/cpp/lzma/Lzma2DecMt.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Lzma2DecMt.c rename to xcrash_lib/src/main/cpp/lzma/Lzma2DecMt.c diff --git a/src/native/libxcrash_dumper/jni/lzma/Lzma2DecMt.h b/xcrash_lib/src/main/cpp/lzma/Lzma2DecMt.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Lzma2DecMt.h rename to xcrash_lib/src/main/cpp/lzma/Lzma2DecMt.h diff --git a/src/native/libxcrash_dumper/jni/lzma/Lzma2Enc.c b/xcrash_lib/src/main/cpp/lzma/Lzma2Enc.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Lzma2Enc.c rename to xcrash_lib/src/main/cpp/lzma/Lzma2Enc.c diff --git a/src/native/libxcrash_dumper/jni/lzma/Lzma2Enc.h b/xcrash_lib/src/main/cpp/lzma/Lzma2Enc.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Lzma2Enc.h rename to xcrash_lib/src/main/cpp/lzma/Lzma2Enc.h diff --git a/src/native/libxcrash_dumper/jni/lzma/Lzma86.h b/xcrash_lib/src/main/cpp/lzma/Lzma86.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Lzma86.h rename to xcrash_lib/src/main/cpp/lzma/Lzma86.h diff --git a/src/native/libxcrash_dumper/jni/lzma/Lzma86Dec.c b/xcrash_lib/src/main/cpp/lzma/Lzma86Dec.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Lzma86Dec.c rename to xcrash_lib/src/main/cpp/lzma/Lzma86Dec.c diff --git a/src/native/libxcrash_dumper/jni/lzma/Lzma86Enc.c b/xcrash_lib/src/main/cpp/lzma/Lzma86Enc.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Lzma86Enc.c rename to xcrash_lib/src/main/cpp/lzma/Lzma86Enc.c diff --git a/src/native/libxcrash_dumper/jni/lzma/LzmaDec.c b/xcrash_lib/src/main/cpp/lzma/LzmaDec.c similarity index 92% rename from src/native/libxcrash_dumper/jni/lzma/LzmaDec.c rename to xcrash_lib/src/main/cpp/lzma/LzmaDec.c index 962b94b..05f0f48 100644 --- a/src/native/libxcrash_dumper/jni/lzma/LzmaDec.c +++ b/xcrash_lib/src/main/cpp/lzma/LzmaDec.c @@ -17,26 +17,26 @@ #define RC_INIT_SIZE 5 -#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } +#define NORMALIZE do { if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } } while(0) #define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) -#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); -#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); +#define UPDATE_0(p) do { range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); } while(0) +#define UPDATE_1(p) do { range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); } while(0) #define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ { UPDATE_0(p); i = (i + i); A0; } else \ { UPDATE_1(p); i = (i + i) + 1; A1; } -#define TREE_GET_BIT(probs, i) { GET_BIT2(probs + i, i, ;, ;); } +#define TREE_GET_BIT(probs, i) do { GET_BIT2(probs + i, i, ;, ;); } while(0) -#define REV_BIT(p, i, A0, A1) IF_BIT_0(p + i) \ +#define REV_BIT(p, i, A0, A1) do { IF_BIT_0(p + i) \ { UPDATE_0(p + i); A0; } else \ - { UPDATE_1(p + i); A1; } + { UPDATE_1(p + i); A1; } } while(0) #define REV_BIT_VAR( p, i, m) REV_BIT(p, i, i += m; m += m, m += m; i += m; ) #define REV_BIT_CONST(p, i, m) REV_BIT(p, i, i += m; , i += m * 2; ) #define REV_BIT_LAST( p, i, m) REV_BIT(p, i, i -= m , ; ) #define TREE_DECODE(probs, limit, i) \ - { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } + do { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } while(0) /* #define _LZMA_SIZE_OPT */ @@ -44,17 +44,17 @@ #define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) #else #define TREE_6_DECODE(probs, i) \ - { i = 1; \ + do { i = 1; \ TREE_GET_BIT(probs, i); \ TREE_GET_BIT(probs, i); \ TREE_GET_BIT(probs, i); \ TREE_GET_BIT(probs, i); \ TREE_GET_BIT(probs, i); \ TREE_GET_BIT(probs, i); \ - i -= 0x40; } + i -= 0x40; } while(0) #endif -#define NORMAL_LITER_DEC TREE_GET_BIT(prob, symbol) +#define NORMAL_LITER_DEC TREE_GET_BIT(prob, symbol); #define MATCHED_LITER_DEC \ matchByte += matchByte; \ bit = offs; \ @@ -64,22 +64,22 @@ -#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } +#define NORMALIZE_CHECK do { if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } } while(0) #define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) -#define UPDATE_0_CHECK range = bound; -#define UPDATE_1_CHECK range -= bound; code -= bound; +#define UPDATE_0_CHECK do { range = bound; } while(0) +#define UPDATE_1_CHECK do { range -= bound; code -= bound; } while(0) #define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ { UPDATE_0_CHECK; i = (i + i); A0; } else \ { UPDATE_1_CHECK; i = (i + i) + 1; A1; } #define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) #define TREE_DECODE_CHECK(probs, limit, i) \ - { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } + do { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } while(0) -#define REV_BIT_CHECK(p, i, m) IF_BIT_0_CHECK(p + i) \ +#define REV_BIT_CHECK(p, i, m) do { IF_BIT_0_CHECK(p + i) \ { UPDATE_0_CHECK; i += m; m += m; } else \ - { UPDATE_1_CHECK; m += m; i += m; } + { UPDATE_1_CHECK; m += m; i += m; } } while(0) #define kNumPosBitsMax 4 @@ -472,7 +472,7 @@ int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit numDirectBits -= kNumAlignBits; do { - NORMALIZE + NORMALIZE; range >>= 1; { @@ -675,7 +675,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS prob = probs + IsMatch + COMBINED_PS_STATE; IF_BIT_0_CHECK(prob) { - UPDATE_0_CHECK + UPDATE_0_CHECK; /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ @@ -823,7 +823,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS numDirectBits -= kNumAlignBits; do { - NORMALIZE_CHECK + NORMALIZE_CHECK; range >>= 1; code -= range & (((code - range) >> 31) - 1); /* if (code >= range) code -= range; */ @@ -1137,8 +1137,8 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll { UInt32 dictSize = propNew.dicSize; SizeT mask = ((UInt32)1 << 12) - 1; - if (dictSize >= ((UInt32)1 << 30)) mask = ((UInt32)1 << 22) - 1; - else if (dictSize >= ((UInt32)1 << 22)) mask = ((UInt32)1 << 20) - 1;; + if (dictSize >= ((UInt32)1 << 30)) mask = ((UInt32)1 << 22) - 1; + else if (dictSize >= ((UInt32)1 << 22)) mask = ((UInt32)1 << 20) - 1; dicBufSize = ((SizeT)dictSize + mask) & ~mask; if (dicBufSize < dictSize) dicBufSize = dictSize; diff --git a/src/native/libxcrash_dumper/jni/lzma/LzmaDec.h b/xcrash_lib/src/main/cpp/lzma/LzmaDec.h similarity index 95% rename from src/native/libxcrash_dumper/jni/lzma/LzmaDec.h rename to xcrash_lib/src/main/cpp/lzma/LzmaDec.h index 28ce60c..46a83b6 100644 --- a/src/native/libxcrash_dumper/jni/lzma/LzmaDec.h +++ b/xcrash_lib/src/main/cpp/lzma/LzmaDec.h @@ -73,7 +73,7 @@ typedef struct Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; } CLzmaDec; -#define LzmaDec_Construct(p) { (p)->dic = NULL; (p)->probs = NULL; } +#define LzmaDec_Construct(p) do { (p)->dic = NULL; (p)->probs = NULL; } while(0) void LzmaDec_Init(CLzmaDec *p); diff --git a/src/native/libxcrash_dumper/jni/lzma/LzmaEnc.c b/xcrash_lib/src/main/cpp/lzma/LzmaEnc.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/LzmaEnc.c rename to xcrash_lib/src/main/cpp/lzma/LzmaEnc.c diff --git a/src/native/libxcrash_dumper/jni/lzma/LzmaEnc.h b/xcrash_lib/src/main/cpp/lzma/LzmaEnc.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/LzmaEnc.h rename to xcrash_lib/src/main/cpp/lzma/LzmaEnc.h diff --git a/src/native/libxcrash_dumper/jni/lzma/LzmaLib.c b/xcrash_lib/src/main/cpp/lzma/LzmaLib.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/LzmaLib.c rename to xcrash_lib/src/main/cpp/lzma/LzmaLib.c diff --git a/src/native/libxcrash_dumper/jni/lzma/LzmaLib.h b/xcrash_lib/src/main/cpp/lzma/LzmaLib.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/LzmaLib.h rename to xcrash_lib/src/main/cpp/lzma/LzmaLib.h diff --git a/src/native/libxcrash_dumper/jni/lzma/MtCoder.c b/xcrash_lib/src/main/cpp/lzma/MtCoder.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/MtCoder.c rename to xcrash_lib/src/main/cpp/lzma/MtCoder.c diff --git a/src/native/libxcrash_dumper/jni/lzma/MtCoder.h b/xcrash_lib/src/main/cpp/lzma/MtCoder.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/MtCoder.h rename to xcrash_lib/src/main/cpp/lzma/MtCoder.h diff --git a/src/native/libxcrash_dumper/jni/lzma/MtDec.c b/xcrash_lib/src/main/cpp/lzma/MtDec.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/MtDec.c rename to xcrash_lib/src/main/cpp/lzma/MtDec.c diff --git a/src/native/libxcrash_dumper/jni/lzma/MtDec.h b/xcrash_lib/src/main/cpp/lzma/MtDec.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/MtDec.h rename to xcrash_lib/src/main/cpp/lzma/MtDec.h diff --git a/src/native/libxcrash_dumper/jni/lzma/Ppmd.h b/xcrash_lib/src/main/cpp/lzma/Ppmd.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Ppmd.h rename to xcrash_lib/src/main/cpp/lzma/Ppmd.h diff --git a/src/native/libxcrash_dumper/jni/lzma/Ppmd7.c b/xcrash_lib/src/main/cpp/lzma/Ppmd7.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Ppmd7.c rename to xcrash_lib/src/main/cpp/lzma/Ppmd7.c diff --git a/src/native/libxcrash_dumper/jni/lzma/Ppmd7.h b/xcrash_lib/src/main/cpp/lzma/Ppmd7.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Ppmd7.h rename to xcrash_lib/src/main/cpp/lzma/Ppmd7.h diff --git a/src/native/libxcrash_dumper/jni/lzma/Ppmd7Dec.c b/xcrash_lib/src/main/cpp/lzma/Ppmd7Dec.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Ppmd7Dec.c rename to xcrash_lib/src/main/cpp/lzma/Ppmd7Dec.c diff --git a/src/native/libxcrash_dumper/jni/lzma/Ppmd7Enc.c b/xcrash_lib/src/main/cpp/lzma/Ppmd7Enc.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Ppmd7Enc.c rename to xcrash_lib/src/main/cpp/lzma/Ppmd7Enc.c diff --git a/src/native/libxcrash_dumper/jni/lzma/Precomp.h b/xcrash_lib/src/main/cpp/lzma/Precomp.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Precomp.h rename to xcrash_lib/src/main/cpp/lzma/Precomp.h diff --git a/src/native/libxcrash_dumper/jni/lzma/RotateDefs.h b/xcrash_lib/src/main/cpp/lzma/RotateDefs.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/RotateDefs.h rename to xcrash_lib/src/main/cpp/lzma/RotateDefs.h diff --git a/src/native/libxcrash_dumper/jni/lzma/Sha256.c b/xcrash_lib/src/main/cpp/lzma/Sha256.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Sha256.c rename to xcrash_lib/src/main/cpp/lzma/Sha256.c diff --git a/src/native/libxcrash_dumper/jni/lzma/Sha256.h b/xcrash_lib/src/main/cpp/lzma/Sha256.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Sha256.h rename to xcrash_lib/src/main/cpp/lzma/Sha256.h diff --git a/src/native/libxcrash_dumper/jni/lzma/Sort.c b/xcrash_lib/src/main/cpp/lzma/Sort.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Sort.c rename to xcrash_lib/src/main/cpp/lzma/Sort.c diff --git a/src/native/libxcrash_dumper/jni/lzma/Sort.h b/xcrash_lib/src/main/cpp/lzma/Sort.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Sort.h rename to xcrash_lib/src/main/cpp/lzma/Sort.h diff --git a/src/native/libxcrash_dumper/jni/lzma/Threads.c b/xcrash_lib/src/main/cpp/lzma/Threads.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Threads.c rename to xcrash_lib/src/main/cpp/lzma/Threads.c diff --git a/src/native/libxcrash_dumper/jni/lzma/Threads.h b/xcrash_lib/src/main/cpp/lzma/Threads.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Threads.h rename to xcrash_lib/src/main/cpp/lzma/Threads.h diff --git a/src/native/libxcrash_dumper/jni/lzma/Xz.c b/xcrash_lib/src/main/cpp/lzma/Xz.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Xz.c rename to xcrash_lib/src/main/cpp/lzma/Xz.c diff --git a/src/native/libxcrash_dumper/jni/lzma/Xz.h b/xcrash_lib/src/main/cpp/lzma/Xz.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/Xz.h rename to xcrash_lib/src/main/cpp/lzma/Xz.h diff --git a/src/native/libxcrash_dumper/jni/lzma/XzCrc64.c b/xcrash_lib/src/main/cpp/lzma/XzCrc64.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/XzCrc64.c rename to xcrash_lib/src/main/cpp/lzma/XzCrc64.c diff --git a/src/native/libxcrash_dumper/jni/lzma/XzCrc64.h b/xcrash_lib/src/main/cpp/lzma/XzCrc64.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/XzCrc64.h rename to xcrash_lib/src/main/cpp/lzma/XzCrc64.h diff --git a/src/native/libxcrash_dumper/jni/lzma/XzCrc64Opt.c b/xcrash_lib/src/main/cpp/lzma/XzCrc64Opt.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/XzCrc64Opt.c rename to xcrash_lib/src/main/cpp/lzma/XzCrc64Opt.c diff --git a/src/native/libxcrash_dumper/jni/lzma/XzDec.c b/xcrash_lib/src/main/cpp/lzma/XzDec.c similarity index 95% rename from src/native/libxcrash_dumper/jni/lzma/XzDec.c rename to xcrash_lib/src/main/cpp/lzma/XzDec.c index ebf1983..597321d 100644 --- a/src/native/libxcrash_dumper/jni/lzma/XzDec.c +++ b/xcrash_lib/src/main/cpp/lzma/XzDec.c @@ -22,7 +22,7 @@ #ifdef SHOW_DEBUG_INFO #define PRF(x) x #else -#define PRF(x) +#define PRF(x) do {} while(0) #endif #define PRF_STR(s) PRF(printf("\n" s "\n")) @@ -771,8 +771,8 @@ static Bool Xz_CheckFooter(CXzStreamFlags flags, UInt64 indexSize, const Byte *b } #define READ_VARINT_AND_CHECK(buf, pos, size, res) \ - { unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \ - if (s == 0) return SZ_ERROR_ARCHIVE; pos += s; } + do { unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \ + if (s == 0) return SZ_ERROR_ARCHIVE; pos += s; } while(0) static Bool XzBlock_AreSupportedFilters(const CXzBlock *p) diff --git a/src/native/libxcrash_dumper/jni/lzma/XzEnc.c b/xcrash_lib/src/main/cpp/lzma/XzEnc.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/XzEnc.c rename to xcrash_lib/src/main/cpp/lzma/XzEnc.c diff --git a/src/native/libxcrash_dumper/jni/lzma/XzEnc.h b/xcrash_lib/src/main/cpp/lzma/XzEnc.h similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/XzEnc.h rename to xcrash_lib/src/main/cpp/lzma/XzEnc.h diff --git a/src/native/libxcrash_dumper/jni/lzma/XzIn.c b/xcrash_lib/src/main/cpp/lzma/XzIn.c similarity index 100% rename from src/native/libxcrash_dumper/jni/lzma/XzIn.c rename to xcrash_lib/src/main/cpp/lzma/XzIn.c diff --git a/xcrash_lib/src/main/cpp/xcrash.exports b/xcrash_lib/src/main/cpp/xcrash.exports new file mode 100644 index 0000000..47d8c51 --- /dev/null +++ b/xcrash_lib/src/main/cpp/xcrash.exports @@ -0,0 +1,12 @@ +{ + global: + JNI_OnLoad; + xc_test_crash; + xc_test_call_1; + xc_test_call_2; + xc_test_call_3; + xc_test_call_4; + + local: + *; +}; diff --git a/src/native/libxcrash/jni/xc_common.c b/xcrash_lib/src/main/cpp/xcrash/xc_common.c similarity index 100% rename from src/native/libxcrash/jni/xc_common.c rename to xcrash_lib/src/main/cpp/xcrash/xc_common.c diff --git a/src/native/libxcrash/jni/xc_common.h b/xcrash_lib/src/main/cpp/xcrash/xc_common.h similarity index 100% rename from src/native/libxcrash/jni/xc_common.h rename to xcrash_lib/src/main/cpp/xcrash/xc_common.h diff --git a/src/native/libxcrash/jni/xc_crash.c b/xcrash_lib/src/main/cpp/xcrash/xc_crash.c similarity index 97% rename from src/native/libxcrash/jni/xc_crash.c rename to xcrash_lib/src/main/cpp/xcrash/xc_crash.c index 9888a74..1bd8e6c 100644 --- a/src/native/libxcrash/jni/xc_crash.c +++ b/xcrash_lib/src/main/cpp/xcrash/xc_crash.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -52,11 +53,13 @@ #include "xcc_b64.h" #include "xcc_util.h" #include "xc_crash.h" +#include "xc_trace.h" #include "xc_common.h" #include "xc_dl.h" #include "xc_util.h" #include "xc_jni.h" #include "xc_fallback.h" +#include "xcd_log.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu-statement-expression" @@ -254,7 +257,10 @@ static void xc_xcrash_record_java_stacktrace() if(NULL == (cerr = xc_dl_sym(libcpp, XCC_UTIL_LIBCPP_CERR))) goto end; //peek libart.so - if(xc_common_api_level >= 29) libart = xc_dl_create(XCC_UTIL_LIBART_APEX); + if(xc_common_api_level >= 30) + libart = xc_dl_create(XCC_UTIL_LIBART_APEX_30); + else if(xc_common_api_level == 29) + libart = xc_dl_create(XCC_UTIL_LIBART_APEX_29); if(NULL == libart && NULL == (libart = xc_dl_create(XCC_UTIL_LIBART))) goto end; if(NULL == (current = (xcc_util_libart_thread_current_t)xc_dl_sym(libart, XCC_UTIL_LIBART_THREAD_CURRENT))) goto end; if(NULL == (dump = (xcc_util_libart_thread_dump_t)xc_dl_sym(libart, XCC_UTIL_LIBART_THREAD_DUMP))) @@ -411,6 +417,13 @@ static void xc_crash_signal_handler(int sig, siginfo_t *si, void *uc) if(0 != xcc_signal_crash_ignore()) goto exit; } + if(XC_TRACE_DUMP_ON_GOING == xc_trace_dump_status) + { + xc_trace_dump_status = XC_TRACE_DUMP_ART_CRASH; + XCD_LOG_WARN("meet error sig(%d) while calling ART dump trace\n", sig); + siglongjmp(jmpenv, 1); + } + //save crash time clock_gettime(CLOCK_REALTIME, &crash_tp); xc_crash_time = (uint64_t)(crash_tp.tv_sec) * 1000 * 1000 + (uint64_t)crash_tp.tv_nsec / 1000; @@ -448,7 +461,8 @@ static void xc_crash_signal_handler(int sig, siginfo_t *si, void *uc) if(EINVAL == errno) { //this kernel does not support PR_SET_PTRACER_ANY, or Yama is not enabled - ; + //errno = errno; + (void)errno; } else { diff --git a/src/native/libxcrash/jni/xc_crash.h b/xcrash_lib/src/main/cpp/xcrash/xc_crash.h similarity index 100% rename from src/native/libxcrash/jni/xc_crash.h rename to xcrash_lib/src/main/cpp/xcrash/xc_crash.h diff --git a/src/native/libxcrash/jni/xc_fallback.c b/xcrash_lib/src/main/cpp/xcrash/xc_fallback.c similarity index 100% rename from src/native/libxcrash/jni/xc_fallback.c rename to xcrash_lib/src/main/cpp/xcrash/xc_fallback.c diff --git a/src/native/libxcrash/jni/xc_fallback.h b/xcrash_lib/src/main/cpp/xcrash/xc_fallback.h similarity index 100% rename from src/native/libxcrash/jni/xc_fallback.h rename to xcrash_lib/src/main/cpp/xcrash/xc_fallback.h diff --git a/src/native/libxcrash/jni/xc_jni.c b/xcrash_lib/src/main/cpp/xcrash/xc_jni.c similarity index 100% rename from src/native/libxcrash/jni/xc_jni.c rename to xcrash_lib/src/main/cpp/xcrash/xc_jni.c diff --git a/src/native/libxcrash/jni/xc_jni.h b/xcrash_lib/src/main/cpp/xcrash/xc_jni.h similarity index 100% rename from src/native/libxcrash/jni/xc_jni.h rename to xcrash_lib/src/main/cpp/xcrash/xc_jni.h diff --git a/src/native/libxcrash/jni/xc_test.c b/xcrash_lib/src/main/cpp/xcrash/xc_test.c similarity index 100% rename from src/native/libxcrash/jni/xc_test.c rename to xcrash_lib/src/main/cpp/xcrash/xc_test.c diff --git a/src/native/libxcrash/jni/xc_test.h b/xcrash_lib/src/main/cpp/xcrash/xc_test.h similarity index 100% rename from src/native/libxcrash/jni/xc_test.h rename to xcrash_lib/src/main/cpp/xcrash/xc_test.h diff --git a/src/native/libxcrash/jni/xc_trace.c b/xcrash_lib/src/main/cpp/xcrash/xc_trace.c similarity index 89% rename from src/native/libxcrash/jni/xc_trace.c rename to xcrash_lib/src/main/cpp/xcrash/xc_trace.c index e15cd94..6a88003 100644 --- a/src/native/libxcrash/jni/xc_trace.c +++ b/xcrash_lib/src/main/cpp/xcrash/xc_trace.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -43,10 +44,15 @@ #include "xc_dl.h" #include "xc_jni.h" #include "xc_util.h" +#include "xcd_log.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu-statement-expression" + +#define XC_TRACE_FAST_CALLBACK_METHOD_NAME "traceCallbackBeforeDump" +#define XC_TRACE_FAST_CALLBACK_METHOD_SIGNATURE "()V" + #define XC_TRACE_CALLBACK_METHOD_NAME "traceCallback" #define XC_TRACE_CALLBACK_METHOD_SIGNATURE "(Ljava/lang/String;Ljava/lang/String;)V" @@ -76,9 +82,13 @@ static int xc_trace_dump_fds; static int xc_trace_dump_network_info; //callback +static jmethodID xc_trace_fast_cb_method = NULL; static jmethodID xc_trace_cb_method = NULL; static int xc_trace_notifier = -1; +xc_trace_dump_status_t xc_trace_dump_status = XC_TRACE_DUMP_NOT_START; +sigjmp_buf jmpenv; + static void xc_trace_load_signal_catcher_tid() { char buf[256]; @@ -142,7 +152,10 @@ static int xc_trace_load_symbols() if(NULL == libcpp && NULL == (libcpp = xc_dl_create(XCC_UTIL_LIBCPP))) goto end; if(NULL == (xc_trace_libcpp_cerr = xc_dl_sym(libcpp, XCC_UTIL_LIBCPP_CERR))) goto end; - if(xc_common_api_level >= 29) libart = xc_dl_create(XCC_UTIL_LIBART_APEX); + if(xc_common_api_level >= 30) + libart = xc_dl_create(XCC_UTIL_LIBART_APEX_30); + else if(xc_common_api_level == 29) + libart = xc_dl_create(XCC_UTIL_LIBART_APEX_29); if(NULL == libart && NULL == (libart = xc_dl_create(XCC_UTIL_LIBART))) goto end; if(NULL == (xc_trace_libart_runtime_instance = (void **)xc_dl_sym(libart, XCC_UTIL_LIBART_RUNTIME_INSTANCE))) goto end; if(NULL == (xc_trace_libart_runtime_dump = (xcc_util_libart_runtime_dump_t)xc_dl_sym(libart, XCC_UTIL_LIBART_RUNTIME_DUMP))) goto end; @@ -175,7 +188,6 @@ static int xc_trace_check_address_valid() int r = XCC_ERRNO_INVAL; if(NULL == (f = fopen("/proc/self/maps", "r"))) return XCC_ERRNO_SYS; - while(fgets(line, sizeof(line), f)) { if(2 != sscanf(line, "%"SCNxPTR"-%"SCNxPTR" r", &start, &end)) continue; @@ -202,6 +214,7 @@ static int xc_trace_check_address_valid() } } if(0 != r) goto end; + if(xc_common_api_level >= 30) goto end; r = XCC_ERRNO_INVAL; rewind(f); @@ -216,7 +229,6 @@ static int xc_trace_check_address_valid() break; } } - end: fclose(f); return r; @@ -307,6 +319,10 @@ static void *xc_trace_dumper(void *arg) //check if process already crashed if(xc_common_native_crashed || xc_common_java_crashed) break; + if(NULL == xc_trace_fast_cb_method) continue; + (*env)->CallStaticVoidMethod(env, xc_common_cb_class, xc_trace_fast_cb_method); + XC_JNI_IGNORE_PENDING_EXCEPTION(); + //trace time if(0 != gettimeofday(&tv, NULL)) break; trace_time = (uint64_t)(tv.tv_sec) * 1000 * 1000 + (uint64_t)tv.tv_usec; @@ -338,11 +354,22 @@ static void *xc_trace_dumper(void *arg) if(0 != xcc_util_write_str(fd, "Failed to duplicate FD.\n")) goto end; goto skip; } - if(xc_trace_is_lollipop) - xc_trace_libart_dbg_suspend(); - xc_trace_libart_runtime_dump(*xc_trace_libart_runtime_instance, xc_trace_libcpp_cerr); - if(xc_trace_is_lollipop) - xc_trace_libart_dbg_resume(); + + xc_trace_dump_status = XC_TRACE_DUMP_ON_GOING; + if(sigsetjmp(jmpenv, 1) == 0) + { + if(xc_trace_is_lollipop) + xc_trace_libart_dbg_suspend(); + xc_trace_libart_runtime_dump(*xc_trace_libart_runtime_instance, xc_trace_libcpp_cerr); + if(xc_trace_is_lollipop) + xc_trace_libart_dbg_resume(); + } + else + { + fflush(NULL); + XCD_LOG_WARN("longjmp to skip dumping trace\n"); + } + dup2(xc_common_fd_null, STDERR_FILENO); skip: @@ -361,7 +388,8 @@ static void *xc_trace_dumper(void *arg) xc_common_close_trace_log(fd); //rethrow SIGQUIT to ART Signal Catcher - if(xc_trace_rethrow) xc_trace_send_sigquit(); + if(xc_trace_rethrow && (XC_TRACE_DUMP_ART_CRASH != xc_trace_dump_status)) xc_trace_send_sigquit(); + xc_trace_dump_status = XC_TRACE_DUMP_END; //JNI callback //Do we need to implement an emergency buffer for disk exhausted? @@ -398,12 +426,16 @@ static void xc_trace_handler(int sig, siginfo_t *si, void *uc) static void xc_trace_init_callback(JNIEnv *env) { if(NULL == xc_common_cb_class) return; - + + xc_trace_fast_cb_method = (*env)->GetStaticMethodID(env, xc_common_cb_class, XC_TRACE_FAST_CALLBACK_METHOD_NAME, XC_TRACE_FAST_CALLBACK_METHOD_SIGNATURE); + XC_JNI_CHECK_NULL_AND_PENDING_EXCEPTION(xc_trace_fast_cb_method, err); + xc_trace_cb_method = (*env)->GetStaticMethodID(env, xc_common_cb_class, XC_TRACE_CALLBACK_METHOD_NAME, XC_TRACE_CALLBACK_METHOD_SIGNATURE); XC_JNI_CHECK_NULL_AND_PENDING_EXCEPTION(xc_trace_cb_method, err); return; err: + xc_trace_fast_cb_method = NULL; xc_trace_cb_method = NULL; } @@ -424,6 +456,7 @@ int xc_trace_init(JNIEnv *env, //is Android Lollipop (5.x)? xc_trace_is_lollipop = ((21 == xc_common_api_level || 22 == xc_common_api_level) ? 1 : 0); + xc_trace_dump_status = XC_TRACE_DUMP_NOT_START; xc_trace_rethrow = rethrow; xc_trace_logcat_system_lines = logcat_system_lines; xc_trace_logcat_events_lines = logcat_events_lines; diff --git a/src/native/libxcrash/jni/xc_trace.h b/xcrash_lib/src/main/cpp/xcrash/xc_trace.h similarity index 86% rename from src/native/libxcrash/jni/xc_trace.h rename to xcrash_lib/src/main/cpp/xcrash/xc_trace.h index 607dfd0..a0ec2fd 100644 --- a/src/native/libxcrash/jni/xc_trace.h +++ b/xcrash_lib/src/main/cpp/xcrash/xc_trace.h @@ -25,6 +25,7 @@ #define XC_TRACE_H 1 #include +#include #include #include @@ -32,6 +33,16 @@ extern "C" { #endif +typedef enum { + XC_TRACE_DUMP_NOT_START = 0, + XC_TRACE_DUMP_ON_GOING, + XC_TRACE_DUMP_ART_CRASH, + XC_TRACE_DUMP_END +} xc_trace_dump_status_t; + +extern xc_trace_dump_status_t xc_trace_dump_status; +extern sigjmp_buf jmpenv; + int xc_trace_init(JNIEnv *env, int rethrow, unsigned int logcat_system_lines, diff --git a/src/native/libxcrash/jni/xc_util.c b/xcrash_lib/src/main/cpp/xcrash/xc_util.c similarity index 100% rename from src/native/libxcrash/jni/xc_util.c rename to xcrash_lib/src/main/cpp/xcrash/xc_util.c diff --git a/src/native/libxcrash/jni/xc_util.h b/xcrash_lib/src/main/cpp/xcrash/xc_util.h similarity index 100% rename from src/native/libxcrash/jni/xc_util.h rename to xcrash_lib/src/main/cpp/xcrash/xc_util.h diff --git a/src/native/libxcrash_dumper/jni/xcd_arm_exidx.c b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_arm_exidx.c similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_arm_exidx.c rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_arm_exidx.c diff --git a/src/native/libxcrash_dumper/jni/xcd_arm_exidx.h b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_arm_exidx.h similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_arm_exidx.h rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_arm_exidx.h diff --git a/src/native/libxcrash_dumper/jni/xcd_core.c b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_core.c similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_core.c rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_core.c diff --git a/src/native/libxcrash_dumper/jni/xcd_dwarf.c b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_dwarf.c similarity index 99% rename from src/native/libxcrash_dumper/jni/xcd_dwarf.c rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_dwarf.c index 24ecdaf..e7ff71b 100644 --- a/src/native/libxcrash_dumper/jni/xcd_dwarf.c +++ b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_dwarf.c @@ -102,6 +102,7 @@ struct xcd_dwarf xcd_dwarf_type_t type; pid_t pid; uintptr_t load_bias; + uintptr_t hdr_load_bias; //for .eh_frame_hdr xcd_dwarf_cie_tree_t cie_cache; xcd_memory_t *memory; @@ -911,12 +912,14 @@ static int xcd_dwarf_get_fde_offset_from_pc(xcd_dwarf_t *self, uintptr_t pc, siz { int r; uint64_t v64; - int is_rel_encoded = ((self->eh_frame_hdr_table_encoding & 0x70) <= DW_EH_PE_funcrel ? 1 : 0); size_t first = 0; size_t last = self->eh_frame_hdr_fde_count; size_t cur; uintptr_t cur_pc; + int is_rel_encoded = ((self->eh_frame_hdr_table_encoding & 0x70) <= DW_EH_PE_funcrel && + (self->eh_frame_hdr_table_encoding & 0x70) > 0) ? 1 : 0; + while(first < last) { cur = (first + last) / 2; @@ -926,7 +929,7 @@ static int xcd_dwarf_get_fde_offset_from_pc(xcd_dwarf_t *self, uintptr_t pc, siz self->memory_pc_offset = 0; if(0 != (r = xcd_dwarf_read_encoded(self, &v64, self->eh_frame_hdr_table_encoding))) return r; cur_pc = (uintptr_t)v64; - if(is_rel_encoded) cur_pc += self->load_bias; + if(is_rel_encoded) cur_pc += self->hdr_load_bias; if(pc == cur_pc) { @@ -1659,7 +1662,7 @@ static int xcd_dwarf_init_eh_frame_hdr(xcd_dwarf_t *self) return 0; } -int xcd_dwarf_create(xcd_dwarf_t **self, xcd_memory_t *memory, pid_t pid, uintptr_t load_bias, +int xcd_dwarf_create(xcd_dwarf_t **self, xcd_memory_t *memory, pid_t pid, uintptr_t load_bias, uintptr_t hdr_load_bias, size_t offset, size_t size, xcd_dwarf_type_t type) { int r = 0; @@ -1668,6 +1671,7 @@ int xcd_dwarf_create(xcd_dwarf_t **self, xcd_memory_t *memory, pid_t pid, uintpt (*self)->type = type; (*self)->pid = pid; (*self)->load_bias = load_bias; + (*self)->hdr_load_bias = hdr_load_bias; RB_INIT(&((*self)->cie_cache)); (*self)->memory = memory; (*self)->memory_cur_offset = offset; diff --git a/src/native/libxcrash_dumper/jni/xcd_dwarf.h b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_dwarf.h similarity index 96% rename from src/native/libxcrash_dumper/jni/xcd_dwarf.h rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_dwarf.h index 864c314..e27aa0c 100644 --- a/src/native/libxcrash_dumper/jni/xcd_dwarf.h +++ b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_dwarf.h @@ -42,7 +42,7 @@ typedef enum typedef struct xcd_dwarf xcd_dwarf_t; -int xcd_dwarf_create(xcd_dwarf_t **self, xcd_memory_t *memory, pid_t pid, uintptr_t load_bias, +int xcd_dwarf_create(xcd_dwarf_t **self, xcd_memory_t *memory, pid_t pid, uintptr_t load_bias, uintptr_t hdr_load_bias, size_t offset, size_t size, xcd_dwarf_type_t type); int xcd_dwarf_step(xcd_dwarf_t *self, xcd_regs_t *regs, uintptr_t pc, int *finished); diff --git a/src/native/libxcrash_dumper/jni/xcd_elf.c b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_elf.c similarity index 94% rename from src/native/libxcrash_dumper/jni/xcd_elf.c rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_elf.c index 812519a..be49348 100644 --- a/src/native/libxcrash_dumper/jni/xcd_elf.c +++ b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_elf.c @@ -111,14 +111,17 @@ int xcd_elf_step(xcd_elf_t *self, uintptr_t rel_pc, uintptr_t step_pc, xcd_regs_ *sigreturn = 0; //try sigreturn - if(0 == xcd_regs_try_step_sigreturn(regs, rel_pc, self->memory, self->pid)) + if(rel_pc >= self->load_bias) { - *finished = 0; - *sigreturn = 1; + if(0 == xcd_regs_try_step_sigreturn(regs, rel_pc - self->load_bias, self->memory, self->pid)) + { + *finished = 0; + *sigreturn = 1; #if XCD_ELF_DEBUG - XCD_LOG_DEBUG("ELF: step by sigreturn OK, rel_pc=%"PRIxPTR", finished=0", rel_pc); + XCD_LOG_DEBUG("ELF: step by sigreturn OK, rel_pc=%"PRIxPTR", finished=0", rel_pc); #endif - return 0; + return 0; + } } //try DWARF (.debug_frame and .eh_frame) diff --git a/src/native/libxcrash_dumper/jni/xcd_elf.h b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_elf.h similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_elf.h rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_elf.h diff --git a/src/native/libxcrash_dumper/jni/xcd_elf_interface.c b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_elf_interface.c similarity index 94% rename from src/native/libxcrash_dumper/jni/xcd_elf_interface.c rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_elf_interface.c index 6ef4fd5..4885d95 100644 --- a/src/native/libxcrash_dumper/jni/xcd_elf_interface.c +++ b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_elf_interface.c @@ -85,9 +85,6 @@ struct xcd_elf_interface uintptr_t load_bias; int is_gnu; - //PT_LOAD(s) in program headers - xcd_elf_load_queue_t loads; - //symbols (.dynsym with .dynstr, .symtab with .strtab) xcd_elf_symbols_queue_t symbolsq; @@ -101,8 +98,10 @@ struct xcd_elf_interface //.eh_frame with option .eh_frame_hdr size_t eh_frame_offset; size_t eh_frame_size; + uintptr_t eh_frame_load_bias; size_t eh_frame_hdr_offset; size_t eh_frame_hdr_size; + uintptr_t eh_frame_hdr_load_bias; xcd_dwarf_t *dwarf_eh_frame; xcd_dwarf_type_t dwarf_eh_frame_type; @@ -167,10 +166,10 @@ static int xcd_elf_interface_check_valid(ElfW(Ehdr) *ehdr) static int xcd_elf_interface_read_program_headers(xcd_elf_interface_t *self, ElfW(Ehdr) *ehdr, uintptr_t *load_bias) { - size_t i; - ElfW(Phdr) phdr; - xcd_elf_load_t *load, *load_tmp; - int r; + size_t i; + ElfW(Phdr) phdr; + int try_save_load_bias = 0; + int r; for(i = 0; i < ehdr->e_phnum * ehdr->e_phentsize; i += ehdr->e_phentsize) { @@ -186,36 +185,26 @@ static int xcd_elf_interface_read_program_headers(xcd_elf_interface_t *self, Elf { if(0 == (phdr.p_flags & PF_X)) continue; - //save load bias - if(0 == phdr.p_offset) + if(!try_save_load_bias && phdr.p_vaddr > phdr.p_offset) { - self->load_bias = phdr.p_vaddr; - + self->load_bias = phdr.p_vaddr - phdr.p_offset; if(NULL != load_bias) *load_bias = self->load_bias; } - - if(NULL == (load = malloc(sizeof(xcd_elf_load_t)))) - { - r = XCC_ERRNO_NOMEM; - goto err; - } - load->vaddr = phdr.p_vaddr; - load->offset = phdr.p_offset; - load->size = phdr.p_memsz; - TAILQ_INSERT_TAIL(&(self->loads), load, link); + try_save_load_bias = 1; break; } case PT_GNU_EH_FRAME: self->eh_frame_hdr_offset = phdr.p_offset; - self->eh_frame_hdr_size = phdr.p_memsz; + self->eh_frame_hdr_size = phdr.p_memsz; + self->eh_frame_hdr_load_bias = phdr.p_vaddr - phdr.p_offset; break; case PT_ARM_EXIDX: self->arm_exidx_offset = phdr.p_offset; - self->arm_exidx_size = phdr.p_memsz; + self->arm_exidx_size = phdr.p_memsz; break; case PT_DYNAMIC: self->dynamic_offset = phdr.p_offset; - self->dynamic_size = phdr.p_memsz; + self->dynamic_size = phdr.p_memsz; break; default: break; @@ -224,11 +213,6 @@ static int xcd_elf_interface_read_program_headers(xcd_elf_interface_t *self, Elf return 0; err: - TAILQ_FOREACH_SAFE(load, &(self->loads), link, load_tmp) - { - TAILQ_REMOVE(&(self->loads), load, link); - free(load); - } return r; } @@ -331,11 +315,13 @@ static int xcd_elf_interface_read_section_headers(xcd_elf_interface_t *self, Elf { self->eh_frame_offset = shdr.sh_offset; self->eh_frame_size = shdr.sh_size; + self->eh_frame_load_bias = shdr.sh_addr - shdr.sh_offset; } - else if(0 == strcmp(name, ".eh_frame_hdr")) + else if(0 == strcmp(name, ".eh_frame_hdr") && 0 == self->eh_frame_hdr_offset) { self->eh_frame_hdr_offset = shdr.sh_offset; self->eh_frame_hdr_size = shdr.sh_size; + self->eh_frame_hdr_load_bias = shdr.sh_addr - shdr.sh_offset; } else if(0 == strcmp(name, ".gnu_debugdata")) { @@ -380,7 +366,6 @@ int xcd_elf_interface_create(xcd_elf_interface_t **self, pid_t pid, xcd_memory_t if(NULL == (*self = calloc(1, sizeof(xcd_elf_interface_t)))) return XCC_ERRNO_NOMEM; (*self)->pid = pid; (*self)->memory = memory; - TAILQ_INIT(&((*self)->loads)); TAILQ_INIT(&((*self)->symbolsq)); TAILQ_INIT(&((*self)->strtabq)); @@ -398,7 +383,8 @@ int xcd_elf_interface_create(xcd_elf_interface_t **self, pid_t pid, xcd_memory_t //dwarf from .eh_frame with .eh_frame_hdr if(0 != (*self)->eh_frame_hdr_offset && 0 != (*self)->eh_frame_hdr_size) { - xcd_dwarf_create(&((*self)->dwarf_eh_frame), memory, pid, (*self)->load_bias, + xcd_dwarf_create(&((*self)->dwarf_eh_frame), memory, pid, + (*self)->eh_frame_load_bias, (*self)->eh_frame_hdr_load_bias, (*self)->eh_frame_hdr_offset, (*self)->eh_frame_hdr_size, XCD_DWARF_TYPE_EH_FRAME_HDR); (*self)->dwarf_eh_frame_type = XCD_DWARF_TYPE_EH_FRAME_HDR; @@ -407,7 +393,8 @@ int xcd_elf_interface_create(xcd_elf_interface_t **self, pid_t pid, xcd_memory_t //dwarf from .eh_frame without .eh_frame_hdr if(NULL == (*self)->dwarf_eh_frame && 0 != (*self)->eh_frame_offset && 0 != (*self)->eh_frame_size) { - xcd_dwarf_create(&((*self)->dwarf_eh_frame), memory, pid, (*self)->load_bias, + xcd_dwarf_create(&((*self)->dwarf_eh_frame), memory, pid, + (*self)->eh_frame_load_bias, 0, (*self)->eh_frame_offset, (*self)->eh_frame_size, XCD_DWARF_TYPE_EH_FRAME); (*self)->dwarf_eh_frame_type = XCD_DWARF_TYPE_EH_FRAME; @@ -415,7 +402,8 @@ int xcd_elf_interface_create(xcd_elf_interface_t **self, pid_t pid, xcd_memory_t //dwarf from .debug_frame if(0 != (*self)->debug_frame_offset && 0 != (*self)->debug_frame_size) - xcd_dwarf_create(&((*self)->dwarf_debug_frame), memory, pid, (*self)->load_bias, + xcd_dwarf_create(&((*self)->dwarf_debug_frame), memory, pid, + (*self)->load_bias, 0, (*self)->debug_frame_offset, (*self)->debug_frame_size, XCD_DWARF_TYPE_DEBUG_FRAME); diff --git a/src/native/libxcrash_dumper/jni/xcd_elf_interface.h b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_elf_interface.h similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_elf_interface.h rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_elf_interface.h diff --git a/src/native/libxcrash_dumper/jni/xcd_frames.c b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_frames.c similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_frames.c rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_frames.c diff --git a/src/native/libxcrash_dumper/jni/xcd_frames.h b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_frames.h similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_frames.h rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_frames.h diff --git a/src/native/libxcrash_dumper/jni/xcd_log.h b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_log.h similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_log.h rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_log.h diff --git a/src/native/libxcrash_dumper/jni/xcd_map.c b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_map.c similarity index 90% rename from src/native/libxcrash_dumper/jni/xcd_map.c rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_map.c index 3e0f9e1..c546650 100644 --- a/src/native/libxcrash_dumper/jni/xcd_map.c +++ b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_map.c @@ -88,18 +88,18 @@ xcd_elf_t *xcd_map_get_elf(xcd_map_t *self, pid_t pid, void *maps_obj) return self->elf; } -uintptr_t xcd_map_get_rel_pc(xcd_map_t *self, uintptr_t pc, pid_t pid, void *maps_obj) +uintptr_t xcd_map_get_rel_pc(xcd_map_t *self, uintptr_t abs_pc, pid_t pid, void *maps_obj) { xcd_elf_t *elf = xcd_map_get_elf(self, pid, maps_obj); uintptr_t load_bias = (NULL == elf ? 0 : xcd_elf_get_load_bias(elf)); - return pc - self->start + load_bias + self->elf_offset; + return abs_pc - (self->start - self->elf_offset - load_bias); } -uintptr_t xcd_map_get_abs_pc(xcd_map_t *self, uintptr_t pc, pid_t pid, void *maps_obj) +uintptr_t xcd_map_get_abs_pc(xcd_map_t *self, uintptr_t rel_pc, pid_t pid, void *maps_obj) { xcd_elf_t *elf = xcd_map_get_elf(self, pid, maps_obj); uintptr_t load_bias = (NULL == elf ? 0 : xcd_elf_get_load_bias(elf)); - return self->start + pc - load_bias - self->elf_offset; + return (self->start - self->elf_offset - load_bias) + rel_pc; } diff --git a/src/native/libxcrash_dumper/jni/xcd_map.h b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_map.h similarity index 91% rename from src/native/libxcrash_dumper/jni/xcd_map.h rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_map.h index 5be02c7..a8c2e9d 100644 --- a/src/native/libxcrash_dumper/jni/xcd_map.h +++ b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_map.h @@ -58,8 +58,8 @@ int xcd_map_init(xcd_map_t *self, uintptr_t start, uintptr_t end, size_t offset, void xcd_map_uninit(xcd_map_t *self); xcd_elf_t *xcd_map_get_elf(xcd_map_t *self, pid_t pid, void *maps_obj); -uintptr_t xcd_map_get_rel_pc(xcd_map_t *self, uintptr_t pc, pid_t pid, void *maps_obj); -uintptr_t xcd_map_get_abs_pc(xcd_map_t *self, uintptr_t pc, pid_t pid, void *maps_obj); +uintptr_t xcd_map_get_rel_pc(xcd_map_t *self, uintptr_t abs_pc, pid_t pid, void *maps_obj); +uintptr_t xcd_map_get_abs_pc(xcd_map_t *self, uintptr_t rel_pc, pid_t pid, void *maps_obj); #ifdef __cplusplus } diff --git a/src/native/libxcrash_dumper/jni/xcd_maps.c b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_maps.c similarity index 95% rename from src/native/libxcrash_dumper/jni/xcd_maps.c rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_maps.c index ac68f51..20c01a3 100644 --- a/src/native/libxcrash_dumper/jni/xcd_maps.c +++ b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_maps.c @@ -200,7 +200,7 @@ int xcd_maps_record(xcd_maps_t *self, int log_fd) size_t width_offset = 0; uintptr_t load_bias = 0; char load_bias_buf[64] = "\0"; - char *name = ""; + char *name; char *prev_name = NULL; //get width of size and offset columns @@ -228,22 +228,17 @@ int xcd_maps_record(xcd_maps_t *self, int log_fd) TAILQ_FOREACH(mi, &(self->maps), link) { //get load_bias - if(NULL != mi->map.elf) - { - if(0 != (load_bias = xcd_elf_get_load_bias(mi->map.elf))) - snprintf(load_bias_buf, sizeof(load_bias_buf), " (load base 0x%"PRIxPTR")", load_bias); - } + if(NULL != mi->map.elf && 0 != (load_bias = xcd_elf_get_load_bias(mi->map.elf))) + snprintf(load_bias_buf, sizeof(load_bias_buf), " (load bias 0x%"PRIxPTR")", load_bias); else - { load_bias_buf[0] = '\0'; - } - //get name + //fix name and load_bias if(NULL != mi->map.name) { if(NULL == prev_name) name = mi->map.name; - else if(0 == strcmp(prev_name, mi->map.name)) + else if(0 == strcmp(prev_name, mi->map.name) && '\0' == load_bias_buf[0]) name = ">"; //same as prev line else name = mi->map.name; diff --git a/src/native/libxcrash_dumper/jni/xcd_maps.h b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_maps.h similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_maps.h rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_maps.h diff --git a/src/native/libxcrash_dumper/jni/xcd_md5.c b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_md5.c similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_md5.c rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_md5.c diff --git a/src/native/libxcrash_dumper/jni/xcd_md5.h b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_md5.h similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_md5.h rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_md5.h diff --git a/src/native/libxcrash_dumper/jni/xcd_memory.c b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_memory.c similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_memory.c rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_memory.c diff --git a/src/native/libxcrash_dumper/jni/xcd_memory.h b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_memory.h similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_memory.h rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_memory.h diff --git a/src/native/libxcrash_dumper/jni/xcd_memory_buf.c b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_memory_buf.c similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_memory_buf.c rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_memory_buf.c diff --git a/src/native/libxcrash_dumper/jni/xcd_memory_buf.h b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_memory_buf.h similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_memory_buf.h rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_memory_buf.h diff --git a/src/native/libxcrash_dumper/jni/xcd_memory_file.c b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_memory_file.c similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_memory_file.c rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_memory_file.c diff --git a/src/native/libxcrash_dumper/jni/xcd_memory_file.h b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_memory_file.h similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_memory_file.h rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_memory_file.h diff --git a/src/native/libxcrash_dumper/jni/xcd_memory_remote.c b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_memory_remote.c similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_memory_remote.c rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_memory_remote.c diff --git a/src/native/libxcrash_dumper/jni/xcd_memory_remote.h b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_memory_remote.h similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_memory_remote.h rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_memory_remote.h diff --git a/src/native/libxcrash_dumper/jni/xcd_process.c b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_process.c similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_process.c rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_process.c diff --git a/src/native/libxcrash_dumper/jni/xcd_process.h b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_process.h similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_process.h rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_process.h diff --git a/src/native/libxcrash_dumper/jni/xcd_regs.h b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_regs.h similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_regs.h rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_regs.h diff --git a/src/native/libxcrash_dumper/jni/xcd_regs_arm.c b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_regs_arm.c similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_regs_arm.c rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_regs_arm.c diff --git a/src/native/libxcrash_dumper/jni/xcd_regs_arm64.c b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_regs_arm64.c similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_regs_arm64.c rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_regs_arm64.c diff --git a/src/native/libxcrash_dumper/jni/xcd_regs_x86.c b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_regs_x86.c similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_regs_x86.c rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_regs_x86.c diff --git a/src/native/libxcrash_dumper/jni/xcd_regs_x86_64.c b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_regs_x86_64.c similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_regs_x86_64.c rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_regs_x86_64.c diff --git a/src/native/libxcrash_dumper/jni/xcd_sys.c b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_sys.c similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_sys.c rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_sys.c diff --git a/src/native/libxcrash_dumper/jni/xcd_sys.h b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_sys.h similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_sys.h rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_sys.h diff --git a/src/native/libxcrash_dumper/jni/xcd_thread.c b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_thread.c similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_thread.c rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_thread.c diff --git a/src/native/libxcrash_dumper/jni/xcd_thread.h b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_thread.h similarity index 100% rename from src/native/libxcrash_dumper/jni/xcd_thread.h rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_thread.h diff --git a/src/native/libxcrash_dumper/jni/xcd_util.c b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_util.c similarity index 60% rename from src/native/libxcrash_dumper/jni/xcd_util.c rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_util.c index 68df636..8eb2909 100644 --- a/src/native/libxcrash_dumper/jni/xcd_util.c +++ b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_util.c @@ -45,61 +45,92 @@ #include "XzCrc64.h" #pragma clang diagnostic pop -int xcd_util_ptrace_read_long(pid_t pid, uintptr_t addr, long *value) +extern __attribute((weak)) ssize_t process_vm_readv(pid_t, const struct iovec *, unsigned long, const struct iovec *, unsigned long, unsigned long); + +static size_t xcd_util_process_vm_readv(pid_t pid, uintptr_t remote_addr, void* dst, size_t dst_len) { - // ptrace() returns -1 and sets errno when the operation fails. - // To disambiguate -1 from a valid result, we clear errno beforehand. - errno = 0; - *value = ptrace(PTRACE_PEEKTEXT, pid, (void *)addr, NULL); - if(-1 == *value && 0 != errno) + size_t page_size = (size_t)sysconf(_SC_PAGE_SIZE); + struct iovec src_iovs[64]; + uintptr_t cur_remote_addr = remote_addr; + size_t total_read = 0; + + while (dst_len > 0) { - XCD_LOG_ERROR("UTIL: ptrace error, addr:%"PRIxPTR", errno:%d\n", addr, errno); - return errno; + // the destination + struct iovec dst_iov = {.iov_base = &((uint8_t *)dst)[total_read], .iov_len = dst_len}; + + // the source + size_t iovecs_used = 0; + while (dst_len > 0) + { + // fill iov_base + src_iovs[iovecs_used].iov_base = (void *)cur_remote_addr; + + // fill iov_len (one page at a time, page boundaries aligned) + uintptr_t misalignment = cur_remote_addr & (page_size - 1); + size_t iov_len = page_size - misalignment; + src_iovs[iovecs_used].iov_len = (iov_len > dst_len ? dst_len : iov_len); + + if (__builtin_add_overflow(cur_remote_addr, iov_len, &cur_remote_addr)) return total_read; + dst_len -= iov_len; + + if(64 == ++iovecs_used) break; + } + + // read from source to destination + ssize_t rc; + if(NULL != process_vm_readv) + rc = process_vm_readv(pid, &dst_iov, 1, src_iovs, iovecs_used, 0); + else + rc = syscall(__NR_process_vm_readv, pid, &dst_iov, 1, src_iovs, iovecs_used, 0); + if(-1 == rc) return total_read; + + total_read += (size_t)rc; } - - return 0; + + return total_read; } -size_t xcd_util_ptrace_read(pid_t pid, uintptr_t addr, void *dst, size_t bytes) +static size_t xcd_util_original_ptrace(pid_t pid, uintptr_t remote_addr, void *dst, size_t dst_len) { // Make sure that there is no overflow. uintptr_t max_size; - if(__builtin_add_overflow(addr, bytes, &max_size)) return 0; + if(__builtin_add_overflow(remote_addr, dst_len, &max_size)) return 0; size_t bytes_read = 0; long data; - size_t align_bytes = addr & (sizeof(long) - 1); + size_t align_bytes = remote_addr & (sizeof(long) - 1); if(align_bytes != 0) { - if(0 != xcd_util_ptrace_read_long(pid, addr & ~(sizeof(long) - 1), &data)) return 0; + if(0 != xcd_util_ptrace_read_long(pid, remote_addr & ~(sizeof(long) - 1), &data)) return 0; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu-statement-expression" - size_t copy_bytes = XCC_UTIL_MIN(sizeof(long) - align_bytes, bytes); + size_t copy_bytes = XCC_UTIL_MIN(sizeof(long) - align_bytes, dst_len); #pragma clang diagnostic pop memcpy(dst, (uint8_t *)(&data) + align_bytes, copy_bytes); - addr += copy_bytes; + remote_addr += copy_bytes; dst = (void *)((uintptr_t)dst + copy_bytes); - bytes -= copy_bytes; + dst_len -= copy_bytes; bytes_read += copy_bytes; } size_t i; - for(i = 0; i < bytes / sizeof(long); i++) + for(i = 0; i < dst_len / sizeof(long); i++) { - if(0 != xcd_util_ptrace_read_long(pid, addr, &data)) return bytes_read; + if(0 != xcd_util_ptrace_read_long(pid, remote_addr, &data)) return bytes_read; memcpy(dst, &data, sizeof(long)); dst = (void *)((uintptr_t)dst + sizeof(long)); - addr += sizeof(long); + remote_addr += sizeof(long); bytes_read += sizeof(long); } - size_t left_over = bytes & (sizeof(long) - 1); + size_t left_over = dst_len & (sizeof(long) - 1); if(left_over) { - if(0 != xcd_util_ptrace_read_long(pid, addr, &data)) return bytes_read; + if(0 != xcd_util_ptrace_read_long(pid, remote_addr, &data)) return bytes_read; memcpy(dst, &data, left_over); bytes_read += left_over; @@ -108,12 +139,54 @@ size_t xcd_util_ptrace_read(pid_t pid, uintptr_t addr, void *dst, size_t bytes) return bytes_read; } +size_t xcd_util_ptrace_read(pid_t pid, uintptr_t remote_addr, void *dst, size_t dst_len) +{ + static size_t (*ptrace_read)(pid_t, uintptr_t, void *, size_t) = NULL; + + if(NULL != ptrace_read) + { + return ptrace_read(pid, remote_addr, dst, dst_len); + } + else + { + size_t bytes = xcd_util_process_vm_readv(pid, remote_addr, dst, dst_len); + if(bytes > 0) + { + __atomic_store_n(&ptrace_read, xcd_util_process_vm_readv, __ATOMIC_SEQ_CST); + return bytes; + } + bytes = xcd_util_original_ptrace(pid, remote_addr, dst, dst_len); + if(bytes > 0) + { + __atomic_store_n(&ptrace_read, xcd_util_original_ptrace, __ATOMIC_SEQ_CST); + return bytes; + } + return 0; + } +} + int xcd_util_ptrace_read_fully(pid_t pid, uintptr_t addr, void *dst, size_t bytes) { size_t rc = xcd_util_ptrace_read(pid, addr, dst, bytes); return rc == bytes ? 0 : XCC_ERRNO_MISSING; } + +int xcd_util_ptrace_read_long(pid_t pid, uintptr_t addr, long *value) +{ + // ptrace() returns -1 and sets errno when the operation fails. + // To disambiguate -1 from a valid result, we clear errno beforehand. + errno = 0; + *value = ptrace(PTRACE_PEEKTEXT, pid, (void *)addr, NULL); + if(-1 == *value && 0 != errno) + { + //XCD_LOG_INFO("UTIL: ptrace error, addr:%"PRIxPTR", errno:%d\n", addr, errno); + return errno; + } + + return 0; +} + static void* xcd_util_xz_alloc(ISzAllocPtr p, size_t size) { (void)p; diff --git a/src/native/libxcrash_dumper/jni/xcd_util.h b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_util.h similarity index 81% rename from src/native/libxcrash_dumper/jni/xcd_util.h rename to xcrash_lib/src/main/cpp/xcrash_dumper/xcd_util.h index 0cd3f9e..a12a10c 100644 --- a/src/native/libxcrash_dumper/jni/xcd_util.h +++ b/xcrash_lib/src/main/cpp/xcrash_dumper/xcd_util.h @@ -27,32 +27,14 @@ #include #include #include -#include #ifdef __cplusplus extern "C" { #endif -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wpadded" -typedef struct -{ - int api_level; - char *os_version; - char *abi_list; - char *manufacturer; - char *brand; - char *model; - char *build_fingerprint; - char *revision; -} xcd_util_build_prop_t; -#pragma clang diagnostic pop - -void xcd_util_load_build_prop(xcd_util_build_prop_t *prop); - -int xcd_util_ptrace_read_long(pid_t pid, uintptr_t addr, long *value); size_t xcd_util_ptrace_read(pid_t pid, uintptr_t addr, void *dst, size_t bytes); int xcd_util_ptrace_read_fully(pid_t pid, uintptr_t addr, void *dst, size_t bytes); +int xcd_util_ptrace_read_long(pid_t pid, uintptr_t addr, long *value); int xcd_util_xz_decompress(uint8_t* src, size_t src_size, uint8_t** dst, size_t* dst_size); diff --git a/src/java/xcrash/xcrash_lib/src/main/java/xcrash/ActivityMonitor.java b/xcrash_lib/src/main/java/xcrash/ActivityMonitor.java similarity index 100% rename from src/java/xcrash/xcrash_lib/src/main/java/xcrash/ActivityMonitor.java rename to xcrash_lib/src/main/java/xcrash/ActivityMonitor.java diff --git a/src/java/xcrash/xcrash_lib/src/main/java/xcrash/AnrHandler.java b/xcrash_lib/src/main/java/xcrash/AnrHandler.java similarity index 97% rename from src/java/xcrash/xcrash_lib/src/main/java/xcrash/AnrHandler.java rename to xcrash_lib/src/main/java/xcrash/AnrHandler.java index 4e03c5c..fbb3850 100644 --- a/src/java/xcrash/xcrash_lib/src/main/java/xcrash/AnrHandler.java +++ b/xcrash_lib/src/main/java/xcrash/AnrHandler.java @@ -62,6 +62,7 @@ class AnrHandler { private boolean dumpFds; private boolean dumpNetworkInfo; private ICrashCallback callback; + private ICrashCallback anrFastCallback; private long lastTime = 0; private FileObserver fileObserver = null; @@ -75,7 +76,7 @@ static AnrHandler getInstance() { @SuppressWarnings("deprecation") void initialize(Context ctx, int pid, String processName, String appId, String appVersion, String logDir, boolean checkProcessState, int logcatSystemLines, int logcatEventsLines, int logcatMainLines, - boolean dumpFds, boolean dumpNetworkInfo, ICrashCallback callback) { + boolean dumpFds, boolean dumpNetworkInfo, ICrashCallback callback, ICrashCallback anrFastCallback) { //check API level if (Build.VERSION.SDK_INT >= 21) { @@ -95,6 +96,7 @@ void initialize(Context ctx, int pid, String processName, String appId, String a this.dumpFds = dumpFds; this.dumpNetworkInfo = dumpNetworkInfo; this.callback = callback; + this.anrFastCallback = anrFastCallback; fileObserver = new FileObserver("/data/anr/", CLOSE_WRITE) { public void onEvent(int event, String path) { @@ -139,6 +141,13 @@ private void handleAnr(String filepath) { return; } + if(anrFastCallback != null) { + try { + anrFastCallback.onCrash(null, null); + } catch (Exception ignored) { + } + } + //check process error state if (this.checkProcessState) { if (!Util.checkProcessAnrState(this.ctx, anrTimeoutMs)) { diff --git a/src/java/xcrash/xcrash_lib/src/main/java/xcrash/DefaultLogger.java b/xcrash_lib/src/main/java/xcrash/DefaultLogger.java similarity index 100% rename from src/java/xcrash/xcrash_lib/src/main/java/xcrash/DefaultLogger.java rename to xcrash_lib/src/main/java/xcrash/DefaultLogger.java diff --git a/src/java/xcrash/xcrash_lib/src/main/java/xcrash/Errno.java b/xcrash_lib/src/main/java/xcrash/Errno.java similarity index 100% rename from src/java/xcrash/xcrash_lib/src/main/java/xcrash/Errno.java rename to xcrash_lib/src/main/java/xcrash/Errno.java diff --git a/src/java/xcrash/xcrash_lib/src/main/java/xcrash/FileManager.java b/xcrash_lib/src/main/java/xcrash/FileManager.java similarity index 100% rename from src/java/xcrash/xcrash_lib/src/main/java/xcrash/FileManager.java rename to xcrash_lib/src/main/java/xcrash/FileManager.java diff --git a/src/java/xcrash/xcrash_lib/src/main/java/xcrash/ICrashCallback.java b/xcrash_lib/src/main/java/xcrash/ICrashCallback.java similarity index 100% rename from src/java/xcrash/xcrash_lib/src/main/java/xcrash/ICrashCallback.java rename to xcrash_lib/src/main/java/xcrash/ICrashCallback.java diff --git a/src/java/xcrash/xcrash_lib/src/main/java/xcrash/ILibLoader.java b/xcrash_lib/src/main/java/xcrash/ILibLoader.java similarity index 100% rename from src/java/xcrash/xcrash_lib/src/main/java/xcrash/ILibLoader.java rename to xcrash_lib/src/main/java/xcrash/ILibLoader.java diff --git a/src/java/xcrash/xcrash_lib/src/main/java/xcrash/ILogger.java b/xcrash_lib/src/main/java/xcrash/ILogger.java similarity index 100% rename from src/java/xcrash/xcrash_lib/src/main/java/xcrash/ILogger.java rename to xcrash_lib/src/main/java/xcrash/ILogger.java diff --git a/src/java/xcrash/xcrash_lib/src/main/java/xcrash/JavaCrashHandler.java b/xcrash_lib/src/main/java/xcrash/JavaCrashHandler.java similarity index 83% rename from src/java/xcrash/xcrash_lib/src/main/java/xcrash/JavaCrashHandler.java rename to xcrash_lib/src/main/java/xcrash/JavaCrashHandler.java index d74b373..a2db3f0 100644 --- a/src/java/xcrash/xcrash_lib/src/main/java/xcrash/JavaCrashHandler.java +++ b/xcrash_lib/src/main/java/xcrash/JavaCrashHandler.java @@ -27,8 +27,11 @@ import java.io.RandomAccessFile; import java.io.StringWriter; import java.lang.Thread.UncaughtExceptionHandler; +import java.text.DateFormat; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.regex.Pattern; @@ -203,6 +206,58 @@ private void handleException(Thread thread, Throwable throwable) { } } + private String getLibInfo(List libPathList) { + StringBuilder sb = new StringBuilder(); + for (String libPath : libPathList) { + File libFile = new File(libPath); + if (libFile.exists() && libFile.isFile()) { + String md5 = Util.getFileMD5(libFile); + + DateFormat timeFormatter = new SimpleDateFormat(Util.timeFormatterStr, Locale.US); + Date lastTime = new Date(libFile.lastModified()); + + sb.append(" ").append(libPath).append("(BuildId: unknown. FileSize: ").append(libFile.length()).append(". LastModified: ") + .append(timeFormatter.format(lastTime)).append(". MD5: ").append(md5).append(")\n"); + } else { + sb.append(" ").append(libPath).append(" (Not found)\n"); + } + } + + String libInfo = sb.toString(); + return libInfo; + } + + private String getBuildId(String stktrace) { + String buildId = ""; + List libPathList = new ArrayList(); + if (stktrace.contains("UnsatisfiedLinkError")) { + String libInfo = null; + String[] tempLibPathStr; + tempLibPathStr = stktrace.split("\""); // " is the delimiter + for (String libPathStr : tempLibPathStr) { + if (libPathStr.isEmpty() || !libPathStr.endsWith(".so")) continue; + libPathList.add(libPathStr); + + String libName = libPathStr.substring(libPathStr.lastIndexOf('/') + 1); + + libPathList.add(XCrash.nativeLibDir + "/" + libName); + libPathList.add("/vendor/lib/" + libName); + libPathList.add("/vendor/lib64/" + libName); + libPathList.add("/system/lib/" + libName); + libPathList.add("/system/lib64/" + libName); + + libInfo = getLibInfo(libPathList); + } + + buildId = "build id:" + + "\n" + + libInfo + + "\n"; + } + + return buildId; + } + private String getEmergency(Date crashTime, Thread thread, Throwable throwable) { //stack stace @@ -216,7 +271,8 @@ private String getEmergency(Date crashTime, Thread thread, Throwable throwable) + "\n" + "java stacktrace:\n" + stacktrace - + "\n"; + + "\n" + + getBuildId(stacktrace); } private String getOtherThreadsInfo(Thread crashedThread) { diff --git a/src/java/xcrash/xcrash_lib/src/main/java/xcrash/NativeHandler.java b/xcrash_lib/src/main/java/xcrash/NativeHandler.java similarity index 91% rename from src/java/xcrash/xcrash_lib/src/main/java/xcrash/NativeHandler.java rename to xcrash_lib/src/main/java/xcrash/NativeHandler.java index 463e1dc..f41c68a 100644 --- a/src/java/xcrash/xcrash_lib/src/main/java/xcrash/NativeHandler.java +++ b/xcrash_lib/src/main/java/xcrash/NativeHandler.java @@ -26,6 +26,7 @@ import android.content.Context; import android.os.Build; import android.text.TextUtils; +import android.util.Log; import java.io.File; import java.util.Map; @@ -33,8 +34,9 @@ @SuppressLint("StaticFieldLeak") class NativeHandler { + private static final String TAG = "xcrash"; private static final NativeHandler instance = new NativeHandler(); - private long anrTimeoutMs = 15 * 1000; + private long anrTimeoutMs = 25 * 1000; private Context ctx; private boolean crashRethrow; @@ -42,6 +44,7 @@ class NativeHandler { private boolean anrEnable; private boolean anrCheckProcessState; private ICrashCallback anrCallback; + private ICrashCallback anrFastCallback; private boolean initNativeLibOk = false; @@ -78,7 +81,8 @@ int initialize(Context ctx, int anrLogcatMainLines, boolean anrDumpFds, boolean anrDumpNetworkInfo, - ICrashCallback anrCallback) { + ICrashCallback anrCallback, + ICrashCallback anrFastCallback) { //load lib if (libLoader == null) { try { @@ -102,7 +106,8 @@ int initialize(Context ctx, this.anrEnable = anrEnable; this.anrCheckProcessState = anrCheckProcessState; this.anrCallback = anrCallback; - this.anrTimeoutMs = anrRethrow ? 15 * 1000 : 30 * 1000; //setting rethrow to "false" is NOT recommended + this.anrFastCallback = anrFastCallback; + this.anrTimeoutMs = anrRethrow ? 25 * 1000 : 45 * 1000; //setting rethrow to "false" is NOT recommended //init native lib try { @@ -112,7 +117,7 @@ int initialize(Context ctx, Util.getAbiList(), Build.MANUFACTURER, Build.BRAND, - Build.MODEL, + Util.getMobileModel(), Build.FINGERPRINT, appId, appVersion, @@ -214,9 +219,25 @@ private static void crashCallback(String logPath, String emergency, boolean dump } } + // do NOT obfuscate this method + @SuppressWarnings("unused") + private static void traceCallbackBeforeDump() { + Log.i(TAG, "trace fast callback time: " + System.currentTimeMillis()); + ICrashCallback anrFastCallback = NativeHandler.getInstance().anrFastCallback; + if (anrFastCallback != null) { + try { + anrFastCallback.onCrash(null, null); + } catch (Exception e) { + XCrash.getLogger().w(Util.TAG, "NativeHandler ANR callback.onCrash failed", e); + } + } + } + // do NOT obfuscate this method @SuppressWarnings("unused") private static void traceCallback(String logPath, String emergency) { + Log.i(TAG, "trace slow callback time: " + System.currentTimeMillis()); + if (TextUtils.isEmpty(logPath)) { return; } diff --git a/src/java/xcrash/xcrash_lib/src/main/java/xcrash/TombstoneManager.java b/xcrash_lib/src/main/java/xcrash/TombstoneManager.java similarity index 100% rename from src/java/xcrash/xcrash_lib/src/main/java/xcrash/TombstoneManager.java rename to xcrash_lib/src/main/java/xcrash/TombstoneManager.java diff --git a/src/java/xcrash/xcrash_lib/src/main/java/xcrash/TombstoneParser.java b/xcrash_lib/src/main/java/xcrash/TombstoneParser.java similarity index 99% rename from src/java/xcrash/xcrash_lib/src/main/java/xcrash/TombstoneParser.java rename to xcrash_lib/src/main/java/xcrash/TombstoneParser.java index bfb3375..1b122dc 100644 --- a/src/java/xcrash/xcrash_lib/src/main/java/xcrash/TombstoneParser.java +++ b/xcrash_lib/src/main/java/xcrash/TombstoneParser.java @@ -510,7 +510,7 @@ private static void addSystemInfo(Map map) { } if (TextUtils.isEmpty(map.get(keyModel))) { - map.put(keyModel, Build.MODEL); + map.put(keyModel, Util.getMobileModel()); } if (TextUtils.isEmpty(map.get(keyAbiList))) { diff --git a/src/java/xcrash/xcrash_lib/src/main/java/xcrash/Util.java b/xcrash_lib/src/main/java/xcrash/Util.java similarity index 67% rename from src/java/xcrash/xcrash_lib/src/main/java/xcrash/Util.java rename to xcrash_lib/src/main/java/xcrash/Util.java index 2303097..883ac0d 100644 --- a/src/java/xcrash/xcrash_lib/src/main/java/xcrash/Util.java +++ b/xcrash_lib/src/main/java/xcrash/Util.java @@ -26,14 +26,21 @@ import android.content.Context; import android.os.Build; import android.os.Debug; +import android.system.Os; import android.text.TextUtils; +import android.util.Log; import java.io.BufferedReader; import java.io.File; +import java.io.FileInputStream; import java.io.FileReader; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStreamReader; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.math.BigInteger; +import java.security.MessageDigest; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -70,20 +77,20 @@ private Util() { static String getProcessName(Context ctx, int pid) { //get from ActivityManager - try { - ActivityManager manager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE); - if (manager != null) { - List processInfoList = manager.getRunningAppProcesses(); - if (processInfoList != null) { - for (ActivityManager.RunningAppProcessInfo processInfo : processInfoList) { - if (processInfo.pid == pid && !TextUtils.isEmpty(processInfo.processName)) { - return processInfo.processName; //OK - } - } - } - } - } catch (Exception ignored) { - } +// try { +// ActivityManager manager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE); +// if (manager != null) { +// List processInfoList = manager.getRunningAppProcesses(); +// if (processInfoList != null) { +// for (ActivityManager.RunningAppProcessInfo processInfo : processInfoList) { +// if (processInfo.pid == pid && !TextUtils.isEmpty(processInfo.processName)) { +// return processInfo.processName; //OK +// } +// } +// } +// } +// } catch (Exception ignored) { +// } //get from /proc/PID/cmdline BufferedReader br = null; @@ -151,6 +158,34 @@ static String getAbiList() { } } + static String getFileMD5(File file) { + String s = null; + + if (!file.exists()) { + return null; + } + + FileInputStream in = null; + byte[] buffer = new byte[1024]; + int len; + + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + in = new FileInputStream(file); + while ((len = in.read(buffer, 0, 1024)) != -1) { + md.update(buffer, 0, len); + } + in.close(); + BigInteger bigInt = new BigInteger(1, md.digest()); + s = String.format("%032x", bigInt); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + + return s; + } + static String getAppVersion(Context ctx) { String appVersion = null; @@ -187,14 +222,14 @@ static String getProcessMemoryInfo() { sb.append(String.format(Locale.US, memInfoFmt2, "TOTAL:", mi.getMemoryStat("summary.total-pss"), "TOTAL SWAP:", mi.getMemoryStat("summary.total-swap"))); } else { sb.append(String.format(Locale.US, memInfoFmt, "Java Heap:", "~ " + mi.dalvikPrivateDirty)); - sb.append(String.format(Locale.US, memInfoFmt, "Native Heap:", String.valueOf(mi.nativePrivateDirty))); + sb.append(String.format(Locale.US, memInfoFmt, "Native Heap:", mi.nativePrivateDirty)); sb.append(String.format(Locale.US, memInfoFmt, "Private Other:", "~ " + mi.otherPrivateDirty)); if (Build.VERSION.SDK_INT >= 19) { - sb.append(String.format(Locale.US, memInfoFmt, "System:", String.valueOf(mi.getTotalPss() - mi.getTotalPrivateDirty() - mi.getTotalPrivateClean()))); + sb.append(String.format(Locale.US, memInfoFmt, "System:", (mi.getTotalPss() - mi.getTotalPrivateDirty() - mi.getTotalPrivateClean()))); } else { sb.append(String.format(Locale.US, memInfoFmt, "System:", "~ " + (mi.getTotalPss() - mi.getTotalPrivateDirty()))); } - sb.append(String.format(Locale.US, memInfoFmt, "TOTAL:", String.valueOf(mi.getTotalPss()))); + sb.append(String.format(Locale.US, memInfoFmt, "TOTAL:", mi.getTotalPss())); } } catch (Exception e) { XCrash.getLogger().i(Util.TAG, "Util getProcessMemoryInfo failed", e); @@ -264,11 +299,15 @@ static boolean checkProcessAnrState(Context ctx, long timeoutMs) { for (int i = 0; i < poll; i++) { List processErrorList = am.getProcessesInErrorState(); if (processErrorList != null) { + XCrash.getLogger().e(Util.TAG, "processErrorList is NOT null !!!!" + ", i = " + i); for (ActivityManager.ProcessErrorStateInfo errorStateInfo : processErrorList) { + XCrash.getLogger().e(Util.TAG, "errorStateInfo.pid = " + errorStateInfo.pid + ", my pid = " + pid + ", errorStateInfo.condition = " + errorStateInfo.condition); if (errorStateInfo.pid == pid && errorStateInfo.condition == ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING) { return true; } } + } else { + XCrash.getLogger().e(Util.TAG, "processErrorList is null !!!!" + " poll = " + poll + ", i = " + i); } try { @@ -296,7 +335,7 @@ static String getLogHeader(Date startTime, Date crashTime, String crashType, Str + "ABI list: '" + Util.getAbiList() + "'\n" + "Manufacturer: '" + Build.MANUFACTURER + "'\n" + "Brand: '" + Build.BRAND + "'\n" - + "Model: '" + Build.MODEL + "'\n" + + "Model: '" + Util.getMobileModel() + "'\n" + "Build fingerprint: '" + Build.FINGERPRINT + "'\n"; } @@ -363,11 +402,15 @@ public boolean accept(File dir, String name) { for (File fd : fds) { String path = null; try { - path = fd.getCanonicalPath(); + if (Build.VERSION.SDK_INT >= 21) { + path = Os.readlink(fd.getAbsolutePath()); + } else { + path = fd.getCanonicalPath(); + } } catch (Exception ignored) { } sb.append(" fd ").append(fd.getName()).append(": ") - .append(TextUtils.isEmpty(path) ? "???" : path).append('\n'); + .append(TextUtils.isEmpty(path) ? "???" : path.trim()).append('\n'); count++; if (count > 1024) { @@ -457,4 +500,171 @@ private static void getLogcatByBufferName(int pid, StringBuilder sb, String buff } } } + + + public static String getSystemProperty(String key, String defaultValue) { + try { + Class clz = Class.forName("android.os.SystemProperties"); + Method get = clz.getMethod("get", String.class, String.class); + return (String) get.invoke(clz, key, defaultValue); + } catch (NoSuchMethodException var4) { + var4.printStackTrace(); + } catch (IllegalAccessException var5) { + var5.printStackTrace(); + } catch (InvocationTargetException var6) { + var6.printStackTrace(); + } catch (ClassNotFoundException var7) { + var7.printStackTrace(); + } + + return defaultValue; + } + + public static String getMobileModel() { + String mobileModel = null; + if (Rom.isMiui()) { + String deviceName = ""; + + try { + Class systemProperties = Class.forName("android.os.SystemProperties"); + Method get = systemProperties.getDeclaredMethod("get", String.class, String.class); + deviceName = (String) get.invoke(systemProperties, "ro.product.marketname", ""); + if (TextUtils.isEmpty(deviceName)) { + deviceName = (String) get.invoke(systemProperties, "ro.product.model", ""); + } + } catch (InvocationTargetException var3) { + var3.printStackTrace(); + } catch (NoSuchMethodException var4) { + var4.printStackTrace(); + } catch (IllegalAccessException var5) { + var5.printStackTrace(); + } catch (ClassNotFoundException var6) { + var6.printStackTrace(); + } + + mobileModel = deviceName; + } else { + mobileModel = Build.MODEL; + } + + if (mobileModel == null) { + mobileModel = ""; + } + + return mobileModel; + } + + + public static class Rom { + private static final String TAG = "Rom"; + + public static final String ROM_MIUI = "MIUI"; + public static final String ROM_EMUI = "EMUI"; + public static final String ROM_FLYME = "FLYME"; + public static final String ROM_OPPO = "OPPO"; + public static final String ROM_SMARTISAN = "SMARTISAN"; + public static final String ROM_VIVO = "VIVO"; + public static final String ROM_QIKU = "QIKU"; + + private static final String KEY_VERSION_MIUI = "ro.miui.ui.version.name"; + private static final String KEY_VERSION_EMUI = "ro.build.version.emui"; + private static final String KEY_VERSION_OPPO = "ro.build.version.opporom"; + private static final String KEY_VERSION_SMARTISAN = "ro.smartisan.version"; + private static final String KEY_VERSION_VIVO = "ro.vivo.os.version"; + + private static String sName; + private static String sVersion; + + public static boolean isEmui() { + return check(ROM_EMUI); + } + + public static boolean isMiui() { + return check(ROM_MIUI); + } + + public static boolean isVivo() { + return check(ROM_VIVO); + } + + public static boolean isOppo() { + return check(ROM_OPPO); + } + + public static boolean isFlyme() { + return check(ROM_FLYME); + } + + public static boolean is360() { + return check(ROM_QIKU) || check("360"); + } + + public static boolean isSmartisan() { + return check(ROM_SMARTISAN); + } + + public static String getName() { + if (sName == null) { + check(""); + } + return sName; + } + + public static String getVersion() { + if (sVersion == null) { + check(""); + } + return sVersion; + } + + public static boolean check(String rom) { + if (sName != null) { + return sName.equals(rom); + } + + if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_MIUI))) { + sName = ROM_MIUI; + } else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_EMUI))) { + sName = ROM_EMUI; + } else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_OPPO))) { + sName = ROM_OPPO; + } else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_VIVO))) { + sName = ROM_VIVO; + } else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_SMARTISAN))) { + sName = ROM_SMARTISAN; + } else { + sVersion = Build.DISPLAY; + if (sVersion.toUpperCase().contains(ROM_FLYME)) { + sName = ROM_FLYME; + } else { + sVersion = Build.UNKNOWN; + sName = Build.MANUFACTURER.toUpperCase(); + } + } + return sName.equals(rom); + } + + public static String getProp(String name) { + String line = null; + BufferedReader input = null; + try { + Process p = Runtime.getRuntime().exec("getprop " + name); + input = new BufferedReader(new InputStreamReader(p.getInputStream()), 1024); + line = input.readLine(); + input.close(); + } catch (IOException ex) { + Log.e(TAG, "Unable to read prop " + name, ex); + return null; + } finally { + if (input != null) { + try { + input.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return line; + } + } } diff --git a/src/java/xcrash/xcrash_lib/src/main/java/xcrash/Version.java b/xcrash_lib/src/main/java/xcrash/Version.java similarity index 96% rename from src/java/xcrash/xcrash_lib/src/main/java/xcrash/Version.java rename to xcrash_lib/src/main/java/xcrash/Version.java index eecdb0e..afcb82e 100644 --- a/src/java/xcrash/xcrash_lib/src/main/java/xcrash/Version.java +++ b/xcrash_lib/src/main/java/xcrash/Version.java @@ -27,6 +27,6 @@ class Version { private Version() { } - static final String version = "2.4.8"; + static final String version = "3.1.0"; static final String fullVersion = "xCrash " + version; } diff --git a/src/java/xcrash/xcrash_lib/src/main/java/xcrash/XCrash.java b/xcrash_lib/src/main/java/xcrash/XCrash.java similarity index 96% rename from src/java/xcrash/xcrash_lib/src/main/java/xcrash/XCrash.java rename to xcrash_lib/src/main/java/xcrash/XCrash.java index b5943d1..73821b0 100644 --- a/src/java/xcrash/xcrash_lib/src/main/java/xcrash/XCrash.java +++ b/xcrash_lib/src/main/java/xcrash/XCrash.java @@ -38,6 +38,7 @@ public final class XCrash { private static String appVersion = null; private static String logDir = null; private static ILogger logger = new DefaultLogger(); + public static String nativeLibDir = null; private XCrash() { } @@ -69,6 +70,7 @@ public static synchronized int init(Context ctx, InitParameters params) { if (XCrash.initialized) { return Errno.OK; } + XCrash.initialized = true; if (ctx == null) { @@ -104,6 +106,8 @@ public static synchronized int init(Context ctx, InitParameters params) { } XCrash.appVersion = params.appVersion; + XCrash.nativeLibDir = ctx.getApplicationInfo().nativeLibraryDir; + //save log dir if (TextUtils.isEmpty(params.logDir)) { params.logDir = ctx.getFilesDir() + "/tombstones"; @@ -175,7 +179,8 @@ public static synchronized int init(Context ctx, InitParameters params) { params.anrLogcatMainLines, params.anrDumpFds, params.anrDumpNetworkInfo, - params.anrCallback); + params.anrCallback, + params.anrFastCallback); } //init native crash handler / ANR handler (API level >= 21) @@ -208,7 +213,8 @@ public static synchronized int init(Context ctx, InitParameters params) { params.anrLogcatMainLines, params.anrDumpFds, params.anrDumpNetworkInfo, - params.anrCallback); + params.anrCallback, + params.anrFastCallback); } //maintain tombstone and placeholder files in a background thread with some delay @@ -712,6 +718,7 @@ public InitParameters setNativeCallback(ICrashCallback callback) { boolean anrDumpFds = true; boolean anrDumpNetworkInfo = true; ICrashCallback anrCallback = null; + ICrashCallback anrFastCallback = null; /** * Enable the ANR capture feature. (Default: enable) @@ -755,7 +762,7 @@ public InitParameters setAnrRethrow(boolean rethrow) { /** * Set whether the process error state (from "ActivityManager#getProcessesInErrorState()") is a necessary condition for ANR. (Default: true) * - *

Note: On some Android TV box devices, the ANR is not reflected by process error state. In this case, set this option to false. + *

Note: On some Android TV box devices and on most Oppo phones, the ANR is not reflected by process error state. In this case, set this option to false. * * @param checkProcessState If true, process state error will be a necessary condition for ANR. * @return The InitParameters object. @@ -849,6 +856,20 @@ public InitParameters setAnrCallback(ICrashCallback callback) { this.anrCallback = callback; return this; } + + /** + * Set a fast callback to be executed when an ANR occurred. + * This callback is called before ANR trace dump + * (If not set, nothing will be happened.) + * + * @param fastCallback An instance of {@link xcrash.ICrashCallback}. + * @return The InitParameters object. + */ + @SuppressWarnings("unused") + public InitParameters setAnrFastCallback(ICrashCallback fastCallback) { + this.anrFastCallback = fastCallback; + return this; + } } static String getAppId() { @@ -859,7 +880,7 @@ static String getAppVersion() { return appVersion; } - static String getLogDir() { + public static String getLogDir() { return logDir; } diff --git a/src/java/xcrash/xcrash_sample/.gitignore b/xcrash_sample/.gitignore similarity index 100% rename from src/java/xcrash/xcrash_sample/.gitignore rename to xcrash_sample/.gitignore diff --git a/src/java/xcrash/xcrash_sample/build.gradle b/xcrash_sample/build.gradle similarity index 74% rename from src/java/xcrash/xcrash_sample/build.gradle rename to xcrash_sample/build.gradle index 35ba618..e578f86 100644 --- a/src/java/xcrash/xcrash_sample/build.gradle +++ b/xcrash_sample/build.gradle @@ -3,6 +3,7 @@ apply plugin: 'com.android.application' android { compileSdkVersion rootProject.ext.compileSdkVersion buildToolsVersion rootProject.ext.buildToolsVersion + ndkVersion rootProject.ext.ndkVersion defaultConfig { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion @@ -10,7 +11,7 @@ android { versionCode 1 versionName "1.0" ndk { - abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64' + abiFilters rootProject.ext.abiFilters.split(",") } } compileOptions { @@ -31,8 +32,10 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'androidx.appcompat:appcompat:1.1.0' - implementation 'androidx.constraintlayout:constraintlayout:1.1.3' - //implementation 'com.iqiyi.xcrash:xcrash-android-lib:2.4.8' + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'androidx.constraintlayout:constraintlayout:2.0.1' +// implementation 'com.iqiyi.xcrash:xcrash-android-lib:3.1.0' implementation project(':xcrash_lib') } + +apply from: rootProject.file('gradle/sanitizer.gradle') diff --git a/src/java/xcrash/xcrash_sample/proguard-rules.pro b/xcrash_sample/proguard-rules.pro similarity index 100% rename from src/java/xcrash/xcrash_sample/proguard-rules.pro rename to xcrash_sample/proguard-rules.pro diff --git a/src/java/xcrash/xcrash_sample/src/main/AndroidManifest.xml b/xcrash_sample/src/main/AndroidManifest.xml similarity index 85% rename from src/java/xcrash/xcrash_sample/src/main/AndroidManifest.xml rename to xcrash_sample/src/main/AndroidManifest.xml index e25f77e..7e70e04 100644 --- a/src/java/xcrash/xcrash_sample/src/main/AndroidManifest.xml +++ b/xcrash_sample/src/main/AndroidManifest.xml @@ -13,7 +13,8 @@ android:theme="@style/AppTheme" tools:ignore="AllowBackup,GoogleAppIndexingWarning"> - + @@ -21,7 +22,8 @@ - +